hey alexlee, i also struggled w/ choice. i tend to use ESM mostly - it’s futureproof and works in modern envs, while sticking with CJS for node-only pkgs. umd’s nearly obsolete unless you need older browser support. docs - npm might help.
I’ve been through this dilemma too, and here’s what I’ve learned:
For packages used in both client and server environments, dual packaging (ESM + CJS) is indeed the most flexible approach. It covers all bases and caters to a diverse developer audience.
For Node-only applications, I prefer sticking with CommonJS. It’s robust in Node and sidesteps any additional overhead.
UMD has largely been phased out for me, owing to the rise of ES modules and modern bundlers. However, when absolute compatibility is necessary without a build process, UMD might still find its niche.
Always ensure your package is accompanied by a comprehensive README and solid CI/CD configuration to facilitate smoother adoption and maintenance.
In my experience, dual packaging (ESM + CJS) is the way to go for packages used across client and server. It offers the best compatibility and performance benefits. For Node-only packages, I still prefer CommonJS as it’s more straightforward and widely supported.
Regarding UMD, I’ve found its usefulness diminishing. Most modern projects use bundlers or CDNs that support ESM, making UMD less necessary. However, if you’re targeting a wide range of environments or creating a library for direct browser use, UMD can still be valuable.
For publishing open-source npm packages, I’ve found the npm documentation quite comprehensive. Additionally, GitHub’s guide on creating packages is an excellent resource. Remember to include clear documentation, examples, and maintain semantic versioning for your packages.