Once upon a time in web development, building web pages required just HTML, CSS, and some JavaScript for interactivity. This was the typical code structure of most websites:
Most often, developers would introduce third-party JavaScript libraries for extra interactivity:
JavaScript was perceived as a client-side scripting language during this period — and nothing more. That would soon change, especially with the introduction of Node.js.
Node.js proved that JavaScript had more than just client-side capabilities, and could handle network requests, routing, complex animations, and storage, too.
Then we started building large-scale products like ecommerce sites, social media apps, learning platforms, etc., with JavaScript. This introduced more third-party libraries, but since content delivery networks (CDNs) weren’t popular then, so you had to download the library’s JS files. This made code messy and difficult to maintain, and the developer experience was horrible.
During this period, the ever-progressive JS community started focusing on improving developer experience with developer tools. This led to the birth of bundlers.
Jump ahead:
A bundler is simply a development tool aggregating all JS files as input, and outputs a single JS file that is loadable on a web browser. A bundler ensures that all source code and third-party dependencies are up-to-date and error-free.
Before the era of bundling code, optimization and logging were major issues. Bundlers solve that with features such as:
Bundlers like Browserify have existed since 2010, using require
to load npm packages in the browser. However, JavaScript didn’t have an inbuilt module system until the introduction of ES2015. A subsequent new wave of modular programming led to the birth of module bundlers like webpack, Rollup, Parcel, and esbuild.
Of all the bundlers, webpack got everyone’s attention first, and is currently the most used bundler with ~28 million weekly downloads.
webpack is a static module bundler. When introduced to a project, it generates a dependency graph from one or more entry points (more like index.js
), and combines all the modules (JS and non-JS) into one bundle — or more, depending on your configuration.
These bundles become static files (HTML, CSS, JS, assets) that the browser can process. It requires no configuration to bundle your project, but is very configurable.
Let’s briefly take a look at how webpack approaches dependency resolution.
index.js
file, but you can choose a different entry point or more than one pointwebpack.config.js: module.exports = { entry: ['../../index.js', '../../server.js'], };
dist
folderconst path = require('path');module.exports = { output: { path: path.resolve(__dirname, 'dist'), }, };
module.exports = { module: { rules: [ { test: /.(js|jsx)$/, exclude: "/node-modules/", use: "babel-loader" }, { test: /\.html$/, use: "html-loader" }, { test: /\.(scss|sass)$/, use: ["style-loader", "css-loader", "sass-loader"] }, { test: /\.(png|jpe?g|gif)$/i, use: [ { loader: 'file-loader', }, ], }, ]
}
}
const BrotliPlugin = require('brotli-webpack-plugin'); module.exports = { plugins: [ new BrotliPlugin({ asset: '[path].br[query]', test: /.(js|css|html|svg)$/, }) ] }
module.exports = { mode: 'development', };
These are the core concepts of webpack. If you’ve worked with JavaScript frameworks such as Vue, React, Angular, and so on, you’ll notice these core webpack concepts are implemented. This is because these frameworks use webpack for bundling.
The impact of webpack in frontend tooling and architecture is vast. It’s widely used in single-page applications (SPAs), applications that use server-side rendering (SSR), and static site generators (SSGs). In short, other language frameworks, such as PHP (Laravel) and Ruby (Rails), use webpack to manage JavaScript, CSS, and static assets, like images or fonts.
Moreover, with the availability of native ES modules in the browser and the rise of JavaScript tools written in compile-to-native languages, the choice of bundler requires more attention.
These issues led the ever-progressive JS community to develop better alternatives to webpack. One of the most successful alternatives so far is Vite. Let’s briefly explore Vite.
Vite is a build tool that provides a faster development experience in web projects. Unlike a bundler, Vite consists of two parts:
The HMR API in Vite is considerably faster than webpack. Vite solves the slow development server problem we have with webpack, even as the project expands. It also ushers in a new era of ESM-based development tools and bundleless architecture. We won’t go deep into Vite, cause it’s past the scope of this article, but the goal of introducing it is so you’ll note these points:
These points raise the question, “If Vite isn’t the successor to Webpack, what is?” A few weeks ago, Vercel answered that question with the release of Turbopack. In the next section, we’ll learn about what Turbopack is, its pros and cons, how to use it in a Next.js project, and what makes it better than webpack. We’ll briefly discuss the future of webpack-based projects as well.
Turbopack is an incremental bundler optimized for your JavaScript and TypeScript projects. Unlike other bundlers written in JS/TS, Turbopack is Rust-based. It’s the official successor to webpack, and is being built by the creators of webpack and Next.js.
Turbopack claims to be 700x faster than webpack and 10x faster than Vite in large project (though Vite’s creator disagrees with this). So what makes Turbopack so fast?
We’ve discussed the importance of startup time in developer experience and how the webpack dev server is slow to start as the project gets bigger because it rebuilds the entire application every time a file is changed. Turbopack, on the other hand, compiles only the code needed to start the project.
Turbo Engine is a powerful Rust library that enables incremental computation. In computer science, incremental computation refers to using the previously computed output when computing a new output when a sequence of inputs is slightly different from each other, rather than computing the new output from scratch. This computation is applied when optimizing compilers. One way to achieve incremental computation is through caching. Turbo Engine implements incremental computation using function-level caching. Let’s explore the features and drawbacks of Turbopack.
Let’s highlight some of the features of Turbopack:
Let’s highlight some of Turbopack early drawbacks. It’s important to note that Turbopack is still very new and experimental, so these issues might be fixed as it matures.
tsc --watch
or depend on your code IDE for type checking.Turbopack is still in its alpha version and has only been deployed as a Next.js 13 dev server. To run a Next.js 13 project powered by Turbopack, run this command on your terminal:
<
pre class=”language-bash hljs>npx create-next-app –example with-turbopack
This command will bootstrap a Next.js 13 sample with React Server Components. Run yarn install
to install dependencies.
Now for the moment of truth. Let’s run the project with yarn dev
:
A compilation time of 6.264ms with 20+ components!
For context, let’s compare this startup time with a non-Turbopack Next.js 13 project, with fewer components and dependencies.
We compiled client and server in 11s, almost twice the Turbopack compile time!
The difference is clear. We can only look forward to when Turbopack will be a low-level engine for other frameworks.
As we’ve discussed, Turbopack is still in experiment mode and is not yet ready for production environments. So at the time of writing this article, you can’t port your project to Turbopack.
Firstly, for webpack aficionados, Turbopack is a preview of the future. webpack has roughly 26 million weekly downloads, which will continue for as long as possible until the project maintainers pull the plug.
If you visit Snowpack, which is not maintained anymore, you will be advised to use Vite. I imagine the same thing will happen with webpack and Turbopack in the future.
However, Turbopack is managed by Vercel, and we don’t know when the bundler will be ready for wide, production-grade adoption. I recommend using Vite in the interim if you’re looking for an alternative to webpack.
Turbopack is a promising project that will certainly redefine bundling tools architecture in an era where build tools such as Vite and esbuild are replacing bundlers. In this article, we learned what bundlers are and how they work. Then we introduced webpack as the bundler par excellence tool; we went on to learn its core concepts and briefly explored Vite as an alternative to webpack.
We also covered Vite as a build tool, and not a successor to webpack. This introduced us to Turbopack. We learned what Turbopack was, how it worked, its top features and issues, how to use it in a project, and how it affects existing webpack users.
There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
One Reply to "Introducing Turbopack: A Rust-based successor to webpack"
is Turbopack production ready? Is NextJS 13.1 production ready?