Skip to content

doc: add path rules and validation for export targets in package.json #58604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions doc/api/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,59 @@ subpaths where possible instead of a separate map entry per package subpath
export. This also mirrors the requirement of using [the full specifier path][]
in relative and absolute import specifiers.

#### Path Rules and Validation for Export Targets

When defining paths as targets in the [`"exports"`][] field, Node.js enforces
several rules to ensure security, predictability, and proper encapsulation.
Understanding these rules is crucial for authors publishing packages.

##### Targets must be relative URLs

All target paths in the [`"exports"`][] map (the values associated with export
keys) must be relative URL strings starting with `./`.

```json
// package.json
{
"name": "my-package",
"exports": {
".": "./dist/main.js", // Correct
"./feature": "./lib/feature.js", // Correct
// "./origin-relative": "/dist/main.js", // Incorrect: Must start with ./
// "./absolute": "file:///dev/null", // Incorrect: Must start with ./
// "./outside": "../common/util.js" // Incorrect: Must start with ./
}
}
```

Reasons for this behavior include:

* **Security:** Prevents exporting arbitrary files from outside the
package's own directory.
* **Encapsulation:** Ensures all exported paths are resolved relative to
the package root, making the package self-contained.

##### No path traversal or invalid segments

Export targets must not resolve to a location outside the package's root
directory. Additionally, path segments like `.` (single dot), `..` (double dot),
or `node_modules` (and their URL-encoded equivalents) are generally disallowed
within the `target` string after the initial `./` and in any `subpath` part
substituted into a target pattern.

```json
// package.json
{
"name": "my-package",
"exports": {
// ".": "./dist/../../elsewhere/file.js", // Invalid: path traversal
// ".": "././dist/main.js", // Invalid: contains "." segment
// ".": "./dist/../dist/main.js", // Invalid: contains ".." segment
// "./utils/./helper.js": "./utils/helper.js" // Key has invalid segment
}
}
```

### Exports sugar

<!-- YAML
Expand Down
Loading