DEV Community

丁久
丁久

Posted on • Originally published at dingjiu1989-hue.github.io

Build Tools: esbuild, swc, turbopack, vite — Speed Comparison

This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.

Build Tools: esbuild, swc, turbopack, vite — Speed Comparison

Introduction

JavaScript build tooling has undergone a revolution. Webpack-era builds that took minutes are now replaced by tools that bundle in milliseconds. The new generation — esbuild, swc, turbopack, and vite — leverage native code (Go, Rust) and modern architectures to deliver dramatically faster builds.

esbuild

esbuild is an extremely fast bundler written in Go:

// build.js

const esbuild = require("esbuild");

esbuild.build({

  entryPoints: ["src/index.tsx"],

  bundle: true,

  outfile: "dist/bundle.js",

  minify: true,

  sourcemap: true,

  target: ["es2020"],

  loader: {

    ".tsx": "tsx",

    ".png": "dataurl",

    ".svg": "text",

  },

  define: {

    "process.env.NODE_ENV": '"production"',

  },

  plugins: [],

}).catch(() => process.exit(1));

// Watch mode

esbuild.context({

  entryPoints: ["src/index.tsx"],

  bundle: true,

  outfile: "dist/bundle.js",

}).then(ctx => ctx.watch());

// v0.24+ supports CSS bundling and bundling

# Command line

esbuild src/index.tsx --bundle --outfile=dist/bundle.js --minify
Enter fullscreen mode Exit fullscreen mode

Speed: 10-100x faster than Webpack on equivalent bundles. A 1000-module TypeScript project bundles in ~100ms. Builds are CPU-bound on Go's efficient parallelism.

Limitations: No native TypeScript type checking (delegates to tsc separately). Plugin ecosystem is smaller. Code splitting is less sophisticated than Webpack's.

swc

swc is a Rust-based compiler and bundler:

// .swcrc

{

  "jsc": {

    "parser": {

      "syntax": "typescript",

      "tsx": true,

      "decorators": true

    },

    "target": "es2020",

    "transform": {

      "react": {

        "runtime": "automatic"

      }

    },

    "minify": {

      "compress": true,

      "mangle": true

    }

  },

  "module": {

    "type": "es6"

  },

  "minify": true

}

# Transpile a file

swc src/index.ts -o dist/index.js

# Bundle entry points

swc src/index.ts --out-dir dist --config-file .swcrc
Enter fullscreen mode Exit fullscreen mode

swc is commonly used as a compiler replacement within Webpack (via swc-loader) or as a standalone for TypeScript transpilation. Its bundler is newer than esbuild's but benefits from Rust's memory safety and parallelism.

Speed: Comparable to esbuild for transpilation. Slightly slower for bundling due to more conservative AST handling. The minify pass is very fast.

Turbopack

Vercel's Rust-based incremental bundler, designed as a Webpack successor:

// next.config.js — Turbopack in Next.js

const nextConfig = {

  experimental: {

    turbo: {

      rules: {

        "*.svg": ["@svgr/webpack"],

      },

      resolveAlias: {

        underscore: "lodash",

      },

      treeShaking: true,

      minify: "esbuild", // Use esbuild for minification

    },

  },

};

module.exports = nextConfig;

# Start Next.js with Turbopack

next dev --turbo

# Build with Turbopack (Next.js 15+)

next build --turbo
Enter fullscreen mode Exit fullscreen mode

Turbopack is deeply integrated with Next.js. As a standalone bundler, it is less mature. Its key innovation is function-level caching: it tracks changes at the function granularity and only rebuilds affected functions.

Speed: Up to 10x faster than Webpack in development. Cold builds are comparable to esbuild. Hot module replacement is near-instant with function-level granularity.

Vite

Vite uses esbuild for dependencies and Rollup for production builds:

// vite.config.ts

import { defineConfig } from "vite";

import react from "@vitejs/plugin-react";

import path from "path";

export default defineConfig({

  plugins: [react()],

  resolve: {

    alias: {

      "@": path.resolve(__dirname, "./src"),

    },

  },

  build: {

    rollupOptions: {

      output: {

        manualChunks: {

          vendor: ["react", "react-dom"],

          utils: ["lodash", "date-fns"],

        },

      },

    },

    target: "es2020",

    minify: "esbuild",

    cssCodeSplit: true,

  },

  server: {

    hmr: true,

    watch: {

      usePolling: false,

    },

  },

});

# Development

vite dev    # Near-instant start, uses esbuild for pre-bundling

# Production build

vite build  # Uses Rollup for optimal production output
Enter fullscreen mode Exit fullscreen mode

Speed: Development server starts in <50ms regardless of project size. Native ESM in dev means no bundling needed. Pre-bundling dependencies with esbuild only happens once. Production builds are slower (Rollup) but produce optimized output.

Benchmarks

| Task | esbuild | swc | Turbopack | Vite |

|------|---------|-----|-----------|------|


Read the full article on AI Study Room for complete code examples, comparison tables, and related resources.

Found this useful? Check out more developer guides and tool comparisons on AI Study Room.

Top comments (0)