esbuild VS webpack

Compare esbuild vs webpack and see what are their differences.


An extremely fast JavaScript and CSS bundler and minifier (by evanw)


A bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through "loaders", modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff. (by webpack)
Our great sponsors
  • SonarLint - Deliver Cleaner and Safer Code - Right in Your IDE of Choice!
  • Scout APM - Less time debugging, more time building
  • SaaSHub - Software Alternatives and Reviews
esbuild webpack
202 185
31,790 61,088
- 0.6%
9.8 9.8
11 days ago 4 days ago
Go JavaScript
MIT License MIT License
The number of mentions indicates the total number of mentions that we've tracked plus the number of user suggested alternatives.
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.


Posts with mentions or reviews of esbuild. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2022-05-20.
  • Using the ESBuild plug-in mechanism to achieve the desired functionality
    2 projects | | 20 May 2022
    esbuild is a general purpose code compiler and build tool that uses golang builds, it is very fast and 1~2 orders of magnitude higher in performance than the existing js toolchain. It's not an out-of-the-box build tool yet, but with its plugin system we can already do a lot of things.
    2 projects | | 20 May 2022
    import { Plugin } from 'esbuild' /** * Automatically exclude all dependencies * Some regular expression syntax of js is not supported by golang, see */ export function autoExternal(): Plugin { return { name: 'autoExternal', setup(build) { build.onResolve({ filter: /. */ }, (args) => { if (/^\. {1,2}\//.test(args.path)) { return } return { path: args.path, external: true, } }) }, } }
  • Go: The language of cloud-native development - SD Times
    3 projects | | 10 May 2022
    But then you see stuff like ESBuild, where the Evan Wallace (the author) tried to write in both Rust and Go, and his Go version was faster. According to him, this was probably because Go runs destructors in a parallel thread, whereas Rust runs them in the same thread (source), among other factors. The same performance could theoretically be achieved in Rust, but it would demand a lot more effort.
  • Better Backend DX: Fastify + ESBuild = ⚡️
    8 projects | | 9 May 2022
    Use esbuild as a compiler and backend bundler
    8 projects | | 9 May 2022
    Will provide an alternative solution for Windows later. (ref:
  • Unix command line conventions over time
    9 projects | | 7 May 2022
  • Why You Should Ditch Create-React-App for Vite
    1 project | | 5 May 2022
    Esbuild is a Javascript build tool written in Go, which pre-bundles dependencies 10-100 times faster than Javascript-based bundlers.
  • Make your end to end tests fast
    3 projects | | 4 May 2022
    We did this via the npm threads wrapper and esbuild. We first moved all of our compute code into a new file with minimal imports, called imageCompare.worker.js. We then added a pre-compilation step with esbuild to compile this file into a bundle. We then spawn the worker using this generated file as a blob, and interact with it via the threads promise interface.
  • Is typescript better than JS?
    1 project | | 2 May 2022
    Though, if you want to use one, do yourself a favor and give esbuild a try. It is orders of magnitude faster, at the cost of less flexibility.
  • How I Build and Deliver B2B SaaS Software as a 1.5* Person Indie Developer
    12 projects | | 19 Apr 2022
    Make my builds faster by forcing myself onto esbuild from the beginning, even if that makes delivering some capabilities harder (like web workers and service workers, Hot Module Replacement, and so on).


Posts with mentions or reviews of webpack. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2022-05-19.
  • How we used JSDoc & Webpack to write some custom JavaScript decorators & annotations
    2 projects | | 19 May 2022
    You could write a pre-build script to write the docs into a file and then read that in at compile time, but where's the fun in that? We use Webpack for our bundling needs, which means we can write a custom loader. This will run JSDoc over the file for us, play around with the data a little bit and give us a nice output. We can use this output to configure which data comes out the model.
  • Use Vite for React Apps instead of CRA
    6 projects | | 16 May 2022
    CRA uses Webpack to bundle the code. Webpack bundles the entire code, so if your codebase is very large more than 10k lines you might see a slower start in the development server and a long waiting time to see the changes made.
  • Setup jest from scratch in a vanilla js project.
    3 projects | | 13 May 2022
    A co-worker was setting up webpack and asked me to enable jest.
  • By Crayons and For Crayons
    12 projects | | 13 May 2022
    It is using Webpack for bundling, Redux and Immer for application state management.
  • webpack-bundle-analyzer shows webpack -p does not remove development dependency react-dom.development.js
    2 projects | | 9 May 2022
    const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;const SOURCE_DIR = './src';const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({ template: SOURCE_DIR + '/index.html', filename: 'index.html', inject: 'body'});module.exports = env => { console.log(`Environment Configs: ${JSON.stringify(env) || 'Default'}`); console.log(` Available Configs: = true / false //for allow webpack to watch build `) let environment = env || {}; const { watch, analyze, } = environment; const configedAnalyzer = new BundleAnalyzerPlugin({ // Can be `server`, `static` or `disabled`. // In `server` mode analyzer will start HTTP server to show bundle report. // In `static` mode single HTML file with bundle report will be generated. // In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`. analyzerMode: 'static',//was server // Host that will be used in `server` mode to start HTTP server. analyzerHost: '', // Port that will be used in `server` mode to start HTTP server. analyzerPort: 9124, // Path to bundle report file that will be generated in `static` mode. // Relative to bundles output directory. reportFilename: './../report/bundle_anlaysis.html', // Module sizes to show in report by default. // Should be one of `stat`, `parsed` or `gzip`. // See "Definitions" section for more information. defaultSizes: 'stat', // Automatically open report in default browser openAnalyzer: Boolean(analyze), // If `true`, Webpack Stats JSON file will be generated in bundles output directory generateStatsFile: Boolean(analyze), // Name of Webpack Stats JSON file that will be generated if `generateStatsFile` is `true`. // Relative to bundles output directory. statsFilename: 'stats.json', // Options for `stats.toJson()` method. // For example you can exclude sources of your modules from stats file with `source: false` option. // See more options here: statsOptions: null, // Log level. Can be 'info', 'warn', 'error' or 'silent'. logLevel: 'info' }); return { entry: SOURCE_DIR + '/index.js', output: { path: path.resolve(__dirname, "dist"), filename: 'bundle.js', }, module: { rules: [ { test: /\.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: ['env', 'react'] } } } ] }, watchOptions: { aggregateTimeout: 300, poll: 1000 }, watch: Boolean(watch), plugins: [HtmlWebpackPluginConfig, configedAnalyzer], // devServer: { contentBase: path.join(__dirname, "dist"), compress: false, port: 9123, } };} When I do webpack -p file size is a lot smaller but this react-dom.development.js take over almost 50% of the size, in my case 500ish KB out of 1.1ish MB.
  • ZKu Week 1: Introduction to ZKP
    5 projects | | 9 May 2022
    It's an ES module, so it can be directly imported into bigger projects using Rollup or Webpack.
  • What Does Webpack 4 Expect From A Package With sideEffects: false
    1 project | | 5 May 2022
    From Webpack docs
  • How to config webpack to transpile files from other lerna packages (ejected from create-react-app)
    3 projects | | 4 May 2022
    ... resolve: { // This allows you to set a fallback for where Webpack should look for modules. // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // modules: ['node_modules', paths.appNodeModules].concat( modules.additionalModulePaths || [] ), // These are the reasonable defaults supported by the Node ecosystem. // We also include JSX as a common component filename extension to support // some tools, although we do not recommend using it, see: // // `web` extension prefixes have been added for better support // for React Native Web. extensions: paths.moduleFileExtensions .map(ext => `.${ext}`) .filter(ext => useTypeScript || !ext.includes('ts')), alias: { // Support React Native Web // 'react-native': 'react-native-web', // Allows for better profiling with ReactDevTools ...(isEnvProductionProfile && { 'react-dom$': 'react-dom/profiling', 'scheduler/tracing': 'scheduler/tracing-profiling', }), ...(modules.webpackAliases || {}), }, plugins: [ // Adds support for installing with Plug'n'Play, leading to faster installs and adding // guards against forgotten dependencies and such. PnpWebpackPlugin, // Prevents users from importing files from outside of src/ (or node_modules/). // This often causes confusion because we only process files within src/ with babel. // To fix this, we prevent you from importing files out of src/ -- if you'd like to, // please link the files into your node_modules/ and let module-resolution kick in. // Make sure your source files are compiled, as they will not be processed in any way. new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]), ], }, resolveLoader: { plugins: [ // Also related to Plug'n'Play, but this time it tells Webpack to load its loaders // from the current package. PnpWebpackPlugin.moduleLoader(module), ], }, module: { strictExportPresence: true, rules: [ // Disable require.ensure as it's not a standard language feature. { parser: { requireEnsure: false } }, // First, run the linter. // It's important to do this before Babel processes the JS. { test: /\.(js|mjs|jsx|ts|tsx)$/, enforce: 'pre', use: [ { options: { cache: true, formatter: require.resolve('react-dev-utils/eslintFormatter'), eslintPath: require.resolve('eslint'), resolvePluginsRelativeTo: __dirname, }, loader: require.resolve('eslint-loader'), }, ], //=================== INCLUDED =====================/ // // Included the lenrna packages directory (up directory) // in order to transpile all files from other packages. // //=================================================== include: [path.resolve(__dirname, "../.."), paths.appSrc], }, { // "oneOf" will traverse all following loaders until one will // match the requirements. When no loader matches it will fall // back to the "file" loader at the end of the loader list. oneOf: [ // "url" loader works like "file" loader except that it embeds assets // smaller than specified limit in bytes as data URLs to avoid requests. // A missing `test` is equivalent to a match. { test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: require.resolve('url-loader'), options: { limit: imageInlineSizeLimit, name: 'static/media/[name].[hash:8].[ext]', }, }, // Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features. { test: /\.(js|mjs|jsx|ts|tsx)$/, /// Renato Mendes /// This was added to support transpiling of monorepo modules. /// See /// /// Original: /// include: paths.appSrc /// include: [path.resolve(__dirname, "../.."), path.resolve(paths.lernaRoot + "/packages"), paths.appSrc], // include: paths.appSrc, include: [paths.lernaRoot, paths.appSrc], loader: require.resolve('babel-loader'), options: { customize: require.resolve( 'babel-preset-react-app/webpack-overrides' ), plugins: [ [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]', }, }, }, ], ], // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ // directory for faster rebuilds. cacheDirectory: true, // See #6846 for context on why cacheCompression is disabled cacheCompression: false, compact: isEnvProduction, }, }, // Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features. { test: /\.(js|mjs)$/, exclude: /@babel(?:\/|\\{1,2})runtime/, loader: require.resolve('babel-loader'), options: { babelrc: false, configFile: false, compact: false, presets: [ [ require.resolve('babel-preset-react-app/dependencies'), { helpers: true }, ], ], cacheDirectory: true, // See #6846 for context on why cacheCompression is disabled cacheCompression: false, // If an error happens in a package, it's possible to be // because it was compiled. Thus, we don't want the browser // debugger to show the original code. Instead, the code // being evaluated would be much more helpful. sourceMaps: false, }, }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. // "style" loader turns CSS into JS modules that inject tags. // In production, we use MiniCSSExtractPlugin to extract that CSS // to a file, but in development "style" loader enables hot editing // of CSS. // By default we support CSS Modules with the extension .module.css { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, }), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See sideEffects: true, }, // Adds support for CSS Modules ( // using the extension .module.css { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }), }, // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the // extensions .module.scss or .module.sass { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, 'sass-loader' ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See sideEffects: true, }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass { test: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }, 'sass-loader' ), }, // "file" loader makes sure those assets get served by WebpackDevServer. // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. // This loader doesn't use a "test" so it will catch all modules // that fall through the other loaders. { loader: require.resolve('file-loader'), // Exclude `js` files to keep "css" loader working as it injects // its runtime that would otherwise be processed through "file" loader. // Also exclude `html` and `json` extensions so they get processed // by webpacks internal loaders. exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], options: { name: 'static/media/[name].[hash:8].[ext]', }, }, // ** STOP ** Are you adding a new loader? // Make sure to add the new loader(s) before the "file" loader. ], }, ], } ... I'm still getting the error, as my external component is not getting transpiled.

    How to make the above webpack config transpile my code that resides in another package of my lerna project? Any other config missing? What am I doing wrong?

    Answer link :

  • Quick newbie question!
    1 project | | 3 May 2022
    This is some magic that happens behind the scenes when you run react-scripts build or start command. Under the hood, that's using Webpack to turn all of your source code into a more efficient, browser-readable bundle.
  • Modern, faster alternatives to ESLint
    10 projects | | 3 May 2022
    Webpack is a static module bundler for modern JavaScript applications - this means that it takes our JavaScript code and its dependencies and builds them into a single file. Webpack identifies all the dependencies (including images and other non-code files) in an application and builds a dependency graph internally. It then makes this into several bundles that can be loaded onto the browser. Webpack doesn't require any configuration by default to work, but it supports custom configurations for more complex projects. Let's look at how we can configure webpack to work with ESLint.

What are some alternatives?

When comparing esbuild and webpack you can also consider the following projects:

swc - Rust-based platform for the Web

craco - Create React App Configuration Override, an easy and comprehensible configuration layer for create-react-app

vite - Next generation frontend tooling. It's fast!

Rollup - Next-generation ES module bundler

parcel - The zero configuration build tool for the web. 📦🚀

Tailwind CSS - A utility-first CSS framework for rapid UI development.

import-maps - How to control the behavior of JavaScript imports

Snowpack - ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️ [Moved to:]

terser - 🗜 JavaScript parser, mangler and compressor toolkit for ES6+