Esbuild: Is this still just an "existence proof"?

Created on 13 Aug 2020  Â·  4Comments  Â·  Source: evanw/esbuild

In readme it says that the project is "existence proof" for a fast bundler. But it seems to me that this project is no longer just that.

  • it seems you are investing a lot of your time into it
  • judging by changelog your attention to details is well beyond MVP
  • the whole plugin API endeavor sounds like a direction to pretty mature bundler
  • people seem to use it in the wild. Only as a minifier but still.

On the other hand you are maintaining architecture.md which seems to me as a starting point for other people to reproduce some of your work before digging into code.

So is there some set of features that you are reaching after which you are going to abandon this project?

I mean it all looks very promising, but the perspective of getting abandoned after all is scary) Can you clarify this a little bit more please?) In readme or at least in this issue.

Most helpful comment

You're right that the project is more than that now. I should consider changing that part of the readme.

I'm not planning to abandon it. But I am planning to have it 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. I also don't want to commit to maintaining something with that large a scope. I hope that the extensibility points I'm adding to esbuild (transform API, bundling API, and plugin API) will make esbuild useful to include as part of more customized build workflows, but I'm not intending or expecting these extensibility points to cover all use cases.

For example, I'm not currently planning on adding features such as hot reloading and module federation to esbuild itself. There are a lot of other tools that are innovating in that space and if you have those needs, you should probably consider using other tools that are focusing on those features. If someone writes an esbuild plugin to implement either of those features, or uses esbuild's transform library as a part of their implementation, then that's great! But if it turns out it's not practical to use esbuild's API to make it do those things, then that's fine with me too. It wasn't designed for such a custom use case and there are other tools that already serve those needs better.

I'm imagining esbuild as a kind of "linker" for the web. It knows how to transform and bundle JavaScript and hopefully also CSS and HTML in the future. But the details of how your source code ends up as plain JavaScript, CSS, or HTML may be delegated to a higher layer, which may be an esbuild plugin or even another tool entirely that uses esbuild internally (e.g. Vite or Snowpack). Ideally the community can innovate on top of esbuild and other tools by writing 3rd-party code separately without putting code in esbuild itself.

So my goals for esbuild are roughly:

  1. Be a fast bundler that's the real deal (generates production-quality code) and works off-the-shelf in common scenarios (the 80-90% case?) where you aren't doing something too custom.

    I believe this has mostly been accomplished for the JavaScript library use case. However, the common scenarios I have in mind include working with CSS too, so I would still like to try tackling at least that. I consider exploring that direction to be part of my MVP. A plugin API will also help to achieve this goal of being usable in common scenarios. Another way of thinking about the focus on "common scenarios" is that esbuild takes a somewhat opinionated view about how a development workflow should work.

  2. Inspire other bundlers to care about speed and become much faster.

    This hasn't worked as well as I hoped. Existing tools are two orders of magnitude slower than they could be, which I personally think is pretty crazy! Surely there must be some low-hanging fruit performance-wise if there's a 100x speed difference. I was hoping that creating a benchmark and an existence proof would spark more conversation and action from major tools, but I haven't seen too much yet. That's also part of the reason I've been publishing notes on esbuild's architecture. I've been doing R&D on bundler speed and the ideas are likely reusable in other tools as well. My secret backup plan is for people who are still using other tools for major projects to use esbuild for more minor projects and get addicted to fast bundlers, and shift the ecosystem that way :)

    The Parcel team is aware of the esbuild benchmarks and has prototyped some big performance improvements to help large builds, which has been exciting to see. But I haven't yet seen movement from other tools in the space. Webpack 5 (the upcoming version of Webpack) also currently appears to be ~60% slower than Webpack 4 on my benchmark (75s vs. 45s), so some parts of the ecosystem might actually be getting slower in the future, at least for certain use cases. Keep in mind that Webpack 5 is still in development so TBD on the final performance numbers.

  3. Be a transform library for certain commonly-slow tasks (e.g. TS => JS, JSX => JS, JS minification) to speed up other tools.

    This is in a pretty good state already. The transform API in esbuild is already used by Vite and Snowpack, and it's possible to use esbuild as a minifier instead of standard JavaScript-based minifiers to speed up existing build workflows. This is a way for me to help achieve my goal of getting the ecosystem to speed itself up even within tools that aren't themselves considering investing in large performance improvements. People can write plugins for these tools that use esbuild as a library to improve performance somewhat while still keeping the same build workflow.

  4. Add an extensibility layer to esbuild for certain classes of integrations so esbuild is a real bundler in the same league as the major bundlers commonly in use.

    Front-end build workflows today are incredibly complex, and it'd be naive to expect esbuild to fit right in to existing workflows without some amount of customization. For example, people often do crazy stuff with path aliases, and sometimes have data in other formats that need to be converted during the build (e.g. GraphQL queries). I'm building a relatively scoped plugin API for esbuild with those use cases in mind. Light use of this plugin API will enhance developer ergonomics and greatly improve compatibility with existing code bases to help reach the 80-90% use case. But heavy use of this plugin API probably means esbuild is not a great fit for your code base, and will likely lose most of the huge performance advantage that esbuild offers. The plugin API hasn't been released yet, but I think the current work-in-progress design is very promising and should address these needs.

    I'm not planning on opening up all of esbuild's internals to plugins. For example, I'm not planning to have an API where you can manipulate the internal AST. This is partially to keep complexity down, partially to keep the platform stable, and partially to prevent the situation where I have to decide between improving esbuild and breaking plugins or keeping plugins working but being unable to improve esbuild. It was interesting to read a recently-published retrospective from the creator of Babel who is now working on Rome, because it mentions this happening to Babel:

    Over time, I learned the Babel would not have been able to successfully adapt to execute on this vision anyway. The solution to plugins was “expose all the internals” which is an extremely large API surface area to maintain and restricts your ability to make any changes.

Outside of esbuild, 90% of what I work on is web-based and I'm looking forward to using esbuild for all of my future projects. Even after esbuild reaches stability and I stop adding major new features, I'm planning to continue maintaining esbuild to keep up with the core technologies as their specifications evolve over time (i.e. JavaScript, TypeScript, CSS, and HTML). Basically keeping esbuild current and relevant.

Wow that turned out to be a much longer reply than I expected. I hope it was useful and that it answers your questions.

All 4 comments

You're right that the project is more than that now. I should consider changing that part of the readme.

I'm not planning to abandon it. But I am planning to have it 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. I also don't want to commit to maintaining something with that large a scope. I hope that the extensibility points I'm adding to esbuild (transform API, bundling API, and plugin API) will make esbuild useful to include as part of more customized build workflows, but I'm not intending or expecting these extensibility points to cover all use cases.

For example, I'm not currently planning on adding features such as hot reloading and module federation to esbuild itself. There are a lot of other tools that are innovating in that space and if you have those needs, you should probably consider using other tools that are focusing on those features. If someone writes an esbuild plugin to implement either of those features, or uses esbuild's transform library as a part of their implementation, then that's great! But if it turns out it's not practical to use esbuild's API to make it do those things, then that's fine with me too. It wasn't designed for such a custom use case and there are other tools that already serve those needs better.

I'm imagining esbuild as a kind of "linker" for the web. It knows how to transform and bundle JavaScript and hopefully also CSS and HTML in the future. But the details of how your source code ends up as plain JavaScript, CSS, or HTML may be delegated to a higher layer, which may be an esbuild plugin or even another tool entirely that uses esbuild internally (e.g. Vite or Snowpack). Ideally the community can innovate on top of esbuild and other tools by writing 3rd-party code separately without putting code in esbuild itself.

So my goals for esbuild are roughly:

  1. Be a fast bundler that's the real deal (generates production-quality code) and works off-the-shelf in common scenarios (the 80-90% case?) where you aren't doing something too custom.

    I believe this has mostly been accomplished for the JavaScript library use case. However, the common scenarios I have in mind include working with CSS too, so I would still like to try tackling at least that. I consider exploring that direction to be part of my MVP. A plugin API will also help to achieve this goal of being usable in common scenarios. Another way of thinking about the focus on "common scenarios" is that esbuild takes a somewhat opinionated view about how a development workflow should work.

  2. Inspire other bundlers to care about speed and become much faster.

    This hasn't worked as well as I hoped. Existing tools are two orders of magnitude slower than they could be, which I personally think is pretty crazy! Surely there must be some low-hanging fruit performance-wise if there's a 100x speed difference. I was hoping that creating a benchmark and an existence proof would spark more conversation and action from major tools, but I haven't seen too much yet. That's also part of the reason I've been publishing notes on esbuild's architecture. I've been doing R&D on bundler speed and the ideas are likely reusable in other tools as well. My secret backup plan is for people who are still using other tools for major projects to use esbuild for more minor projects and get addicted to fast bundlers, and shift the ecosystem that way :)

    The Parcel team is aware of the esbuild benchmarks and has prototyped some big performance improvements to help large builds, which has been exciting to see. But I haven't yet seen movement from other tools in the space. Webpack 5 (the upcoming version of Webpack) also currently appears to be ~60% slower than Webpack 4 on my benchmark (75s vs. 45s), so some parts of the ecosystem might actually be getting slower in the future, at least for certain use cases. Keep in mind that Webpack 5 is still in development so TBD on the final performance numbers.

  3. Be a transform library for certain commonly-slow tasks (e.g. TS => JS, JSX => JS, JS minification) to speed up other tools.

    This is in a pretty good state already. The transform API in esbuild is already used by Vite and Snowpack, and it's possible to use esbuild as a minifier instead of standard JavaScript-based minifiers to speed up existing build workflows. This is a way for me to help achieve my goal of getting the ecosystem to speed itself up even within tools that aren't themselves considering investing in large performance improvements. People can write plugins for these tools that use esbuild as a library to improve performance somewhat while still keeping the same build workflow.

  4. Add an extensibility layer to esbuild for certain classes of integrations so esbuild is a real bundler in the same league as the major bundlers commonly in use.

    Front-end build workflows today are incredibly complex, and it'd be naive to expect esbuild to fit right in to existing workflows without some amount of customization. For example, people often do crazy stuff with path aliases, and sometimes have data in other formats that need to be converted during the build (e.g. GraphQL queries). I'm building a relatively scoped plugin API for esbuild with those use cases in mind. Light use of this plugin API will enhance developer ergonomics and greatly improve compatibility with existing code bases to help reach the 80-90% use case. But heavy use of this plugin API probably means esbuild is not a great fit for your code base, and will likely lose most of the huge performance advantage that esbuild offers. The plugin API hasn't been released yet, but I think the current work-in-progress design is very promising and should address these needs.

    I'm not planning on opening up all of esbuild's internals to plugins. For example, I'm not planning to have an API where you can manipulate the internal AST. This is partially to keep complexity down, partially to keep the platform stable, and partially to prevent the situation where I have to decide between improving esbuild and breaking plugins or keeping plugins working but being unable to improve esbuild. It was interesting to read a recently-published retrospective from the creator of Babel who is now working on Rome, because it mentions this happening to Babel:

    Over time, I learned the Babel would not have been able to successfully adapt to execute on this vision anyway. The solution to plugins was “expose all the internals” which is an extremely large API surface area to maintain and restricts your ability to make any changes.

Outside of esbuild, 90% of what I work on is web-based and I'm looking forward to using esbuild for all of my future projects. Even after esbuild reaches stability and I stop adding major new features, I'm planning to continue maintaining esbuild to keep up with the core technologies as their specifications evolve over time (i.e. JavaScript, TypeScript, CSS, and HTML). Basically keeping esbuild current and relevant.

Wow that turned out to be a much longer reply than I expected. I hope it was useful and that it answers your questions.

Thank you.

Inspire other bundlers to care about speed and become much faster.
This hasn't worked as well as I hoped

People are suffering from slow bundlers, and your project is like a breath of fresh air. I think bundlers will pay more attention as soon as your audience reaches critical mass. Crossing fingers for you)

Should we close this or would you like to change readme first?

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

Thank you for this, really. I recently went through the pain of setting up a lerna typescript monorepo with webpack, jest, babel, eslint, (and probably a couple other tools I'm forgetting), and the amount of juggling config files to make everything "see" everything else was absurd. I suspect this is an artifact of "unopinionated X" being a big theme in the past few years, and we're now seeing the effect of that.

I would gladly give up the ability to customize everything in exchange for easy to use tools that don't get in my way all the time.

Closing this now that the new website is up.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Gotterbild picture Gotterbild  Â·  3Comments

aelbore picture aelbore  Â·  3Comments

elektronik2k5 picture elektronik2k5  Â·  3Comments

OneOfOne picture OneOfOne  Â·  3Comments

iamakulov picture iamakulov  Â·  4Comments