`platform=neutral` should be the default
Hi Evan. This issue is not a big deal and I would be satisified with you rejecting this for any reason at all. This is just something that has nagged at me for a long time using esbuild, and I couldn't find an existing issue mentioning it.
Currently, platform defaults to browser. I think it should instead default to neutral. Currently, esbuild defaults to applying a complex set of configuration options that are specifically intended to only be useful in a subset of use cases (bundling specifically for browsers). This simply seems very counter-intuitive to me; my intuition is that the default configuration would be as simple and broad as is reasonably possible, but this isn't the case. Literally every time I configure esbuild (which I have been doing frequently), I configure platform=neutral; it's necessary boilerplate that I have to ensure I remember to write.
One argument against doing this that I can think of is that this would be a huge breaking change, although it definitely could be accomodated by the semver rules. Another is: maybe you just want it this way. In the documentation, you say:
The bundler outputs code for the browser by default, so no additional configuration is necessary to get started.
I can totally see why you would want to make it as easy as possible for people to get started with browser use cases; indeed, esbuild is a "bundler for the web". Part of the problem I have is that I feel the default browser configuration is so complex that I configure platform=neutral even when bundling for browsers. I also wonder whether the browser configuration is outdated in the sense that it seems to be intended for older, non-ESM use cases (this is probably the biggest reason I feel like I can't use it).
I'm not necessarily arguing that the browser configuration shouldn't exist; it's just counter-intuitive to me that it's the default. I actually think that the neutral configuration is very browser-friendly; I think the biggest differences are just that it's simpler and more modern.
I would be grateful for any thoughts you have about this.
Doing this would instantly break pretty much all bundling of npm packages, which doesn't seem like a good default behavior. One of the reasons why I had esbuild do this by default is that I didn't like how Rollup needs extra configuration to work with npm packages (specifically both the @rollup/plugin-node-resolve and @rollup/plugin-commonjs plugins). That made Rollup harder to use for the common case.
I want esbuild to be easy to use for common use cases, while still making more custom use cases possible with extra configuration. The neutral platform is intended for custom use cases such as unusual JavaScript environments (e.g. microcontrollers, obscure module formats) and potentially requires a lot of extra configuration, which then requires a lot of extra knowledge about the inner workings of both esbuild's internals and the npm package format. I think it would be a mistake to have esbuild's default behavior require that esbuild's users learn and deal with all of that complexity just to get started.
I really appreciate you engaging with me on this and as I said, I'm happy with you rejecting this for any reason at all. But to respectfully try and push back a bit: specifically with regards to this matter, it kind-of feels like we're living in alternate universes. Literally nothing about this issue must make any sense to you at all; I assume you must be baffled that someone would even think to post this. If I had realised how different our perspectives were, I would have created an issue about concerns with the browser platform, rather than about the benefits of the neutral platform. Given that what you've said is in total contradiction to what I said and that you did not directly engage with the points that I raised, I'm left feeling quite awkward. Nonetheless, I'll try and respond to what you've said and clarify what I said.
You and I both know that the history of modules and packages in the JavaScript ecosystem is an absolute mess. I very much appreciate that part of your motivation in writing esbuild was to smooth over these incompatibilities and making building bundles as straightforward as possible. However, I don't think your sentiment with regard to this matter is an accurate reflection of the current state of the ecosystem. I think that, in the present day, the browser platform is much less useful than you think it is, and that the neutral platform is much more useful than you think it is.
Doing this would instantly break pretty much all bundling of npm packages, which doesn't seem like a good default behavior.
I agree that this would not be a good default behavior. Defaulting the platform to neutral would not result in this behavior. I assume (please correct me if I'm wrong) that you're referring to the fact that the browser platform sets a default value for main-fields. However, main fields are not required to bundle npm packages. Indeed, I can tell from the documentation that this is a point of disagreement:
The main fields setting is empty by default. If you want to use npm-style packages, you will likely have to configure this to be something else such as main for the standard main field used by node.
Since Node 12, "exports" has been the standard, intended way of specifying a package's entry points; the primary utility of the "main" field now is just backwards compatibility, which is even pointed out by the Node documentation itself. I personally have seen very few (if any) modern, recently-maintained packages that do not specify their entry point(s) using "exports"—with one exception, which is esbuild (which isn't of interest for bundling anyway). esbuild will bundle packages using their "exports" field even in the neutral platform without any additional configuration. It just works.
One of the reasons why I had esbuild do this by default is that I didn't like how Rollup needs extra configuration to work with npm packages (specifically both the
@rollup/plugin-node-resolveand@rollup/plugin-commonjsplugins). That made Rollup harder to use for the common case.
Just to reinforce what I'm already saying: these sorts of concerns are already effectively addressed by the neutral platform without additional configuration.
The neutral platform is intended for custom use cases such as unusual JavaScript environments (e.g. microcontrollers, obscure module formats) and potentially requires a lot of extra configuration, which then requires a lot of extra knowledge about the inner workings of both esbuild's internals and the npm package format.
I obviously cannot question what you intended it to be used for, but I guess I regret to inform that I and others are using it in ways you didn't intend. Respectfully, I think this sentiment is a very inaccurate reflection of the usefulness of the neutral platform (and of the comparative usefulness of the browser platform).
As I said originally, I am using the neutral platform for literally everything, always. I feel like it is essentially a requirement in order for esbuild to behave in a simple, modern, desirable way, to the point of it being necessary boilerplate I have to remember to write, as I said originally. I am confident that the browser platform was really important and useful when you wrote it, but I think that importance has severely diminished in the time since. I see the browser platform as a complex set of outdated settings that I literally never need and don't want—certainly not by default. The mere fact that it defaults the output format to iife is a non-starter as far as I'm concerned, but more than that, I feel that the various rules and special cases it applies makes the behavior of my builds harder to understand and less predictable. The simpler my configuration, the more and trust and confidence I have in my build to behave as I expect.
In total contradiction to what you've said, I use the neutral platform specifically because it makes my configuration simpler. For my various use cases, I don't have to apply literally any of the additional configuration you're suggesting I do in order to use the neutral platform; the neutral platform just works.
I want esbuild to be easy to use for common use cases, while still making more custom use cases possible with extra configuration.
I totally agree with this. This is actually the exact point I'm trying to argue. Currently, common use cases need/benefit from extra configuration: setting the platform to neutral. It's actually the browser platform that is more suited to "more custom use cases", although I'm not quite sure 'custom' is the right word in this case. I can see that there is clearly value in the browser platform for bundling outdated packages or for bundling packages that rely on strange/non-standard bundling behavior. With the mass adoption of ESM and "exports" in recent years, outdated packages and these sorts of special cases in common usage are rare and getting increasingly rarer. I see value in the browser platform for these sorts of use cases, but I don't think it's well-suited to being the default anymore.
As I mentioned at the beginning of this comment: in hindsight I realize that it would have been better to present this as a conversation about the browser platform rather than tunnel-visioning on the neutral platform, and I apologize for the miscommunication. "platform=neutral should be the default" really is just what my issue is. Thank you again for your time and your consideration.
As I said originally, this is a huge breaking change and I recognise that this is probably a bigger breaking change than you're comfortable making at this point. I guess I'm just left with the feeling that the default behavior is always going to be stuck in the past—since, respectfully, that is how it feels.
Closing as won't fix. Perhaps this was philosophically not the right default, but esbuild is very widely used at this point and I don't think changing this and breaking everyone is worth it just to fix a philosophical issue like this.