Often overlooked things when discussing esbuild here:
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.
Remember when all of these points applied to webpack, when it was the âsingle simple fast toolâ to replace everyoneâs grunt scripts?
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.
Something a lot of people donât appreciate is that the past ten years have been an anomaly for JavaScript. Theyâve been very tumultuous because there was a ton of evolving that suddenly needed to happen. And I think weâre nearing the end.
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
This is a great point. A "Cambrian explosion" the likes of which the JS ecosystem experienced over the last 10-15 years will slow down eventually. Curious to hear whether other folks agree or not.
I take your point, but I think you could fairly say that JS has been going through growing pains since its inception 25 years ago. It's always been a fast-moving, inconsistently-implemented language. (E.g. Netscape / Mozilla vs. IE support for browser features).
Maybe things are going to calm down a bit? I could believe it. But I just don't see the churn stopping. The browser-as-OS is going to keep getting new features, which JS must bind to. And some users are going to use old browsers that don't support them. So the runtime is inexorably fragmented, vs. say a server-side environment where you mostly write code for a well-known runtime that you get to define.
And what about when everybody starts using wasm to compile other languages into JS? Another explosion of tooling and changes to how we do web development is just round the corner.
Regardless of whether we're coming to the end of it, I think it's more specific than just "growing pains" though - it's not just that we're fixing issues, it's that we're repeatedly throwing away old tools in favor of smaller, more-focused new tools, that then in turn grow in scope over time.
I'm not even mad at all this; I think it's a fundamental part of how software languages and communities make progress; there's no real path for a language/tool/framework to get _smaller_, so they either increase in scope or stay the same, with the latter being quite rare, and both options giving a path for some other thing to supersede them.
I just think it's most pronounced in the JS ecosystem, and find it amusing that we've come full circle on so many of these points, again - although I believe with genuine improvements on the previous iterations. (So more like a spiral; the same location in some dimensions, but with a higher elevation.)
ESBuildâs author and docs[1] are quite clear about its future scope:
> [⌠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
"Weakness: since ESBuild doesnât expose its AST, plugins are often slow which can undermine the benefits of the tool"
I think by the time we even care about the performance of a plugin being "golang" fast, we will have rome built in rust.
Rome will be the full kit and caboodle at native speeds (bundler, tree shaking compiler, linter, type checker, etc...), whereas esbuild will be the rome-lite for when you just want to bundle some code and have it done.
> Remember when all of these points applied to webpack, when it was the âsingle simple fast toolâ to replace everyoneâs grunt scripts?
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.
I really donât, webpack config was was a cluster&âŹ@ from day 1. Also, webpacks goal always was to do everything and the kitchen sink, much different from esbuild.
Seconding that. Itâs the one reason I never started using webpack in the first place, at least not from scratch.
Angular ships with a working config out of the box, and I hope I never, ever will have to tweak that to fix a build.
> 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.
And the one guy writing it is Evan Wallace, co-founder and CTO of Figma. I don't know how he has the time!
Figma's tech is mindblowing. Their entire engine is custom-built in C++ : https://www.figma.com/blog/building-a-professional-design-to...
> 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!
He seems to like writing code
Ironically, the Figma tagline is "Nothing great is made alone"
What in the world? And some say 10x engineers donât existâŚ
I guess build times were a real issue for Figma and it started as an internal project.
This seems like a pet project. Reason I say that is if it was built for work, it would likely be from figma. Instead this project is from Evan himself.
> 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.
This was the reason that Phoenix 1.6 switched away from webpack to esbuild, apparently half the reported issues were webpack related!
This is exactly why the Elixir Phoenix team switched from Webpack to esbuild as the new default. They were spending more time responding to Webpack issues than Phoenix issues and it was an endless time sink.
Work on esbuild started at the start of 2020. It is primarily authored and maintained by Evan Wallace, who, in addition to making this tremendous contribution to the JavaScript ecosystem, is the CTO and co-founder of Figma. Incredible output.
I came here too say this. The man authored in the neighborhood of 100k LOC in a year, just on this. There's a living 10x dev, it's not a myth. What is ridiculous is to think someone can 10x a normal developer, it's more like the difference between the top few percent and the bottom 10-20%. Evan Wallace is a beast, no doubt.
While he is certainly an excellent developer with great productivity to boot, LOC is an obtuse metric. For example there is a package-lock.json commit which is almost 20K lines. Otherwise I totally agree.
Agree, if anything it should be the reverse, less LOC produced means more efficient developer. But that's also a shit metric, as then people start cramming in as much complexity in every line as possible.
Best would be if we could actually measure "complexity" in a objective manner.
I really wish people would stop idolising so called '10x' developers.
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.
Ehhh no I donât think itâs that simple.
Iâve found that in any tech company, while there are many people that write good code and do a great job, there are always a handful (even at a place like Apple) that truly push the industry forward and in certain directions, partly because of how they see years ahead, partly because they are supremely talented, and partly because they attract other really good talent just to work with them.
And we know many of their names. Folks like Brian Cantrill, Yehuda Katz, Fabrice Bellard, John Carmack, Bret Taylor.
They arenât just good programmers. Theyâre constantly dwelling in uncharted territory.
Iâm not advocating worshipping them, just stating that their talent and output is hell of a lot more than even 10x.
Perhaps that is what makes them '10x developers': a great familiarity with their toolset and a deep understanding of the problems they are solving. In this sense I don't think it's bad to idolize them, as familiarity and understanding are achievable by many people, and they could all become a '10x developer'.
And I really wish people would stop denying that there can be a massive difference in productivity from one individual to the next. It doesn't really matter what the theoretical limits are. What matters is the people you have and are hiring, and whether or not they are moving the needle.
Maybe we can put aside whether or not there is No True 10x Developer. But there are certainly 0.1x developers, and even -1x developers.
Sure, like anyone can be Usain Bolt if they are familiar with their body and has a deep understanding of running.
Amazing. That means he does his job right! As a good CTO you shouldn't have anything to do. If you're caught up in work, you're doing it wrong.
> As a good CTO you shouldn't have anything to do.
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.
and he's building tools to optimize his teams.
I don't understand this perspective. Everyone only has so many hours in a day, and there's only so fast you can 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.
As someone that ran a company while working on side open source projects, don't underestimate the therapeutic value of writing code. (As a CEO, my job had almost no coding, and working on my opensource projects made me happy, and restored a lot of my energy.)
CTO and lead developer on a focused project are very different jobs - my guess would be he relaxes from the very strategy and soft-skill heavy day job by diving into a challenging problem that keeps his dev chops up and lets him focus on a finite problem.
So working a shit ton then.
To echo what others have said here, my role as CTO and now CEO has gone from 95% coding to about 5% these days. So some nights I code on ideas and things that have been swirling in my head, just because itâs nice to just quietly write code and solve a finite (but possibly difficult) problem without interruptions. It actually IS therapeutic.
Same
The tool is likely helping Figma pretty directly by cutting developer build times.
Sounds like he solved his own problem?
Bun [1] is a JS bundler based on esbuildâs source, but written in Zig. And it is about 3x faster than esbuild. I think its author Jarred is on HN as well.
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
The numbers seem cherry picked though, I don't like this type of 197.96432100004x faster claims.
Iâm pretty sure ESBuildâs creator has agreed that Bunâs performance claims are probably correct, and that thereâs still more room for optimization of/beyond both.
Granted, those stats are for JSX, but itâll be interesting to check out for sure.
I've been trying to figure out how to build JS projects with the evolving tools (grunt => gulp => webpack => parcel => back to webpack) for years. I stumbled on esbuild and thought why not. Within about 15 minutes, I had solved pretty much all our build issues. Admittedly, our use case was simple-- we needed to transpile React-flavored TS to a npm package. In about 6 lines of code, I had a working bundle. There were no .esbuildrc or esbuild.config.js files, no babel dependencies, and no order of build operations to consider. The tool just worked and it was screaming fast. My first impression was that it _didn't_ work because the process closed in my terminal so quickly.
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.
> My first impression was that it _didn't_ work because the process closed in my terminal so quickly.
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
ESbuild is getting fantastic traction. Itâs the default in Phoenix from 1.6 and comes as a default option in the current alpha of Rails 7, which you can get with a simple
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
Esbuild w/rails 7 is nice, but if youâre using rails, check out vite_ruby [1]. I used it in a side project and it comes with plugins for views HMR + all the good stuff that comes built into vite.
Yes 100% - Iâm actually using Vite Ruby in a project as I really wanted to use Inertia + React and that was by far the easiest way to get everything up and running.
Iâd go so far as to say I wish -j vite was an option in js-bundling :)
Does it not support dynamic imports at all, or does it just not support âdynamic dynamic importsâ i.e. dynamic imports where the module path is not constant?
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.
You can use esbuild to your existing rails apps via the gem jsbundling-rails https://github.com/rails/jsbundling-rails
It works really well
Why is it so fast? Mainly because:
- 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.
Even in single threaded mode itâs fast. I think the main idea is that it creates an AST only a couple of times and then caches it so that the AST can be reused. Webpack on the other hand gets engulfed by its plugins which often do so multiple times.
We recently switched on a few of our project from Webpack and the difference is incredible. Running a watch using this is practically instantaneous compared to our previous setup. I've been recommending it to all my colleagues and we're replacing Webpack slowly but surely.
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.
Webpack is a bane of webdev existence.
Having junior team encounter a webpack breakage === them spending as much time on tooling, as coding itself
>Webpack is a bane of webdev existence.
Modern Web Dev is the cause of Webpack though. Over complicated things.
I cannot count the days I've spend on webpack config breakage during the last years at work. It's never really been good at all either. The gulp setup we had before worked faster, better and didn't break once a month. Webpack really only is a pet project of the idiocratic React-community. Facebook not only screws your personal data over, also your dev workflow!
what are you talking about, webpack has nothing to do with Facebook or React.
Do you have a public example of a PHP/Symfony project that you've ported from Webpack to esbuild?
I'm afraid not, it's all internal and not open-source. :(
esbuild is fast but it has a lot of place you have to figure out yourself and get into your way of doing thing.
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.
This is exactly what I found when I tried esbuild a few months ago. I gave up and went with Parcel 2 at the time as I found it easier to get going (although there were teething problems with Parcel being beta at the time).
I need to give esbuild another go I think.
esbuild is partially [0] used in Vite [1] where you get a dev server et al.
- [0] https://vitejs.dev/guide/why.html#why-not-bundle-with-esbuil... - [1] https://vitejs.dev/
How is the SCSS performance? I've tried just about every trick in the book in an attempt to get our bootstrap-based SCSS projects to compile faster, and I'm at my wits end with it.
Any chance you can share your config?
My project is small and it's amazing fast to me as well. It's basically just outsource its job to another cli. I used esbuild-plugin-sass
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
Thank you so much for sharing!
I'll give this a shot really quick
3. You can inject anything you want without a plugin with `inject`.
4. You can just use `target: node` (or node12, node14.6, etc)
Get a daily email with the the top stories from Hacker News. No spam, unsubscribe at any time.