Skip to main content

Build Process Overview

Thalyson’s Portfolio uses Next.js with TypeScript and is optimized for production builds with advanced features like Turbopack in development and comprehensive bundle analysis.
The project uses Next.js 16+ which includes significant performance improvements and React 19 support.

Build Scripts

The following npm scripts are available in package.json:5-11:
npm run dev
# Starts development server with Turbopack

Next.js Build Configuration

The build configuration is defined in next.config.ts:1-20:
import type { NextConfig } from "next";

const withBundleAnalyzer = require("@next/bundle-analyzer")({
  enabled: process.env.ANALYZE === "true",
});

const nextConfig: NextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "res.cloudinary.com"
      }
    ]
  }
};

export default withBundleAnalyzer(nextConfig);

Key Configuration Features

The project configures remote image patterns for Cloudinary, enabling Next.js Image optimization for external images:
  • Protocol: HTTPS only for security
  • Hostname: res.cloudinary.com for CDN-hosted images
  • Automatic image optimization, resizing, and WebP/AVIF conversion
The @next/bundle-analyzer package is integrated to analyze bundle sizes:
ANALYZE=true npm run build
This generates an interactive visualization of your bundle composition, helping identify optimization opportunities.

Production Optimizations

Next.js automatically applies several production optimizations during the build process:
1

Code Minification

JavaScript and CSS are automatically minified using SWC, Next.js’s Rust-based compiler.
2

Tree Shaking

Unused code is eliminated from the final bundle, reducing bundle size.
3

Static Generation

Pages are pre-rendered at build time when possible for optimal performance.
4

Image Optimization

Images are optimized on-demand with automatic format selection (WebP/AVIF).

Turbopack: Development vs Production

Development Mode

The project uses Turbopack in development (package.json:6):
npm run dev
# Runs: next dev --turbopack
Turbopack provides significantly faster hot module replacement (HMR) and initial compilation compared to Webpack, making development more efficient.
Turbopack Benefits:
  • Up to 700x faster updates than Webpack
  • Incremental compilation
  • Built-in Rust-based bundler
  • Faster cold starts

Production Build

Production builds use Next.js’s optimized build system:
npm run build
This creates a .next directory with:
  • Optimized JavaScript bundles
  • Static HTML pages
  • Server-side rendering functions
  • Build manifest and metadata

Build Output Analysis

After running npm run build, you’ll see output like:
Route (app)                              Size     First Load JS
 /                                    5.2 kB         95.3 kB
 /_not-found                          871 B          85.1 kB
 /about                               3.1 kB         93.2 kB

  (Static)  prerendered as static content

Understanding the Output

  • ○ (Static): Page is pre-rendered at build time
  • λ (Server): Server-rendered on each request
  • ◐ (ISR): Incremental Static Regeneration
  • ◯ (SSG): Static Site Generation with dynamic paths
  • Size: Individual page JavaScript size
  • First Load JS: Total JavaScript loaded on initial page visit
Keep First Load JS under 200 kB for optimal performance. Pages over this threshold may experience slower initial loads.

Bundle Size Optimization

Analyze Your Bundle

1

Run Bundle Analyzer

ANALYZE=true npm run build
This opens an interactive treemap visualization in your browser.
2

Identify Large Dependencies

Look for unexpectedly large packages or duplicate dependencies.
3

Optimize Imports

Use tree-shakeable imports:
// Good: Tree-shakeable
import { Button } from 'lucide-react'

// Avoid: Imports entire library
import * as Icons from 'lucide-react'

Optimization Strategies

// Lazy load heavy components
import dynamic from 'next/dynamic'

const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
  loading: () => <p>Loading...</p>,
  ssr: false // Disable SSR if not needed
})

Image Optimization Best Practices

The project uses Next.js Image component with Cloudinary integration:
import Image from 'next/image'

export default function Hero() {
  return (
    <Image
      src="https://res.cloudinary.com/your-cloud/image.jpg"
      alt="Description"
      width={800}
      height={600}
      priority // For above-the-fold images
      placeholder="blur" // Optional blur placeholder
    />
  )
}
Image Optimization Tips:
  • Use priority for above-the-fold images
  • Specify exact width and height to prevent layout shift
  • Use loading="lazy" for below-the-fold images (default)
  • Next.js automatically serves WebP/AVIF when supported

Code Splitting and Lazy Loading

Automatic Code Splitting

Next.js automatically splits code at the route level. Each page only loads the JavaScript it needs.

Manual Code Splitting

import dynamic from 'next/dynamic'

// Lazy load a component
const ContactForm = dynamic(() => import('@/components/ContactForm'), {
  loading: () => <Skeleton />,
  ssr: true // Enable/disable server rendering
})

Build Troubleshooting

Common Build Errors

Problem: TypeScript compilation errors during build
npm run lint
# Check for type errors

npx tsc --noEmit
# Type check without emitting files
Solution: Fix type errors in your code or update tsconfig.json:7 to be less strict temporarily.
Problem: Cannot find module or dependency
rm -rf node_modules package-lock.json
npm install
npm run build
Solution: Clear node_modules and reinstall dependencies.
Problem: JavaScript heap out of memory
# Increase Node.js memory limit
NODE_OPTIONS="--max-old-space-size=4096" npm run build
Solution: Increase memory allocation or optimize your code to reduce memory usage.
Problem: Failed to optimize imagesSolution: Ensure image URLs in next.config.ts:9-16 match your actual image sources. Verify remote patterns are correctly configured.
Problem: Environment variables undefined in production
// Only variables prefixed with NEXT_PUBLIC_ are available in browser
const apiKey = process.env.NEXT_PUBLIC_API_KEY
Server-side environment variables (without NEXT_PUBLIC_ prefix) are only available in server components and API routes.

Build Performance Tips

1

Use SWC Compiler

Next.js uses SWC by default (faster than Babel). Avoid custom Babel configuration unless necessary.
2

Enable Incremental Builds

TypeScript incremental compilation is enabled in tsconfig.json:15. This speeds up subsequent builds.
3

Optimize Dependencies

Review and remove unused dependencies:
npm uninstall unused-package
4

Cache Build Output

CI/CD systems should cache .next/cache directory between builds.

Pre-Build Checklist

Before building for production, ensure:
  • All TypeScript errors are resolved (npm run lint)
  • Code is formatted (npm run format)
  • Environment variables are configured
  • Image sources are properly configured in next.config.ts
  • Dependencies are up to date and secure
  • Build completes without errors (npm run build)
  • Production build runs locally (npm run build && npm start)
  • Bundle sizes are acceptable (ANALYZE=true npm run build)
After a successful build, test the production build locally with npm start before deploying to catch any issues early.

Build docs developers (and LLMs) love