1. It's not just a faster replacement for a single %tool_name% in your build chain: for the vast majority of cases, it's the whole "chain" in a single cli command if you're doing it right.
That is, you don't just stick it inside, say, webpack as a faster replacement for babel (although you can). No, you look carefully through your webpack configs and its myriad of plugins, ask yourself whether you really need to inline css in jsx in png while simultaneously optimizing it for IE 4.0, realize you don't, through out the whole thing, and use esbuild instead.
I have two 50K+ LOC projects using esbuild, and I would use it even if it was slower than webpack/babel/tsc simply not to worry about the build chain breaking due to an update to some obscure dependency or plugin.
2. It is fast because it's written from scratch to do a set of particular things and do it fast, not just because it's Go and parallelized.
If you look at the commit log you will notice a lot of performance tweaks. If you look into the issues, you will find a lot of requests for additional features rejected, often due to possible negative performance impact.
3. The most impressive part about esbuild development is not just that it's one guy writing it: it is the level of support and documentation he manages to provide alongside.
The release notes alone are a good course into nitty-gritty details of the web ecosystem: all the addressed edge cases are explained in detail. To top it all off--all opened issues, no matter how uninformed they seem, find a courteous response.
It seems there’s a feature treadmill at work here where projects inexorably bloat as they get popular. But we tried “compose tools in the Unix way” with grunt too, and that led to spaghetti scripts, unique to each project, that were hard to reason about. I wonder if there is a middle way that can prevent the tool from giving in to the pressure to add features.
Babel was necessary because core syntaxes were changing so fast. Webpack’s sprawling nature was needed because there were so many alternate dialects, module systems to support, etc. Esbuild is only possible because we’ve generally converged on TypeScript, JSX, ES modules, etc. It knows what you probably were going to configure webpack to do anyway, so it can just do it.
So I wouldn’t call it a “treadmill”, I’d call it growing pains
> [… a list of features that are already done…]
> After that point, I will consider esbuild to be relatively complete. I'm planning for esbuild to reach a mostly stable state and then stop accumulating more features. This will involve saying "no" to requests for adding major features to esbuild itself. I don't think esbuild should become an all-in-one solution for all frontend needs. In particular, I want to avoid the pain and problems of the "webpack config" model where the underlying tool is too flexible and usability suffers.
That said, now quoting you…
> But we tried “compose tools in the Unix way” with grunt too, and that led to spaghetti scripts, unique to each project, that were hard to reason about.
In this respect, ESBuild’s firm stance has a major strength, and a major weakness:
- Strength: the Unix philosophy is easy to achieve, with esbuild-plugin-pipe[2]. There’s just one, simple plugin API, everything follows that same format
- Weakness: since ESBuild doesn’t expose its AST, plugins are often slow which can undermine the benefits of the tool
Don't recall perf being the win with Webpack, Webpack was "Web-Pack" because it allowed you to use CommonJS to co-locate external assets (SVGs, CSS, etc) with code, and then being able to produce distinct bundles from that dependency graph. Grunt had no clue what your source dep graph looked like, you had to build your own pipeline (specifying dependent tasks for each task). Of course, now everybody has their own Webpack config that alters some input or output, but it's a considerably more powerful tool than Grunt ever was.
You're forgetting the 6 months where everyone rewrote everything with Gulp.
And the one guy writing it is Evan Wallace, co-founder and CTO of Figma. I don't know how he has the time!
> Instead of attempting to get one of [HTML/SVG/JS Canvas] to work, we implemented everything from scratch using WebGL. Our renderer is a highly-optimized tile-based engine with support for masking, blurring, dithered gradients, blend modes, nested layer opacity, and more. All rendering is done on the GPU and is fully anti-aliased. Internally our code looks a lot like a browser inside a browser; we have our own DOM, our own compositor, our own text layout engine, and we’re thinking about adding a render tree just like the one browsers use to render HTML.
To most people, esbuild would be a full-time job. Based on the above, it seems that to Evan it's a fraction of the work he did in Figma's early days all at once!
This was the reason that Phoenix 1.6 switched away from webpack to esbuild, apparently half the reported issues were webpack related!
When Redux was first released in 2015, it was deliberately designed to be minimal and extensible. Other Flux libraries at the time had various forms of async handling built in (support for dispatching actions via promises, etc). Dan and Andrew wanted to avoid locking users in to any single form of async handling [0], so the middleware API was designed to let users pick their preferred async approach and syntax.
Similarly, the store setup process was entirely left up to users to add whatever middleware, enhancers, and other configuration users felt was appropriate. The docs were also always unopinionated about preferred file structures, how to organize logic, etc.
Over time, it became very clear that users _wanted_ more specific guidance about how to structure their apps, and wanted Redux itself to build in default setup and configuration.
As a result, we wrote a "Style Guide" docs page [1] that lists our recommended best practices, and created our official Redux Toolkit package [2] as the standard way to write Redux logic. RTK was designed to solve the most common problems and use cases we saw in the ecosystem [3], including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.
RTK has been extremely successful - we routinely get users telling us how much they enjoy using RTK [4], even if they disliked "vanilla Redux" previously.
We also recently released a new "RTK Query" API [5] [6] in RTK 1.6, which is a built-in data fetching and caching API inspired by libraries like Apollo and React Query. Again, similar theme - we looked at what users were doing and what pain points they were running into, and built an official API to help address those use cases.
[0] https://blog.isquaredsoftware.com/2017/09/presentation-might...
[1] https://redux.js.org/style-guide/style-guide
[2] https://redux-toolkit.js.org
[3] https://blog.isquaredsoftware.com/2019/10/redux-starter-kit-...
[4] https://www.reddit.com/r/reactjs/comments/px6kxy/redux_toolk...
[5] https://redux-toolkit.js.org/rtk-query/overview
[6] https://redux.js.org/tutorials/essentials/part-7-rtk-query-b...
Also, in case of working on an Electron project: How well does it handle main/render/preload compile targets and handling of native modules and linking?
Electron-forge is, for instance, the recommended toolchain for building Electron apps and the Webpack stuff is a particular pain in the ass.
It’s not. It doesn’t do hot reloading, and it’s one of the features the author rejected I think.
I guess Vite provides a nice development experience but is built on esbuild.
I'm also a huge fan of HMR, and esbuild in the past has been anti-HMR.
I chose my now "nom de plume" way back in zeros for its seeming originality and simplicity, when compared to my rather common and unwieldy "real" Polish name.
Make, Cmake and autoconf offered solutions in this space, but for C/C++.
I do like what esbuild and swc are doing though.
Anyone that is comfortable and familiar with their toolset (e.g. go, .NET, Java, C++) and has a deep understanding of a problem (and has likely solved it once already), can churn out code far, far, faster than an onlooker.
Is this for real? I mean, yeah, I don't think a CTO should be debugging build scripts, but hiring a great team, mentoring, aligning teams with a common technical vision, meeting with other company leaders to ensure the technical direction meets the needs of the business is an immense amount of work.
If he's writing esbuild that is taking time away from being the CTO of Figma. Either he's working a shit ton, one of the things (Esbuild or Figma) is being somewhat neglected, or his output is actually not as high as it looks.
Probably worth a submission on its own but I am just waiting till it is fully open source.
Edit: ( Deleted those Stats, since it may not be a fair comparison and it was probably not meant to be a fair benchmark in the first place. The details are still in the linked tweets. I do not know the author or am I in anyway affiliate with Bun. )
I am also wondering how much of those optimisation could be used on ESbuild. Since Rails 7 and Phoenix 1.6 will be using esbuild and not Webpack.
[1] https://twitter.com/jarredsumner/status/1390084458724741121
After my first experiment with it, I rewrote our hundreds of lines Cloud Functions deploy script in about 15 lines (most of which is configuration options on the `build()` method).
I'm curious to explore the tool more. Kudos and thanks to the author for an unbelievably useful contribution.
We switched to an esbuild/vite/rollup stack mid year and had the same experience, it's black magic compared to web pack et al
rails new your_app -j esbuild
The only sort of issue I’ve had with it so far is you can’t use it with Inertiajs[1] as it does not support dynamic imports out of the box. Although I’m hesitant to call it an issue if its not in the scope of the project. Perhaps there are plugins I can use.
[1] - https://inertiajs.com
I’d go so far as to say I wish -j vite was an option in js-bundling :)
If it’s the latter, you could have your Inertia page resolver be a giant switch statement of every possible page, where each case is a dynamic import call with a constant module name.
Kind of a pain but I think I’d prefer that if it meant I never had to write a webpack config again.
It works really well
- It's written in Go and compiles to native code. [...] While esbuild is busy parsing your JavaScript, node is busy parsing your bundler's JavaScript. By the time node has finished parsing your bundler's code, esbuild might have already exited and your bundler hasn't even started bundling yet. [...] Go is designed from the core for parallelism while JavaScript is not.
- Parallelism is used heavily.
The main draw for me is the simplicity of the config too. Webpack config (even using things like Symfony's Encore) is pretty convoluted and confusing to track. This, at least in my experience, has greater readability and is simpler to understand.
Having junior team encounter a webpack breakage === them spending as much time on tooling, as coding itself
Modern Web Dev is the cause of Webpack though. Over complicated things.
1. dev server: you have to write a bit of code for this server to act as webpack dev server 2. scss: need to install plugin, and plugin cannot use from command line then you need to write a bit of JavaScript 3. global function: if you do `process.env` now you need to inject into build script 4. node package: if the package use node stuff you have to define thing like `fs/stream` into package.json
very quickly it get into your way of doing thing.
However, once you get past that base line, the cost is constant, the complexity just stop right there and not adding up.
Plus, the speed is amazing.
I need to give esbuild another go I think.
- [0] https://vitejs.dev/guide/why.html#why-not-bundle-with-esbuil... - [1] https://vitejs.dev/
Any chance you can share your config?
This is the gist https://gist.github.com/v9n/c40a6ad2078d09dd86117924b415b7fb
As far as I know, esbuild has no intention to integrate with CSS and will outsorce it to plugin.
I used
4. You can just use `target: node` (or node12, node14.6, etc)
Rome is also being rewritten in Rust, it's more of a complete set of packages that subsume Webpack, Babel and all the other parts of the JS / TS development experience.
Overall I’m pretty bullish on Rust tooling and integration within the JS/ Wasm ecosystem !
Is that correct and how is that working for you practically if it is? The whole point for Typescript for me is to have a compiler typecheck my code and block errors at compile time. ESbuild not typechecking seemed like a major contradiction to using Typescript so I set up a Webpack build using the standard ts compiler.
I've been out the loop of client side stuff a couple of years so to start was bit of a rabbit hole. Grunt/Gulp had gone and now Webpack seems common with a growing fanbase for ESbuild because of it's speed.
This means that for example, during development, you can see your running code quickly, while your editor runs tsc to highlight type checking errors. And in your build system, you can produce a production bundle to test while in parallel checking for type errors.
If you want, your build script can include
`tsc -noEmit`
to type check before the build.Nothing in the above precludes using the compiler to typecheck the code, that's the primary usecase & what sibling is saying about thinking of it as a linter: if typechecking fails, don't build
I wish more products had landing pages that looked like that.
Parcel 2 was released as stable yesterday though and Evan has already updated comparison.
https://github.com/evanw/esbuild/commit/186446eae8cc8c7439eb...
I just switched to esbuild on our main project and the build time went from 7 minutes on CI to 1 second. Kinda stupid really. Anyway, here's to the future, let's hope it works out this time!
The fastest code is no code.
I never jumped into that bandwagon and my build times are instantaneous using regular scripts ...
6 if you include bash/make for using manual scripts to productionize your yui / jqueryUi / mooTools code with uglify/browserify/gcc/etc
Is that an exaggeration or did it really get 420x faster?
We're playing with ESBuild at work, TS/React build that takes 45+ seconds to run with webpack cold, 8 second for a rebuild. With ESBuild/Gulp, the full gulp watch task will refresh in about 1.2 seconds, of which ESBuild ran for about .4 seconds.
So the builds are ~100 times faster with ESBuild, and we're just running it cold every time because it's so fast.
---
It's also really exciting for run-time based compilation. I've been playing around with a server-side React rendering project, and I literally just run esbuild in the controller action in development (some prebuilding for releases) and it's wonderful. Live updates in roughly .6 seconds on average, even for relatively heavy components.
plus, if you're careful with your react code, you can build a react codebase that will actually run if client-side JS is disabled (you can render it all serverside)
This.
Bundling, and even barreling, have pretty much been solved problems for a while. Right now I feel that unit test frameworks, linters, and type checkers are by far the main bottlenecks in the development workflow.
https://eslint.org/docs/user-guide/command-line-interface#ca...
For TS, tsc has an —incremental flag. ts-fork-checker-plugin is non-blocking for the rest of the build too.
The watch rebuild time went from 3-5s (actually a lot when you save your code very often) to something like .5-1 s
The full build time went from 120s to less than 5s
With ESBuild, everything, all the things, build in 0.25 seconds. Build script has massively reduced complexity, as there's no point in running any command other than "build all". There's just the TS code and the output. I'm still running TypeScript in watch mode separately to get compilation errors on the fly (ESBuild doesn't run the TS compiler itself, it has a custom-built translator that optimistically throws away type information), but I no longer configure it to emit translated code. And did I mention the build script is massively simpler?
https://github.com/evanw/esbuild/issues/42#issuecomment-9339...
So I'm currently stuck with a build that takes minutes, even though in principle it should require only seconds.
It is crazy fast. It feels like the Turbo Pascal 3 of web development.
Vite seems to be one of the more interesting CRA alternatives. Though it uses esbuild only for development, and Rollup for production builds. It'll be interesting to see how this develops, and if the fast bundlers keep catching up in terms of features without getting slower.
[1] https://github.com/glromeo/esbuild-sass-plugin
[2] https://hexdocs.pm/phoenix/asset_management.html#esbuild-plu...
Maybe it'll help someone, one difference from the plugin doc was using:
const { sassPlugin } = require("esbuild-sass-plugin");
Instead of:
import { sassPlugin } from "esbuild-sass-plugin";
After all, it would not be Javascript without some import syntax shenanigan ;)
Personally I'd rather not use it at this point, but it's not viable yet
Why would things be easy in a complex project? If you've built complexity into your project it seems a little unreasonable to expect someone else's tool to fix that for you. At some point you need to accept that building things that are simple is your own responsibility. But building things that are simple is incredibly hard so don't be too down on yourself if your project is complex. Software complexity is like entropy; it's very easy to add complexity to a system, and very hard to remove it.
It's also worth noting that you probably don't really want a tool to make your complex project appear more simple. That would only hide the complexity from you, but it would still be there. If your project is complex then your best approach to solving that is a lot of documentation, a lot of testing, and a lot of refactoring.
Edit: though I guess if you include the sibling project swcpack, it covers the same ground. SWC itself doesn't though.
How many scripts does a site need to make it feel faster when bundled?
When I visit websites that are rendered serverside, they usually feel instant to me. Even when they load a dozen scripts or so.
It's because people are using these huge frameworks with a lot of bloated code, it's too big, now devs are forced to do tree shaking and what not to trim the fat... front end JS development has become a madhouse of unnecessary complexity, because of node.js as well...
I hope that with the help of DENO that doesn't suffer from all that cargo culting, front-end development can become a healthier ecosystem...
Yes, some apps are complex, but 99% of front-end UI aren't.
- fast TypeScript/JSX compile
- bundling shared code to reduce request waterfall/splitting to reduce redundancy
- bundle optimization (tree shaking/dead code elimination; minification is actually faster than not using it)
- a simple plugin system for use cases like other compiled frameworks like Vue or Svelte, or whatever else you might want in a build pipeline
While a website that loads scripts per page will only load the scripts that are needed on the current page.
Depends on what you're building. If you have many nested dependencies, you need to bundle them, and not rely on the browser to resolve them at runtime and do dozens of roundtrips to the server to fetch them.
The creator of Rails talks about it here: https://world.hey.com/dhh/modern-web-apps-without-javascript...
Then they'll be faster doing only one request, this is regardless of ssr or spa
Bundling also gives you slatic analysis (typescript and linting), and frees developers from developing in the dark, like keeping track in their brain what component in what script exposes what global.
No it doesn't do that, typescript compiler does the static analysis and whatever linter does the linting, you don't need a bundler for that, a bundler just takes many source files and bundles them into one.
I already replaced Webpack in my Phoenix project (you can compare default steps for building a release here https://nts.strzibny.name/12factor-elixir-phoenix-releases/) and cannot wait to do the same in Rails.
"Snowpack already uses esbuild internally as our default single-file builder for JavaScript, TypeScript and JSX files."
https://www.snowpack.dev/posts/2021-01-13-snowpack-3-0#built...
> Why is esbuild fast? > - It's written in Go and compiles to native code. > - Parallelism is used heavily. > - Everything in esbuild is written from scratch. > - Memory is used efficiently.
> Production readiness > - Used by other projects > - API stability > - Only one main developer > - Not always open to scope expansion
Esbuild is written in GO.
However, I am still have to use TSC to generate declaration files(dts). Are anyone aware of esbuold-like tool to do that job?
Do I recommend Parcel? Not sure, it feels like every time I update the package something breaks (in their defense, it is still in Beta).
It actually implies that JS GC can be faster because it doesn’t require global locks and can collect garbage in parallel.
I do have some complicated Webpack setups that I don't think can be solved with any other bundler.
Why is esbuild fast? https://esbuild.github.io/faq/#why-is-esbuild-fast
- It's written in Go and compiles to native code
- Parallelism is used heavily
- Written from scratch with performance as a goal
- Efficient use of memory
If you use `@aws/sdk`, you are going to have bad time with Typescript. Resolving its types can easily take >50% of compilation time for small projects.
2. It’s written in Go
A bit like Parcel, but faster.
Also if people don't want to use CDNs both Rails and Deno do allow you to serve ES modules from your server.
As a rails dev, I want one, strong opinion on what the default/best approach is. I don't want to configure anything
If someone has open mind, they can also google what is Parcel.
Here everyone: JS build tool in Go? Great!
+1 for parallelism of esbuild. I have a12 core machine and many tools either use one core or when forced to not benefit from more cores.
I also wish they would waste more memory, I have 32gb which re mostly unused even by large projects.
I stand by my opinion: dev tools should make it pleasant for developers not the tool writers.
I'm sorry, but the node.js community needs to stop producing these stuff... it doesn't do anything better than all the webpack vs gulp vs parcel vs snowpack vs rollup vs how many bundlers again?
People have said say that same thing each time a new one pops up since Grunt 10 years+ ago.
If you're going to use a JS bundler written in Go, just stick to MAKEFILE...