NPM-INSTALL-CI-TEST(1)

πŸ’… NAME πŸ’…

okay bestie, welcome to npm-install-ci-test(1) β€” the npm page that's literally just "clean slate, then test". No cap, that's the whole vibe.

✨ Synopsis ✨

npm install-ci-test

aliases: cit, clean-install-test, sit

So yeah β€” four whole ways to summon the exact same energy. cit, clean-install-test, sit… pick your fave, they all do the same thing 🫢


🌸 Description 🌸

This command runs npm ci and then, like, immediately runs npm test. Back to back. No snacks in between. Clean install, then your tests, periodt. πŸ’…


πŸŽ€ Configuration πŸŽ€

real talk: every single one of these knobs is here, so grab a strawberry snack πŸ“ and settle in.

⭐ install-strategy

  • --install-strategy β€” picks how packages get plopped into node_modules
    • Default: "hoisted"
    • Type: "hoisted", "nested", "shallow", or "linked"

The four flavors, bestie:

  • hoisted (the default one) β€” installs the non-duplicated stuff up at the top level, and duplicates only where the directory structure actually needs them.
  • nested β€” the new name for what used to be --legacy-bundling. Installs in place, no hoisting at all.
  • shallow β€” used to be --global-style. Only the direct deps get installed at the top level.
  • linked β€” installs into node_modules/.store, links in place, and stays unhoisted.

We recommend that package authors use --install-strategy=linked while developing, so you catch undeclared ("phantom") dependencies before you publish: the isolated layout only exposes a package's declared dependencies, so an import of a package that was never added to package.json can fail instead of resolving by accident and shipping broken. See Catching undeclared ("phantom") dependencies ⟨/using-npm/developers#catching-undeclared-phantom-dependencies⟩.

⭐ legacy-bundling

  • --legacy-bundling β€” installs packages the same way they're actually depended on, instead of hoisting them in node_modules
    • Default: false
    • Type: Boolean
    • DEPRECATED: this option has been deprecated in favor of --install-strategy=nested

Heads up: this may cause very deep directory structures and duplicate package installs, because there's no de-duplicating happening. It sets --install-strategy=nested.

⭐ global-style

  • --global-style β€” only installs direct dependencies at the top level node_modules, but hoists on deeper dependencies
    • Default: false
    • Type: Boolean
    • DEPRECATED: this option has been deprecated in favor of --install-strategy=shallow

It sets --install-strategy=shallow. That's it, that's the whole job.

⭐ omit

  • --omit β€” which dependency types to leave off the installation tree on disk
    • Default: 'dev' if the NODE_ENV environment variable is set to 'production'; otherwise, empty.
    • Type: "dev", "optional", or "peer" (can be set multiple times)

Important detail, don't skip it πŸ‘€ β€” these dependencies are still resolved and added to the package-lock.json file. They're just not physically installed on disk.

If a package type shows up in both the --include and --omit lists, then it gets included. Include wins, periodt.

And if the resulting omit list includes 'dev', then the NODE_ENV environment variable will be set to 'production' for all lifecycle scripts.

⭐ include

  • --include β€” lets you define which types of dependencies actually get installed
    • Default: (empty)
    • Type: "prod", "dev", "optional", or "peer" (can be set multiple times)

This is literally the inverse of --omit=<type>.

Dependency types you name in --include will not be omitted, no matter what order you typed omit/include on the command line. Order doesn't matter, bestie, it's not a race. πŸ¦‹

⭐ strict-peer-deps

  • --strict-peer-deps β€” makes conflicting peerDependencies an actual install failure
    • Default: false
    • Type: Boolean

If it's true, and --legacy-peer-deps is not set, then any conflicting peerDependencies gets treated as an install failure β€” even if npm could reasonably guess the appropriate resolution based on non-peer dependency relationships. Like, npm could figure it out, but it won't, because you asked it not to. πŸ’€

By default, conflicting peerDependencies deep in the dependency graph get resolved using the nearest non-peer dependency specification β€” even if doing that means some packages receive a peer dependency outside the range set in their package's peerDependencies object.

When such an override happens, a warning is printed explaining the conflict and which packages were involved. But if --strict-peer-deps is set, that warning gets treated as a failure. 🫠

⭐ foreground-scripts

  • --foreground-scripts β€” runs all build scripts (preinstall, install, and postinstall) for installed packages in the foreground process, sharing standard input, output, and error with the main npm process
    • Default: false unless when using npm pack or npm publish where it defaults to true
    • Type: Boolean

Ngl this will generally make installs run slower, and be much noisier β€” but it's lowkey useful for debugging. Pick your chaos. πŸ”₯

⭐ ignore-scripts

  • --ignore-scripts β€” if true, npm does not run scripts specified in package.json files
    • Default: false
    • Type: Boolean

Okay but here's the nuance πŸŽ€ β€” commands explicitly intended to run a particular script, like npm start, npm stop, npm restart, npm test, and npm run, will still run their intended script if ignore-scripts is set. They just won't run any pre- or post-scripts. The main character script still shows up; the entourage stays home.

Setting ignore-scripts also disables .npm-extension execution, as if ignore-extension were set.

⭐ allow-directory

  • --allow-directory β€” limits npm's ability to install dependencies from directories
    • Default: "all"
    • Type: "all", "none", or "root"

By "directories" we mean dependencies that point to a directory instead of a version or semver range.

⚠️ please note that this could leave your tree incomplete and some packages may not function as intended or designed. Changing this setting will not remove dependencies that are already installed.

The three modes:

  • all β€” allows any directories to be installed.
  • none β€” prevents any directories from being installed.
  • root β€” only allows directories defined in your project's package.json to be installed.

It also allows directory dependencies to be used for other commands like npm view.

⭐ allow-file

  • --allow-file β€” limits npm's ability to install dependencies from tarball files
    • Default: "all"
    • Type: "all", "none", or "root"

"Tarball files" meaning dependencies that point to a local tarball file instead of a version or semver range.

⚠️ same warning, bestie: this could leave your tree incomplete and some packages may not function as intended or designed. Changing this setting will not remove dependencies that are already installed.

The modes:

  • all β€” allows any tarball file to be installed.
  • none β€” prevents any tarball file from being installed.
  • root β€” only allows tarball files defined in your project's package.json to be installed.

Also allows tarball file dependencies to be used for other commands like npm view.

⭐ allow-git

  • --allow-git β€” limits npm's ability to fetch dependencies from git references
    • Default: "none"
    • Type: "all", "none", or "root"

Git references = dependencies that point to a git repo instead of a version or semver range.

⚠️ again, fr fr: this could leave your tree incomplete and some packages may not function as intended or designed. Changing this setting will not remove dependencies that are already installed.

As of npm 12 the default is none. Git dependencies run git against a remote repo and may install configuration the project does not control. So opt in explicitly per project (in .npmrc) or per command (on the CLI) when you actually need git deps.

The modes:

  • all β€” allows any git dependencies to be fetched and installed.
  • none β€” prevents any git dependencies from being fetched and installed.
  • root β€” only allows git dependencies defined in your project's package.json to be fetched and installed.

Also allows git dependencies to be fetched for other commands like npm view.

⭐ allow-remote

  • --allow-remote β€” limits npm's ability to fetch dependencies from urls
    • Default: "none"
    • Type: "all", "none", or "root"

Urls = dependencies that point to a tarball url instead of a version or semver range.

⚠️ yes, the same warning: this could leave your tree incomplete and some packages may not function as intended or designed. Changing this setting will not remove dependencies that are already installed.

As of npm 12 the default is none. Tarballs that share a hostname with the configured registry (the typical case for the npm registry, GitHub Packages, and most private registries) are still installed normally. If your registry serves tarballs from a different host, set replace-registry-host or override this setting. Opt in explicitly per project (in .npmrc) or per command (on the CLI) when you intentionally install from a URL.

The modes:

  • all β€” allows any url to be installed.
  • none β€” prevents any url from being installed.
  • root β€” only allows urls defined in your project's package.json to be installed.

Also allows url dependencies to be used for other commands like npm view.

⭐ allow-scripts

  • --allow-scripts β€” comma-separated list of packages whose install-time lifecycle scripts (preinstall, install, postinstall, and prepare for non-registry dependencies) are allowed to run
    • Default: ""
    • Type: String (can be set multiple times)

This one's for one-off and global contexts specifically: npm exec, npx, and npm install -g, where no project package.json is involved. For team-wide policy in a project, use the allowScripts field in package.json (which also supports explicit denials), or configure it in .npmrc.

🚨 Passing --allow-scripts on the command line during a project-scoped npm install, ci, update, or rebuild is an error.</bold>

Each name is matched against a dependency's resolved identity, not against the package's self-reported name. And both --ignore-scripts and --dangerously-allow-all-scripts override this setting.

One more thing 🌸 β€” this value is not exported to the environment for child processes.

⭐ strict-allow-scripts

  • --strict-allow-scripts β€” turns the install-script policy from a warning into a hard error
    • Default: false
    • Type: Boolean

If it's true, any dependency with install scripts that isn't covered by allowScripts will fail the install, instead of being blocked with just a warning. Glow-up from complaint to consequence. πŸ’€

Dependencies explicitly denied with false in allowScripts are always silently skipped; this setting only affects unreviewed entries (packages with install scripts that are neither approved nor denied). And --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

Optional dependencies that can't be installed on the current platform or engine (a non-matching os, cpu, or libc) are not flagged, because their install scripts never run. Makes sense, they never even showed up. πŸ™ˆ

⭐ dangerously-allow-all-scripts

  • --dangerously-allow-all-scripts β€” bypasses the allowScripts policy entirely and runs every dependency install script, regardless of whether it was approved or denied
    • Default: false
    • Type: Boolean
πŸ”₯ intended as a migration escape hatch only β€” its use is strongly discouraged. Also --ignore-scripts still takes precedence over this setting.

It's giving "I'll deal with it later" and later is coming for you. πŸ‘‘

⭐ audit

  • --audit β€” when "true", submits audit reports alongside the current npm command to the default registry and all registries configured for scopes
    • Default: true
    • Type: Boolean

See the documentation for npm help audit for the details on what exactly gets submitted. 🧚

  • --bin-links β€” tells npm to create symlinks (or .cmd shims on Windows) for package executables
    • Default: true
    • Type: Boolean

Set it to false and npm won't do that. This is genuinely useful as a workaround for the fact that some file systems don't support symlinks β€” even on ostensibly Unix systems. 😭

⭐ fund

  • --fund β€” the funding-message toggle
    • Default: true
    • Type: Boolean

When it's set to "true" it shows that lil message at the end of every npm install acknowledging how many dependencies are out there looking for funding. Peep npm help fund for the deets. πŸ’Έ


πŸ§ͺ dry-run

  • Default: false
  • Type: Boolean

This one's for when you wanna be a looky-loo and not touch anything πŸ’… β€” it tells npm you don't want it making any changes, and it should only report what it would have done. You can pass it into literally any command that modifies your local installation, like install, update, dedupe, uninstall, plus pack and publish.

⚠️ Heads up bestie: this is NOT honored by other network-related commands, like dist-tags, owner, etc. So don't go thinking it's a universal vibe check. πŸ™ˆ

πŸ—‚οΈ workspace

  • Default: (empty)
  • Type: String (can be set multiple times πŸ‘€)

Lets you run a command in the context of the configured workspaces of the current project, while filtering so it only runs on the workspaces you named in this config option. It's giving "targeted" energy 🎯

Valid values for the workspace config are either:

  • Workspace names
  • Path to a workspace directory
  • Path to a parent workspace directory (this one will result in selecting all workspaces within that folder 🌸)

When it's set for the npm init command, you can point it at a folder of a workspace that doesn't even exist yet β€” and it'll create the folder and set it up as a brand new workspace within the project. Iconic behavior, honestly. ✨

This value is not exported to the environment for child processes.

🧺 workspaces

  • Default: null
  • Type: null or Boolean

Set it to true and the command runs in the context of all your configured workspaces. All of them. Every single one. 🫢

Explicitly setting it to false makes commands like install ignore workspaces altogether. And when it's not set explicitly:

  • Commands that operate on the node_modules tree (install, update, etc.) will link workspaces into the node_modules folder.
  • Commands that do other things (test, exec, publish, etc.) will operate on the root project, unless one or more workspaces are specified in the workspace config.
This value is not exported to the environment for child processes.

🏠 include-workspace-root

  • Default: false
  • Type: Boolean

Includes the workspace root when workspaces are enabled for a command. Basically: do we let the root project crash the party too? πŸ‘‘

When it's false, specifying individual workspaces via the workspace config β€” or all workspaces via the workspaces flag β€” will cause npm to operate only on the specified workspaces, and not on the root project. Root stays home. 😭

This value is not exported to the environment for child processes.

  • Default: false
  • Type: Boolean

When it's set, file: protocol dependencies get packed and installed as regular dependencies instead of creating a symlink. No symlink shenanigans, just the real thing. πŸŽ€

This option has no effect on workspaces. None. Zero. Nada. 🚫

🌈 See Also

  • npm help install-test
  • npm help ci
  • npm help test

And that's a wrap on this absolute unit of a man page, bestie πŸŽ€ You just read NPM@12.2.1, dated October 2026, page NPM-INSTALL-CI-TEST(1) β€” go forth and ship it, no cap πŸ’–βœ¨πŸ”₯

πŸ“¦ where this page comes from