-
-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Summary
Propose a new inlinedDependencies field in package.json as a community convention for explicitly declaring which dependencies are physically inlined into a published tarball — regardless of how they were inlined. This is a purely declarative metadata field, intended to improve ecosystem observability without instructing any package manager to change its behavior.
Background: bundleDependencies Already Exists — But Is Not Enough
npm already supports a bundleDependencies field (also accepted as bundledDependencies). When set, npm pack and npm publish will copy the listed packages from node_modules directly into the tarball.
This is the mechanism behind packages like vite shipping cac — every npm install vite delivers a copy of cac, yet cac's download count reflects none of this. cac has 20M weekly downloads, and the real number is even higher.
However, bundleDependencies has a specific and narrow semantic: "copy from node_modules at pack time." It does not cover the equally common case where a bundler (Rollup, esbuild, webpack, etc.) statically inlines dependency code at build time. Authors using a bundler pipeline cannot accurately use bundleDependencies to describe their inlined deps, because the mechanism is fundamentally different and the version actually bundled may differ from what's in node_modules.
Proposed: inlinedDependencies Field
A new inlinedDependencies field as a community standard for declaring inlined dependencies regardless of how they were inlined. The key distinction:
| Field | Mechanism | Who sets it |
|---|---|---|
bundleDependencies |
npm pack copies from node_modules |
npm (automatically honored) |
inlinedDependencies (proposed) |
Any method: bundler tree-shaking, manual vendoring, npm pack copy, etc. |
Author declares explicitly |
inlinedDependencies is purely declarative metadata — it does not instruct any package manager to do anything. It is a signal to tooling and registries that says: "these packages are physically present in my tarball in inlined form."
Proposed field shape (open for discussion)
Option A — string[]
{
"inlinedDependencies": ["cac", "rollup"]
}Simple. Exact version must be inferred from dependencies in the same manifest.
Option B — Record<string, string | string[]> (name → exact version or list of versions)
{
"inlinedDependencies": {
"cac": "6.7.14",
"rollup": ["3.29.5", "4.9.1"]
}
}More explicit. Allows authors to record the exact version(s) bundled, which may differ from the range declared in dependencies. The value is an array to accommodate the case where a single package ends up bundled in multiple versions within the same tarball — for example, when two independent parts of a build depend on different major versions of the same library.
Both options are on the table. Community input on ergonomics and tooling compatibility is welcome.
Why Not Just Reuse bundleDependencies?
Its semantic is specifically tied to npm pack copying from node_modules. Using it to describe bundler-inlined code would be a misuse of the field and could mislead package managers and tooling that act on it today.
Open Questions
- Field name:
inlinedDependencies?vendoredDependencies? Other suggestions welcome. - Field format:
string[]vsRecord<string, string | string[]>? Are there other shapes worth considering? - Author adoption: This field is opt-in, meaning authors can simply ignore it — leaving the ecosystem with incomplete data. Possible paths to drive adoption: proactive outreach to high-download packages known to inline deps, integration with popular bundlers to emit the field automatically from the build module graph, or tarball inspection as a fallback to detect undeclared inlined packages and prompt authors to declare them.
- Tooling: Should the ecosystem provide a bundler plugin or CLI to auto-generate
inlinedDependenciesfrom a build output's module graph, rather than requiring authors to maintain it by hand?
Alternatives Considered
- Reuse
bundleDependenciesfor all cases: already exists, but semantically wrong for bundler-inlined code and risks confusing package managers. - Rely on tarball inspection alone: technically possible but expensive at scale, and gives authors no explicit, intent-declaring mechanism.
- Do nothing: leaves the ecosystem blind to a significant class of implicit dependency usage.
This is an RFC — all details are open for discussion. Also cross-posted to npmx as a potential consumer of this standard.