main, jsnext:main and module
main property. It's the entry point of a package, which is exported when a client
requires the package.
Recently, I got an issue on one of my popular GitHub repos,
material-colors. It claimed that "colors.es2015.js const not supported in older browser (Safari 9)", which looked pretty obvious to me. ES2015 is a new spec. Why do older browsers support it?
I totally forgot about it at the time, but the
colors.es2015.js was exposed as the npm package's
jsnext:main. And to my surprise, it turned out that
jsnext:main shouldn't have jsnext or ES2015+ features like
const, arrow function and
class. What a contradiction!
Module bundlers that utilizes tree shaking to reduce bundle size, like Rollup and Webpack 2, require packages to expose ES Modules with
export. So they invented a non-standard property called
However, it had a problem. If the file specified
jsnext:main contains ES2015+ features, it won't run without transpilation on browsers that don't support those features. But normally people don't transpile packages in
node_modules, and many issues were created on GitHub. To solve the problem, people concluded that
jsnext:main shouldn't have ES2015+ features other than
export. What an irony.
I looked into a couple of popular repos, and they had both of
module in addition to
At this time, it seems to be a good idea to have both of them if you want to support tree shaking. If you don't, just go with only the plain old