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

@locotineee/cli

v0.1.2

Published

CLI tool for adding NestJS modules from a registry (shadcn-style)

Downloads

278

Readme

@locotineee/cli

A shadcn-style CLI tool for adding pre-built NestJS modules to your project. Instead of installing opaque npm packages, this CLI copies module source code directly into your project — giving you full ownership and customization ability.

Table of Contents


How It Works

┌──────────┐     fetch      ┌──────────────┐     copy      ┌──────────────┐
│  CLI     │ ──────────────>│   Registry   │ ──────────────>│  Your Project│
│  (local) │                │   (remote)   │                │  src/modules/│
└──────────┘                └──────────────┘                └──────────────┘
                                                                   │
                                                            ┌──────┴───────┐
                                                            │ Auto-wires   │
                                                            │ app.module.ts│
                                                            │ package.json │
                                                            │ .env.example │
                                                            └──────────────┘
  1. Fetch — The CLI downloads the module descriptor (component.json) from a remote registry
  2. Copy — Template files are fetched and written to your src/modules/<name>/ directory
  3. Wire — The CLI auto-modifies app.module.ts (via TypeScript AST), package.json, and .env.example

You own the code. Edit it however you want after installation.


Quick Start

# 1. Initialize the CLI config (one-time setup)
npx @locotineee/cli init

# 2. See what modules are available
npx @locotineee/cli list

# 3. Add a module to your project
npx @locotineee/cli add health

# 4. Install new dependencies that were added
npm install

Running from the monorepo (development)

If you're developing within this monorepo, you can run the CLI directly:

# From the project root
node packages/cli/dist/cli.js init
node packages/cli/dist/cli.js list
node packages/cli/dist/cli.js add health

Commands

init

Initializes the CLI configuration for your project. Creates a nestjs-cli.config.json file in your project root.

npx @locotineee/cli init

What it does:

  1. Reads your nest-cli.json to detect project structure
  2. If monorepo, prompts you to select which app to target
  3. Prompts for a registry URL (defaults to the official registry)
  4. Writes nestjs-cli.config.json

Monorepo detection:

The CLI reads nest-cli.json. If "monorepo": true, it lists all application projects and lets you pick one:

? Select target application:
❯ nestjs-ultimate  (apps/nestjs-ultimate/src)
  nestjs-starter   (apps/nestjs-starter/src)

Output file (nestjs-cli.config.json):

{
  "registryUrl": "https://raw.githubusercontent.com/AggregatorIcapaci/nestjs-registry/main",
  "modulesDir": "apps/nestjs-ultimate/src/modules",
  "appModulePath": "apps/nestjs-ultimate/src/app.module.ts",
  "targetApp": "nestjs-ultimate"
}

list

Lists all available modules in the configured registry.

npx @locotineee/cli list

Example output:

Available modules (registry v1.0.0)

  Name      Version   Description
  ──────────────────────────────────────────
  health    1.0.0     Health check endpoints using @nestjs/terminus [infrastructure, monitoring]

  Total: 1 module(s)

add

Adds a module from the registry into your project.

npx @locotineee/cli add <module-name>

Example:

npx @locotineee/cli add health

What it does (step by step):

  1. Loads config — Reads nestjs-cli.config.json. If missing, tells you to run init first.

  2. Validates module — Fetches registry.json and confirms the module exists.

  3. Checks prerequisites — Some modules depend on others. For example, health requires DatabaseModule to be present in app.module.ts. If a prerequisite is missing, the CLI aborts with a clear message.

  4. Checks idempotency — If the module directory already exists, prompts whether to overwrite.

  5. Shows installation plan — Displays what will be installed:

    Adding module: health v1.0.0
    ℹ Health check module with database, disk, and memory indicators
    
      Files: 5
      Dependencies: @nestjs/terminus
      Env vars: HEALTH_DISK_THRESHOLD_PERCENT, HEALTH_MEMORY_HEAP_MB
    
    ? Proceed with installation? (Y/n)
  6. Copies files — Downloads and writes all module files:

    ✔ Created apps/nestjs-ultimate/src/modules/health/health.module.ts
    ✔ Created apps/nestjs-ultimate/src/modules/health/health.controller.ts
    ✔ Created apps/nestjs-ultimate/src/modules/health/indicators/database.indicator.ts
    ✔ Created apps/nestjs-ultimate/src/modules/health/indicators/disk.indicator.ts
    ✔ Created apps/nestjs-ultimate/src/modules/health/indicators/memory.indicator.ts
  7. Auto-wires app.module.ts — Uses TypeScript AST manipulation (ts-morph) to safely:

    • Add import { HealthModule } from '@modules/health/health.module';
    • Insert HealthModule into the @Module({ imports: [...] }) array under the correct section comment
  8. Updates package.json — Adds any new dependencies:

    ✔ Added dependency: @nestjs/terminus@^11.0.0
  9. Updates .env.example — Appends new environment variables:

    # Disk usage threshold for health check (0-1)
    HEALTH_DISK_THRESHOLD_PERCENT=0.9
    # Max heap memory in MB for health check
    HEALTH_MEMORY_HEAP_MB=300
  10. Prints post-install message:

    ✔ Module "health" added successfully!
    ℹ Run `npm install` to install @nestjs/terminus, then start your app.

After installation, remember to:

# Install any new dependencies that were added to package.json
npm install

# Start the app
npm run start:dev

# Test the health endpoint
curl http://localhost:3000/api/v1/health

Configuration

nestjs-cli.config.json

Created by init. All fields:

| Field | Type | Description | |-------|------|-------------| | registryUrl | string | Base URL of the module registry | | modulesDir | string | Where module files are copied to (relative to project root) | | appModulePath | string | Path to app.module.ts for auto-wiring (relative to project root) | | targetApp | string | Name of the target application (from nest-cli.json) |

You can edit this file manually. For example, to point to a different registry or change the modules directory.


Registry Format

The registry is a static file server (GitHub raw, S3, any CDN) with this structure:

registry/
  registry.json                           # Master manifest
  modules/
    <module-name>/
      component.json                      # Module descriptor
      files/
        <...template files...>            # Actual source code

registry.json (Master Manifest)

{
  "version": "1.0.0",
  "modules": [
    {
      "name": "health",
      "description": "Health check endpoints using @nestjs/terminus",
      "version": "1.0.0",
      "tags": ["infrastructure", "monitoring"]
    }
  ]
}

component.json (Module Descriptor)

Each module has a component.json that describes everything the CLI needs:

{
  "name": "health",
  "description": "Health check module with database, disk, and memory indicators",
  "version": "1.0.0",
  "dependencies": {
    "@nestjs/terminus": "^11.0.0"
  },
  "devDependencies": {},
  "files": [
    { "source": "files/health.module.ts", "target": "health.module.ts" },
    { "source": "files/health.controller.ts", "target": "health.controller.ts" }
  ],
  "moduleImport": {
    "moduleName": "HealthModule",
    "importPath": "@modules/health/health.module",
    "section": "Feature Modules"
  },
  "envVars": [
    {
      "key": "HEALTH_DISK_THRESHOLD_PERCENT",
      "value": "0.9",
      "comment": "Disk usage threshold for health check (0-1)"
    }
  ],
  "requiredModules": ["DatabaseModule"],
  "postInstallMessage": "Run `npm install` to install @nestjs/terminus, then start your app."
}

Fields:

| Field | Description | |-------|-------------| | name | Module identifier (used in add <name>) | | description | Human-readable description | | version | Semantic version of this module template | | dependencies | npm dependencies to add to package.json | | devDependencies | npm devDependencies to add | | files | Array of { source, target } — source is relative to module dir in registry, target is relative to destination dir | | moduleImport.moduleName | The exported class name (e.g., HealthModule) | | moduleImport.importPath | The import path to use in app.module.ts (uses project path aliases) | | moduleImport.section | Which comment section in app.module.ts to insert under (e.g., "Feature Modules") | | envVars | Environment variables to add to .env.example | | requiredModules | Other modules that must be present in app.module.ts before this one can be added | | postInstallMessage | Message displayed after successful installation |


Available Modules

health

Health check endpoints using @nestjs/terminus.

Adds:

| File | Description | |------|-------------| | health.module.ts | Module definition with Terminus | | health.controller.ts | GET /health endpoint with Swagger docs | | indicators/database.indicator.ts | Checks database connectivity via Prisma SELECT 1 | | indicators/disk.indicator.ts | Checks disk usage against configurable threshold | | indicators/memory.indicator.ts | Checks heap memory usage against configurable limit |

Dependencies: @nestjs/terminus@^11.0.0

Prerequisites: DatabaseModule (for the database health indicator)

Environment variables:

| Variable | Default | Description | |----------|---------|-------------| | HEALTH_DISK_THRESHOLD_PERCENT | 0.9 | Disk usage threshold (0-1, where 0.9 = 90%) | | HEALTH_MEMORY_HEAP_MB | 300 | Maximum heap memory in MB |

Endpoint: GET /api/v1/health

Example response:

{
  "status": "ok",
  "info": {
    "database": { "status": "up" },
    "disk": { "status": "up", "usagePercent": 45, "threshold": 90 },
    "memory": { "status": "up", "heapUsedMb": 85, "maxHeapMb": 300 }
  }
}

Self-Hosting a Registry

You can create your own private registry. The CLI only needs a static file server.

Option 1: GitHub Repository

  1. Create a repo with the registry structure above
  2. Push to GitHub
  3. Use the raw content URL: https://raw.githubusercontent.com/<org>/<repo>/main

Option 2: Any Static Host (S3, Cloudflare R2, Nginx)

  1. Upload the registry files preserving the directory structure
  2. Ensure files are served with correct MIME types (.json as application/json, .ts as text/plain)
  3. Use the base URL when running init

Creating a Custom Module

  1. Create modules/<name>/component.json following the schema above
  2. Add your template files under modules/<name>/files/
  3. Add the module entry to registry.json
  4. Template files are plain TypeScript — use the same path aliases as the target project (@modules/*, @database/*, @config/*, @common/*)

Troubleshooting

"No nestjs-cli.config.json found"

Run npx @locotineee/cli init first to generate the config file.

"Required module X not found in app.module.ts"

The module you're trying to add has a prerequisite. Add the required module first. For example, health requires DatabaseModule.

"Failed to fetch registry"

Check that your registryUrl in nestjs-cli.config.json is correct and accessible. The CLI uses native fetch with a 10-second timeout.

Auto-wiring failed

If the CLI can't safely modify app.module.ts (unusual file structure, parse errors), it prints manual instructions:

⚠ Please add the following manually to app.module.ts:

  import { HealthModule } from '@modules/health/health.module';

  Then add HealthModule to the imports array in @Module().

The module files are still copied — only the auto-wiring step is skipped.

Module directory already exists

The CLI detects existing modules and prompts before overwriting. Choose "No" to abort, or "Yes" to overwrite files (the auto-wiring step will skip if the import already exists in app.module.ts).