← Back to DevBytes

Building Modern Web Apps with Turbopack: Complete Guide

Introduction to Turbopack

Turbopack is an incremental bundler optimized for JavaScript and TypeScript, built by the Vercel team. It is written in Rust and designed to replace Webpack and Vite in modern development workflows. Unlike traditional bundlers that process your entire application from scratch on every change, Turbopack uses fine-grained caching and incremental computation to rebuild only the parts that changed. This results in near-instantaneous updates during development and significantly faster production builds.

Why Turbopack Matters

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Modern web applications are growing in complexity, often involving hundreds or thousands of modules. Traditional bundlers struggle to keep up, leading to slow startup times and sluggish hot module replacement (HMR). Turbopack addresses these pain points:

Adopting Turbopack means faster feedback loops for developers and shorter CI/CD pipelines for teams.

Getting Started with Turbopack

Prerequisites

Ensure you have Node.js 18 or later installed. Basic familiarity with npm/yarn and command-line tools is assumed.

Installation and Setup

You can add Turbopack to an existing project or start fresh. The easiest way is to create a new project using a framework that supports Turbopack natively, like Next.js 14+.

npx create-next-app@latest my-app --turbo

This scaffolds a Next.js application with Turbopack enabled. Alternatively, for a plain JavaScript or React setup without a framework, you can install Turbopack directly:

mkdir my-turbopack-app
cd my-turbopack-app
npm init -y
npm install turbopack @turbopack/core @turbopack/cli --save-dev

Then create an entry file and a basic configuration.

Project Structure

A minimal Turbopack project might look like this:

my-turbopack-app/
├── src/
│   ├── index.html
│   └── index.js
├── package.json
└── turbo.json

The src/index.html is the HTML template, and src/index.js is the JavaScript entry point.

Configuration

Turbopack configuration is stored in a turbo.json file at the project root. Here is a basic example:

{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

For bundler-specific options, you can use a turbo.config.js or pass arguments via CLI. Here is an example turbo.config.js for a standalone React app:

export default {
  entry: './src/index.js',
  output: './dist',
  html: {
    template: './src/index.html',
    title: 'My Turbopack App'
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx']
  }
};

Running the Development Server

If you used the Next.js scaffolding, simply run:

cd my-app
npm run dev

For a standalone project, use the Turbopack CLI:

npx turbo dev

This starts a development server (default port 3000) with hot module replacement. Open http://localhost:3000 to see your app.

Building for Production

To create an optimized production build, run:

npm run build

In a Next.js project, this automatically uses Turbopack for building. For standalone setups, execute:

npx turbo build

The output will be placed in the directory specified in your configuration (e.g., dist/).

Core Features in Depth

Incremental Computation

Turbopack tracks dependencies at a granular level using a content-addressable cache. When you edit a file, it only recomputes the modules affected by that change. This is possible because Turbopack’s build graph is composed of tiny, cacheable nodes. For example, if you update a utility function used in ten components, only those ten components and their direct dependents are rebuilt—not the entire application.

Hot Module Replacement

Turbopack’s HMR is designed to preserve application state across updates. When you modify a React component, Turbopack sends only the updated module over a WebSocket connection. The browser applies the patch without reloading the page. This works seamlessly with frameworks like React, Svelte, and Vue. To see it in action, run the dev server and edit any file – the change appears in milliseconds.

Code Splitting

Turbopack automatically splits your code into smaller chunks based on dynamic imports and route boundaries. It supports both eager and lazy loading. For example, in a Next.js app, every page becomes a separate chunk. You can also manually create dynamic imports:

// Lazy load a heavy component
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

function MyPage() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </React.Suspense>
  );
}

Turbopack will split HeavyComponent into its own chunk, loaded only when needed.

CSS and Asset Handling

Turbopack supports CSS modules, PostCSS, Sass, Less, and Stylus. It also handles images, fonts, and other assets with built-in loaders. For example, to use CSS modules:

/* styles.module.css */
.button {
  background-color: blue;
  color: white;
}
// component.js
import styles from './styles.module.css';

function MyButton() {
  return <button className={styles.button}>Click me</button>;
}

Turbopack will automatically scope the class names and optimize CSS output during production builds.

Integrating with Frameworks

Next.js with Turbopack

Next.js 14+ has first-class support for Turbopack. To enable it, simply add the --turbo flag to the dev command or set it in your next.config.js:

// next.config.js
module.exports = {
  experimental: {
    turbo: true
  }
};

Once enabled, all Next.js features (file‑based routing, API routes, middleware, etc.) work with Turbopack’s incremental engine. You can use the same next dev and next build commands.

Using Turbopack with React (Without Next.js)

For a custom React setup, you can configure Turbopack as the bundler. Here is a minimal example:

// turbo.config.js
export default {
  entry: './src/index.jsx',
  output: './dist',
  html: {
    template: './src/index.html',
    title: 'React + Turbopack'
  },
  jsx: 'react-jsx',
  resolve: {
    extensions: ['.js', '.jsx']
  }
};

Then in your src/index.jsx:

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const root = createRoot(document.getElementById('root'));
root.render(<React.StrictMode><App /></React.StrictMode>);

Run npx turbo dev to start development.

Best Practices

Conclusion

Turbopack represents a paradigm shift in web application bundling, offering unprecedented speed through incremental computation and a Rust‑based core. Whether you are building a simple React prototype or a large‑scale Next.js application, Turbopack’s fast HMR and production optimizations will accelerate your development workflow. By following the setup steps, leveraging its core features, and adhering to best practices, you can deliver modern web apps that are both performant and maintainable. As the ecosystem continues to evolve, adopting Turbopack today positions your projects for a future where build times are no longer a bottleneck.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles