All Docs
FeaturesSaaS FactoryUpdated February 19, 2026

Next.js Performance Configuration

Next.js Performance Configuration

This page documents the recommended next.config.ts configuration for SaaS Factory projects. A bare empty export — export default {} — leaves significant performance on the table. The sections below cover each optimization area, why it matters, and how to apply it.


1. Package Import Optimization (experimental.optimizePackageImports)

Why It Matters

Some npm packages export a large number of named exports from a single entry point. Without hints to the compiler, the entire package can end up in the client bundle even if only a fraction of its exports are used.

lucide-react is the most impactful offender in the current stack: it ships 563 icons (~600 KB raw). Using even one icon without optimizePackageImports can cause the full icon set to be included.

Configuration

// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  experimental: {
    optimizePackageImports: [
      'lucide-react',
      'date-fns',
      '@dnd-kit/core',
      '@dnd-kit/sortable',
      '@dnd-kit/utilities',
    ],
  },
};

export default config;

Estimated Impact

  • lucide-react alone: −100–200 KB from the client bundle after tree-shaking.
  • date-fns: moderate savings depending on how many locale/format helpers are imported.
  • @dnd-kit/*: minor savings; included for consistency.

2. Bundle Analyzer (@next/bundle-analyzer)

Why It Matters

Without a bundle analyzer wired into CI, bundle size regressions go undetected until they affect real users. The analyzer generates a visual treemap of every module in the bundle, making it easy to spot unexpected large dependencies.

Installation

npm install --save-dev @next/bundle-analyzer

Configuration

// next.config.ts
import type { NextConfig } from 'next';
import withBundleAnalyzer from '@next/bundle-analyzer';

const config: NextConfig = {
  // ...other options
};

export default withBundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
})(config);

Running the Analyzer

ANALYZE=true npm run build

This opens an interactive treemap in your browser. Add a CI step that runs the build with ANALYZE=true and archives the output for size comparison across releases.


3. Image Format Configuration

Why It Matters

Next.js's built-in Image Optimization API can serve modern image formats to browsers that support them. avif offers the best compression ratios; webp is the widely-supported fallback. Without explicit configuration, Next.js does not serve these formats.

Configuration

const config: NextConfig = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};

Notes

  • avif encoding is more CPU-intensive at build time. For image-heavy pages, consider caching strategies or on-demand ISR.
  • The formats array is ordered by preference; browsers that support avif will receive it first.

4. Production Console Removal (compiler.removeConsole)

Why It Matters

console.log, console.debug, and console.warn calls left in production builds contribute to bundle size and can inadvertently leak internal state in browser devtools. Removing them at compile time keeps production bundles clean without requiring manual audit of every log statement.

Configuration

const config: NextConfig = {
  compiler: {
    removeConsole: {
      exclude: ['error'],
    },
  },
};

This removes all console.* calls except console.error, which is retained for runtime error visibility.


Complete Reference Configuration

The following combines all recommended options into a single next.config.ts:

import type { NextConfig } from 'next';
import withBundleAnalyzer from '@next/bundle-analyzer';

const config: NextConfig = {
  experimental: {
    optimizePackageImports: [
      'lucide-react',
      'date-fns',
      '@dnd-kit/core',
      '@dnd-kit/sortable',
      '@dnd-kit/utilities',
    ],
  },

  images: {
    formats: ['image/avif', 'image/webp'],
  },

  compiler: {
    removeConsole: {
      exclude: ['error'],
    },
  },
};

export default withBundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
})(config);

Summary of Improvements

AreaOptionBenefit
Tree-shakingexperimental.optimizePackageImports−100–200 KB (lucide-react alone)
Observability@next/bundle-analyzerCatch size regressions in CI
Imagesimages.formatsSmaller payloads for modern browsers
Production hygienecompiler.removeConsoleCleaner builds, no log leakage

Introduced in v1.0.24. No breaking changes — all options are additive.