Package ecosystem
JavaScript and TypeScript Package Health: ESM, Types, Exports, and Boundaries
Modern JavaScript packages must navigate ESM/CJS compatibility, type definitions, and subpath exports. A clear package structure prevents runtime surprises for consumers and newcomers.
Avoid the dual package hazard with explicit export conditions
When a package supports both CommonJS (require) and ES Modules (import), subtle bugs can emerge if consumers load two separate instances of internal state. Modern Node.js relies on the exports field in package.json to declare entry points cleanly.
Order condition keys from most specific to least specific: types, import, require, and default. Ensure that subpath imports (like pkg/utils) are explicitly listed in exports or locked down to prevent consumers from relying on private internals.
- Use exports in package.json with types, import, require, and default keys.
- Provide separate ESM and CJS builds without leaking state between them.
- Prevent unintended private file imports by listing specific entrypoints.
Deliver first-class TypeScript types without broken imports
Shipping declaration files (.d.ts) is essential for modern developer experience. Ensure declaration files correspond 1-to-1 with entrypoints and that types are tested against NodeNext module resolution.
If using dual formats, supply separate .d.ts for CJS and .d.mts for ESM, or leverage tsup/pkgroll tools that generate verified type maps automatically.
Declare supported Node.js engines and audit dependencies
Specify the supported Node runtime versions in engines.node (e.g. >=18.0.0). This prevents installation failures in legacy environments and allows tools to warn users early.
Keep dependencies separated: production dependencies under dependencies, development and build tooling under devDependencies, and shared plugins in peerDependencies.
About this guide
Written by ETHIOR Editorial for contributors and maintainers. This guide explains practical product and repository practices; it is not legal, security, employment, or financial advice. Review the project’s How It Works, Privacy Policy, and Terms & Conditions for product boundaries.
Put the ideas into practice
Run a fresh public GitHub audit and use the visible contributor signals as a starting point—not as a certification of project quality or safety.
Check a repository