⚡ TECH BLOG
Home
Blog
Tags
About
⚡

Powered by Next.js 15 & Modern Web Tech ⚡

Back to Home

Next.js 12: New Features and Improvements

January 15, 2022
nextjsreactweb-developmentjavascript
Next.js 12: New Features and Improvements

Next.js 12: New Features and Improvements

Next.js 12 brings a host of exciting features that significantly improve developer experience and application performance. Let's dive into the most important additions.

Rust Compiler: 5x Faster Builds

One of the biggest changes in Next.js 12 is the introduction of a new Rust-based compiler, replacing Babel for transformations.

// next.config.js
module.exports = {
  // This is now enabled by default
  swcMinify: true,
}

Benefits

  • 5x faster fresh builds - Large codebases compile much faster
  • 17x faster fast refresh - Hot module replacement is nearly instant
  • Better error messages - Clearer, more actionable errors

Middleware: Edge Computing Made Easy

Middleware allows you to run code before a request completes, enabling powerful features at the edge.

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Check for authentication
  const isAuthenticated = request.cookies.get('auth-token')
  
  if (!isAuthenticated && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  
  // Add custom headers
  const response = NextResponse.next()
  response.headers.set('x-custom-header', 'custom-value')
  
  return response
}

export const config = {
  matcher: '/dashboard/:path*',
}

Use Cases for Middleware

  • Authentication - Protect routes without hitting the server
  • A/B Testing - Serve different content to different users
  • Geo-location - Redirect based on user location
  • Logging - Track requests at the edge

React 18 Support

Next.js 12 adds support for React 18 and its concurrent features.

// Enable React 18 in next.config.js
module.exports = {
  experimental: {
    reactRoot: true,
  },
}

Automatic Batching

React 18 automatically batches state updates, even in promises and timeouts:

function handleClick() {
  // These will be batched automatically
  setCount(c => c + 1)
  setFlag(f => !f)
  // Only one re-render!
}

async function handleSubmit() {
  const data = await fetchData()
  // React 18 batches these too!
  setData(data)
  setLoading(false)
  setError(null)
}

AVIF Image Support

Next.js 12 adds support for AVIF images, which are 20% smaller than WebP.

import Image from 'next/image'

export default function Gallery() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero image"
      width={1200}
      height={600}
      format="avif"
      priority
    />
  )
}

Image Configuration

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

URL Imports

Import packages directly from URLs without npm install:

// Import directly from a URL
import confetti from 'https://cdn.skypack.dev/canvas-confetti'

function Celebrate() {
  const handleParty = () => {
    confetti()
  }
  return <button onClick={handleParty}>Celebrate!</button>
}
// next.config.js
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev'],
  },
}

Jest Configuration

Next.js 12 includes zero-configuration Jest support.

// jest.config.js
const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './',
})

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testEnvironment: 'jest-environment-jsdom',
}

module.exports = createJestConfig(customJestConfig)

Writing Tests

// __tests__/components/Button.test.jsx
import { render, screen } from '@testing-library/react'
import Button from '@/components/Button'

describe('Button', () => {
  it('renders with correct text', () => {
    render(<Button>Click me</Button>)
    expect(screen.getByRole('button')).toHaveTextContent('Click me')
  })
})

Standalone Output for Docker

Simplified Docker deployments with standalone output mode.

// next.config.js
module.exports = {
  output: 'standalone',
}
# Dockerfile
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:16-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

EXPOSE 3000
CMD ["node", "server.js"]

Performance Improvements

Faster HMR

Hot Module Replacement is now significantly faster, especially in large projects:

  • CSS updates - No more full page refresh for CSS changes
  • Fast refresh - Preserves component state during edits
  • Error recovery - Automatically recovers from syntax errors

Tree Shaking

Better dead code elimination:

// Only import what you need
import { debounce } from 'lodash-es'
// Instead of the entire library

Migration Guide

Upgrading from Next.js 11:

npm install next@12 react@latest react-dom@latest

Breaking Changes

  1. Minimum Node.js version is now 12.22.0
  2. Webpack 5 is the default (webpack 4 removed)
  3. Image optimization requires newer Sharp version
# Update Sharp for image optimization
npm install sharp@latest

Conclusion

Next.js 12 represents a significant leap forward for the framework. The Rust compiler alone makes the upgrade worthwhile, but middleware and React 18 support make this a must-have update for any serious Next.js project.

Next Steps

  • Upgrade your existing projects to Next.js 12
  • Experiment with middleware for edge computing
  • Consider enabling React 18 concurrent features

Happy coding!

Share:

💬 Comments