Configuration

Most options are available either as a config file key, or a command line option (e.g. foo would be --foo), though their CLI version may support a more limited syntax. Some command line options also allow for a shorthand one letter syntax (e.g. -d foo instead of --dir=foo).

The config file defaults to nudeps.js in your project root, and should export an object literal:

export default {
	dir: "./vendor",
	prune: true,
};

Priority (weakest to strongest): hard defaults → defaults from a programmatic caller → built-in mode presets → config file values → matching override rules → CLI args.

Unknown or invalid options fail loudly: typos get a “did you mean” suggestion, invalid values report which layer supplied them, and options from previous versions point at their replacement. Inside override rules only keys are checked, so an invalid value there passes silently.

Top-level values are global; the overrides option scopes any package-scoped option (marked below) to specific packages, versions, or modes.

At a glance

Option Default CLI Per-package What it does
dir ./client_modules --dir, -d ✅ Where packages are materialized
map importmap.js --map, -o Import map injection script path
root Workspace root --root Directory the host serves as /
module false --module Load the map script as type="module"
terse false --terse Minify the map script
prune false --prune Keep only specifiers the entry points use
include — ✅ (only) Direct-install membership: "force" | true | false
ignore Dotfiles, lockfiles --ignore ✅ File globs to skip when copying
imports — ✅ Import map entries merged into the generated map
cjs true --cjs ✅ Shim CommonJS packages
subpaths "split" --subpaths Collapse subpath mappings: "split" | "combined" | "both"
symlink External deps only --symlink ✅ Symlink packages instead of copying
preserveSymlinks false --preserveSymlinks ✅ Keep symlinks inside copied packages
alias true --alias ✅ Unversioned stable paths to packages
wireLocalDeps — ✅ Add the notify hook to local deps’ package.json
overrides — Conditional rules: per package, mode, version
host Auto-detected --host Deploy host adapter
mode — --mode, -m Active mode, tested by rules
hooks — Lifecycle hook callbacks
config nudeps.js --config, -c Config file path
init false --init Full re-initialization: clear caches, regenerate

“Per-package” = settable from a package-matched override rule; an empty CLI cell means config file (or programmatic) only.

Output

dir

--dir, -d · Default: ./client_modules · Package-scoped

Directory to copy deployed dependencies to, relative to project root. It will be created if it does not exist. It is assumed that Nudeps owns this directory, do not use a directory path that you use for other things. Overriding it per package via a rule materializes just that package elsewhere (the import map follows).

map

--map, -o · Default: importmap.js

File path for import map injection script, relative to project root. Nudeps needs to be able to own this file, do not input a file you use for other things too.

root

--root · Default: workspace root

The directory your host serves as /. Hosts without symlink support (Netlify, Cloudflare) express aliases as redirect rules, which need URLs rather than file paths — so set this when dir lives inside a build output directory (e.g. an SSG’s dist/), or the rules will be written outside the deployed site and will not match. Defaults to the npm workspace root, which is typically the deploy root; in a single-package project that is the project root.

module

--module · Default: false

Set to true if the import map script will be loaded as <script type="module">. Please note that this will reduce browser support, as certain browsers do not support injecting import maps after any module has started loading.

terse

--terse · Default: false

Terser import map injection script (compact JSON, no error checks, reduced whitespace). Enabled by default in prod mode.

What gets included

prune

--prune · Default: false

Whether to subset only to specifiers used by the package entry points (true), or include all direct dependencies anyway. Packages with include: "force" survive pruning. See Pruning.

include

Rule-only (inside overrides)

One setting for direct-install membership, replacing separate add/force/exclude lists: true installs a package like a dependency even if unlisted (prunable), "force" also survives prune, false removes a package from direct installs, and undefined restores standard behavior.

export default {
	overrides: {
		"canvas-confetti": { include: true },
		"my-design-system": { include: "force" },
		"@netlify/blobs": { include: false }, // server-side dep
	},
};

Note that include: false does not guarantee absence from the map: a package actively imported by your code still gets mapped.

ignore

--ignore · Package-scoped

Any files to exclude from being copied to the target directory. See Deployed files.

On the command line each --ignore takes a single glob, and the flag may be repeated to add more. Commas do not separate globs: --ignore="dist/**,docs/**" is one glob that matches nothing. The { copy } and { ignore } object forms are config file only.

Resolution

imports

Config file only · Package-scoped

Import map entries deep-merged into the generated map, using the platform’s own imports shape: keys are specifiers, values are paths relative to the map file (or full URLs). Set a value to undefined to remove an entry from the map.

export default {
	imports: {
		lodash: "./vendor/lodash.js",
	},
};

Inside a package rule, values are package-relative paths instead, resolved against the package’s versioned directory — no node_modules paths needed:

export default {
	overrides: {
		"colorjs.io": {
			imports: {
				"colorjs.io/fn": "./src/index-fn.js",
				"colorjs.io/src/": "./src/",
			},
		},
	},
};

cjs

--cjs · Default: true · Package-scoped

Whether to add a CommonJS shim to the import map if any CJS packages are detected. Setting to false will omit both the shim and these packages from the import map. Override per package for misdetected packages. See How are CJS packages handled?

subpaths

--subpaths · Default: "split"

Whether to collapse multiple subpath entries for the same package into a single trailing-slash prefix (e.g. "pkg/" instead of individual "pkg/a", "pkg/b" entries):

Combining subpaths can produce significantly smaller import maps, but is a lossy process, as it can expose specifiers that would not have resolved to anything in the original package. Corresponds to the combineSubpaths option of @jspm/generator.

Linking

--symlink · Default: symlink local dependencies, copy the rest · Package-scoped

Whether to symlink a package into dir instead of copying it. Symlinking means edits to a local dependency are visible immediately, with no re-copy. dev mode sets it to true, prod mode to false.

Note

Netlify, Cloudflare Pages and GitHub Pages do not serve symlinks, so there symlink: true is a local-development affordance, not a deploy strategy. Vercel serves only symlinks that point inside the output directory, and AWS Amplify serves them wherever they point.

--preserveSymlinks · Default: false · Package-scoped

Whether to keep symlinks found inside a package as-is when copying it, rather than dereferencing them to real files. Scope to specific packages via override rules.

alias

--alias · Default: true · Package-scoped

Create unversioned symlinks pointing to versioned directories. Useful for stable URLs to package assets (CSS, images, etc.). See Aliases.

wireLocalDeps

Config file only · Package-scoped

Let Nudeps add "dependencies": "npx nudeps dependents" to the package.json of every local dependency in the chain, so each one notifies its dependents when its own dependencies change.

A package rule decides for that package and for the local dependencies it pulls in:

export default {
	wireLocalDeps: true,
	overrides: {
		"other-repo": { wireLocalDeps: false },
	},
};

Environment

host

--host · Default: auto-detected

Deploy host adapter: netlify, vercel, amplify, cloudflare, or gitHubPages. Set it to force one.

Note

Vercel runs npm install, and so Nudeps, only with a build step. So for Vercel projects, nudeps install adds "build": "nudeps" when there is no build script. It detects Vercel from vercel.json or .vercel/project.json (created by vercel link). Otherwise, run npx nudeps install --host vercel. Other runs never edit your package.json: they warn when the build script is missing and point you to npx nudeps install.

mode

--mode, -m

The active mode. Built-in presets: dev, prod; define your own with rules that match on mode. See Overrides & modes.

overrides

Config file only

Conditional config rules: override options per package, per mode, per version — or unconditionally. See Overrides & modes.

hooks

Config file only

Lifecycle hook callbacks: prepare-start, create-aliases-start, create-aliases-after-external, create-aliases-end. See blissful-hooks.

config

--config, -c · Default: nudeps.js

File path for nudeps configuration, relative to project root. It should export an object literal with the configuration options as keys.