npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lad-tech/nsc-fast-install

v2.0.3

Published

Fast dependencies install for builds docker images of monorepo

Readme

@lad-tech/nsc-fast-install

Fast dependency installer for Node.js services in a monorepo.

nsc-fast-install analyzes the compiled JavaScript entrypoint of a service, finds the packages that are actually required at runtime, and copies only those packages into the service dist/node_modules.

The tool is intended for Docker and CI builds where copying the full root node_modules is too heavy.

Why

In many monorepos dependencies are installed once in the repository root:

backend/
  package.json
  package-lock.json
  node_modules/
  services/
    gate/
    shared/
    users/

This is convenient for development, but inefficient for service images. A service usually needs only a small part of the root dependency tree, while COPY node_modules puts everything into the image.

nsc-fast-install builds a smaller runtime node_modules for a specific service.

What It Does

  1. Resolves the service runtime entrypoint.
  2. Reads tsconfig.json, including JSONC syntax and extends.
  3. Reads the compiled JavaScript file from outDir.
  4. Scans static require() and import dependencies.
  5. Resolves packages using Node-compatible resolution, including package.json#exports.
  6. Expands transitive dependencies from package-lock.json.
  7. Recursively adds installed runtime optionalDependencies of copied npm packages, such as platform packages used by native modules.
  8. Handles npm workspaces and copies workspace packages as real directories, not symlinks.
  9. Writes the result to <outDir>/node_modules, to <output>/node_modules, or to the exact path passed with --nodeModulesOutput.

Install

npm i @lad-tech/nsc-fast-install -D

Basic Usage

Run the tool from the monorepo root after the service has already been built:

npx nsc-fast-install --service services/gate

Or pass an explicit entrypoint:

npx nsc-fast-install --entryPoint services/gate/start.ts

By default, dependencies are copied to:

services/gate/dist/node_modules

Build Order

The tool analyzes compiled JavaScript, not TypeScript source. Build the service first:

npm run build --workspace services/gate
npx nsc-fast-install --service services/gate

If outDir or the compiled entrypoint does not exist, the command fails with a non-zero exit code.

Entrypoint Resolution

For --service, the default strategy is runtime.

Runtime strategy checks source runtime files first:

  1. start.ts
  2. service.ts
  3. index.ts
  4. package.json#main

This is the right default for Docker/service builds where package.json#main may point to a library export such as dist/Api/index.js, while the real runtime entry is start.ts.

To prefer package.json#main, use:

npx nsc-fast-install --service services/gate --entryStrategy main

Package Exports

The resolver supports Node-style package.json#exports, including package subpaths.

Examples that are resolved correctly:

import { SchemaBuilder } from 'shared/SchemaBuilder';
import { WorkspaceFilesClient } from 'shared/clients/WorkspaceFilesClient';
import { UPLOAD_STREAM_MAGIC } from 'shared/helpers/uploadProtocol';
import schema from 'shared/clients/WorkspaceFiles/service.schema.json';

Supported export shapes include:

{
  "name": "shared",
  "exports": {
    ".": "./dist/index.js",
    "./SchemaBuilder": "./dist/SchemaBuilder.js",
    "./clients/*": "./dist/clients/*.js",
    "./helpers/uploadProtocol": "./dist/helpers/uploadProtocol.js",
    "./clients/*/service.schema.json": "./dist/clients/*/service.schema.json"
  }
}

Workspaces

The tool reads npm workspaces from the root package.json:

{
  "workspaces": ["services/*"]
}

Workspace packages are treated as valid dependencies even when they are not listed in the root dependencies.

For example, this is valid:

// services/gate/package.json
{
  "name": "gate",
  "dependencies": {
    "shared": "workspace:*"
  }
}

When npm creates a workspace symlink:

node_modules/shared -> ../services/shared

nsc-fast-install dereferences it and copies the actual package directory into the target node_modules. The Docker context receives a normal directory instead of a symlink.

Workspace dependencies are also expanded recursively. If gate depends on shared, and shared depends on logger, both workspace packages are copied.

Dependency Validation

The missing dependency check uses:

  • root package.json dependencies;
  • target service package.json dependencies;
  • workspace package names;
  • dependencies of referenced workspace packages.

This means service-local workspace dependencies do not need to be duplicated in the root dependencies.

Docker Example

FROM node:22-alpine AS build

WORKDIR /app

COPY package.json package-lock.json ./
COPY services ./services

RUN npm ci
RUN npm run build --workspace services/gate
RUN npx nsc-fast-install --service services/gate

FROM node:22-alpine

WORKDIR /app

COPY --from=build /app/services/gate/dist ./dist

CMD ["node", "dist/start.js"]

Adjust the final CMD to match your service output path.

CLI Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | --entryPoint <path> | string | - | Source or compiled entrypoint, for example services/gate/start.ts. | | --service <path> | string | - | Service directory, for example services/gate. | | --entryStrategy <runtime\|main> | string | runtime | Entrypoint strategy for --service. | | --output <path> | string | outDir | Parent directory where node_modules will be created. Relative paths are resolved from the service directory. | | --nodeModulesOutput <path> | string | - | Exact target node_modules path. Cannot be combined with --output. | | --exclude <list> | string | frontend | Comma-separated directory names to skip. | | --tsconfig <name> | string | tsconfig.json | Service tsconfig filename. | | --skipOptionalRuntimeDeps | boolean | false | Do not copy installed runtime optionalDependencies of selected npm packages. | | --dryRun | boolean | false | Print dependencies without copying or deleting target node_modules. | | --json | boolean | false | Print machine-readable dry-run JSON. Implies --dryRun. | | --verbose | boolean | false | Print resolver and copy details. | | --version | boolean | - | Print package version. |

Dry Run

Use --dryRun to inspect what would be copied:

npx nsc-fast-install --service services/gate --dryRun

Dry-run mode does not remove or create the target node_modules.

For CI and Docker scripts, use JSON output:

npx nsc-fast-install --service services/gate --json

The JSON payload includes entrypoint, targetNodeModules, deps, and missing.

Published Package

The npm package includes compiled JavaScript, source maps, generated declaration files, README, changelog, and the generated dist/package.json used by the CLI version command.

dist/package.json is created during build/prepack; it is not meant to be edited by hand.

Requirements

  • Node.js 22.14 or newer.
  • Node.js project with package-lock.json.
  • Compiled JavaScript output must exist before running the tool.
  • tsconfig.json may use comments, trailing commas, and extends.
  • Static imports or requires must be present in the compiled output. Dynamic runtime-only imports cannot always be detected.
  • npm workspaces are supported through the root workspaces field.
  • Runtime optionalDependencies are copied only when they are installed in the source node_modules; missing optional packages for other platforms are ignored.

Troubleshooting

Dist dir not found

The service has not been built, or compilerOptions.outDir points to a different directory.

Build the service first.

Compiled entrypoint not found

The source entrypoint was found, but the matching JavaScript file was not found in outDir.

Check:

  • whether the service build completed successfully;
  • compilerOptions.rootDir;
  • whether package.json#main points to a library entry instead of a runtime entry;
  • whether you need --entryPoint for this service.

Unresolved imports

The compiled file contains an import that cannot be resolved from the monorepo root or from the importing file.

Check:

  • package.json#exports;
  • workspace symlinks in root node_modules;
  • baseUrl and emitted JS paths;
  • whether the import exists in the compiled output.

Отсутствующие зависимости в package.json

A runtime package is used but is not declared in the root package, target service package, or workspace packages.

Add it to the package that owns the dependency.