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

next-term

v0.1.2

Published

Build CLI applications using Next.js-style file-based routing.

Readme

next-term

Build CLI applications using Next.js-style file-based routing.

Features

  • File-based routing: Organize CLI commands using Next.js-style directory structure
  • React/Ink support: Build beautiful CLI UIs with React and Ink
  • Automatic bundling: All dependencies are bundled into a single distributable CLI
  • Easy distribution: Generate install scripts for easy CLI distribution
  • TypeScript support: Full TypeScript support out of the box
  • Watch mode: Development mode with hot reloading

Installation

npm install next-term
# or
pnpm add next-term
# or
yarn add next-term

Quick Start

0. Initialize your project

Run the interactive setup:

npx next-term init

This will:

  • Ask about your preferred distribution method (bundle or registry)
  • Create a next-term.config.json file with appropriate defaults
  • Generate a JSON schema for IDE autocomplete support
  • Skip unnecessary prompts based on your chosen build type
  • Automatically add .next-term and build output to .gitignore

1. Create command files

Organize your CLI commands using Next.js-style routing:

src/app/
  command.ts          # Default command (runs when no subcommand is provided)
  clock/
    command.tsx        # "my-cli clock" command
  users/
    command.ts         # "my-cli users" command
    [id]/
      command.ts       # "my-cli users <id>" command

2. Write command handlers

Each command.ts or command.tsx file exports a default handler function:

// src/app/command.ts
export default function handler() {
  console.log("Hello from my CLI!");
}
// src/app/clock/command.tsx
import React from 'react';
import { render, Text } from 'ink';

export default async function handler() {
  const Clock = () => {
    return <Text color="blue">Clock</Text>;
  };

  render(<Clock />);
}

3. Build your CLI

Bundle Mode (Self-Hosted Distribution)

npx next-term build

This will:

  • Find all command.ts and command.tsx files
  • Bundle them with all dependencies
  • Generate an install script at public/cli/install
  • Create a distributable CLI in public/cli/

Users can install your CLI by running:

curl https://your-domain.com/cli/install | sh

Registry Mode (npm Distribution)

npx next-term build --package

This will:

  • Find all command.ts and command.tsx files
  • Bundle them with all dependencies
  • Generate a package.json with automatic versioning
  • Create an npm-publishable package in .next-term/dist/

Publish to npm:

cd .next-term/dist
npm publish

Users can install your CLI from npm:

npm install -g your-cli-name

Build Options

  • --package - Create npm-publishable package in .next-term/dist
  • --backend-url <url> - Backend URL for CLI distribution (overrides config)
  • --x-deployment-id <id> - Deployment ID for versioning (overrides config)

Priority Resolution:

  1. CLI flags (highest priority)
  2. Config file values
  3. Vercel environment variables (VERCEL_URL, VERCEL_DEPLOYMENT_ID)
  4. Default values

Configuration

Create a next-term.config.json file to configure your CLI:

Bundle Mode Configuration

{
  "$schema": "./.next-term/next-term.config.schema.json",
  "cliName": "my-cli",
  "outputDir": "cli",
  "buildType": "bundle",
  "backendUrl": "https://my-site.com",
  "deploymentId": "production",
  "installPath": ".my-cli",
  "localBaseUrl": "http://localhost:3000"
}

Registry Mode Configuration

{
  "$schema": "./.next-term/next-term.config.schema.json",
  "cliName": "my-cli",
  "buildType": "registry",
  "localBaseUrl": "http://localhost:3000",
  "npmInfo": {
    "author": "Your Name <[email protected]>",
    "description": "My awesome CLI tool",
    "keywords": ["cli", "terminal", "automation"],
    "repository": {
      "type": "git",
      "url": "https://github.com/user/repo"
    },
    "homepage": "https://example.com",
    "bugs": {
      "url": "https://github.com/user/repo/issues"
    },
    "license": "MIT"
  }
}

Configuration Options

  • $schema - Path to JSON schema for IDE autocomplete (automatically added by npx next-term init)
  • cliName - Name of your CLI command (required)
  • buildType - Distribution mode: "bundle" (self-hosted) or "registry" (npm) (default: "bundle")
  • localBaseUrl - Local base URL for development (default: "http://localhost:3000")

Bundle mode only:

  • outputDir - Output directory relative to public/ (default: "cli")
  • installPath - Installation path on users' machines (default: ".demo-cli")
  • backendUrl - Backend URL for CLI distribution (optional)
  • deploymentId - Deployment ID for versioning (optional)

Registry mode only:

  • npmInfo - npm package metadata (optional object):
    • author - Package author (name )
    • description - Package description
    • keywords - Array of keywords for npm search (merged with defaults: "cli", "next-term")
    • repository - Source repository info (type and url)
    • homepage - Package homepage URL
    • bugs - Bug tracker info (url)
    • license - SPDX license identifier (default: "MIT")

JSON Schema Support

Running npx next-term init automatically creates a JSON schema file at .next-term/next-term.config.schema.json and adds a $schema reference to your config. This provides:

  • IDE autocomplete for all configuration options
  • Inline documentation as you type
  • Validation for config structure and values
  • Works with VS Code, WebStorm, and other JSON-schema-aware editors

The schema file is preserved during builds, so you retain IDE autocomplete when editing your config after building.

Build Types

Bundle Mode ("bundle"):

  • Outputs to public/{outputDir}/
  • Generates install script for curl-based installation
  • Users install via: curl https://your-domain.com/cli/install | sh
  • Auto-updates enabled: CLI checks for updates from your backend on startup
  • Best for self-hosted distribution

Registry Mode ("registry"):

  • Outputs to .next-term/dist/
  • Generates package.json with date-based versioning
  • Ready for npm publishing
  • Users install via: npm install -g your-cli-name
  • Auto-updates disabled: Relies on npm/yarn/pnpm for version management
  • Best for npm/yarn/pnpm distribution

README Documentation

For registry builds, next-term automatically includes README documentation in your npm package:

  1. README-CLI.md (priority): If this file exists in your project root, it will be copied to .next-term/dist/README.md
  2. README.md (fallback): If README-CLI.md doesn't exist, the main README.md is used instead

This allows you to maintain separate documentation:

  • README.md: For developers working on the codebase
  • README-CLI.md: For end-users installing your CLI from npm

Bundle mode doesn't copy README files (not needed for curl-based installation).

Gitignore Management

Running npx next-term init automatically updates your .gitignore file:

Always added:

  • .next-term - Internal build directory

Bundle mode only:

  • public/<outputDir> - Your CLI distribution files (e.g., public/cli)

If .gitignore doesn't exist, it will be created with additional essentials like node_modules and .env files.

Entries are added with a # next-term comment header for clarity. Existing formatting and comments in your .gitignore are preserved.

API

compile(options)

Compile your CLI application.

import { compile } from 'next-term';

await compile({
  folderPath: 'src/app',        // Path to your command files
  outputDir: 'cli',             // Output directory (relative to public/)
  watch: false,                 // Enable watch mode
  internalBuildPath: '.next-term', // Internal build directory
  baseUrl: 'https://example.com', // Base URL for CLI distribution
  cliName: 'my-cli',            // Name of your CLI
  deploymentId: 'deploy-123',   // Optional deployment ID
  installPath: '.my-cli',       // Installation path on user's machine
  buildType: 'registry',        // Build type: 'bundle' or 'registry'
  npmInfo: {                    // Optional npm metadata (registry mode only)
    author: 'Your Name',
    description: 'My CLI tool',
    keywords: ['cli', 'tool'],
    license: 'MIT',
  },
});

Command Routing

Commands are automatically routed based on file structure:

  • src/app/command.tsmy-cli (default command)
  • src/app/clock/command.tsxmy-cli clock
  • src/app/users/[id]/command.tsmy-cli users <id>

Route paths map directly to CLI commands:

  • / → default command
  • /clockclock subcommand
  • /clock/settingsclock settings nested command

Using React/Ink

You can use React and Ink to build interactive CLI UIs:

import React, { useState, useEffect } from 'react';
import { render, Text } from 'ink';

export default function handler() {
  const Counter = () => {
    const [count, setCount] = useState(0);

    useEffect(() => {
      const timer = setInterval(() => {
        setCount(c => c + 1);
      }, 100);

      return () => clearInterval(timer);
    }, []);

    return <Text color="green">{count} tests passed</Text>;
  };

  render(<Counter />);
}

Vercel Deployment

When building on Vercel, next-term automatically detects environment variables:

# On Vercel, these are automatically used:
# - VERCEL_URL → backend URL
# - VERCEL_DEPLOYMENT_ID → deployment ID

npx next-term build --package

You can still override with CLI flags if needed:

npx next-term build --package \
  --backend-url https://custom.com \
  --x-deployment-id custom-id

Automatic Versioning

Registry builds use date-based versioning with build hashes:

Format: YYYY.M.D-{buildHash}
Example: 2026.1.24-a1b2c3d4e5f6

This ensures:

  • Unique versions for every build
  • Chronological ordering
  • npm semver compatibility

Development

Run in watch mode during development:

npx next-term dev

This will watch for changes and rebuild automatically.

Troubleshooting

Config validation errors

If you're getting validation errors in your next-term.config.json:

  1. Make sure you've run npx next-term init to generate the JSON schema
  2. Check that the $schema field points to ./.next-term/next-term.config.schema.json
  3. Verify your IDE supports JSON schema validation (most modern editors do)

Registry build missing npm metadata

If your npm package is missing author, description, or other metadata:

  1. Add an npmInfo object to your config file (see Registry Mode Configuration above)
  2. Fill in the fields you want to include in package.json
  3. Rebuild with npx next-term build --package

Bundle mode CLI not auto-updating

Auto-updates only work in bundle mode. If you're using registry mode:

  • Updates are managed by npm/yarn/pnpm
  • Users update by running npm update -g your-cli-name
  • The CLI will not check for updates on startup

README not included in npm package

For registry builds:

  1. Create a README-CLI.md in your project root (recommended for CLI-specific docs)
  2. Or ensure README.md exists in your project root (used as fallback)
  3. The file will be automatically copied to .next-term/dist/README.md during build

Migration Notes

Breaking Changes

Output file renamed from runtime.js to cli.js

The compiled CLI output is now named cli.js instead of runtime.js. This affects:

  • Bundle mode: public/<outputDir>/cli.js
  • Registry mode: .next-term/dist/cli.js
  • Manifest field renamed from runtimeHash to cliHash

No migration needed - simply rebuild your CLI to use the new naming. Existing deployed CLIs continue working until rebuilt.

Requirements

  • Node.js 18+
  • TypeScript 5+

License

MIT