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

@qodalis/cli

v2.0.0-beta.13

Published

Framework-agnostic CLI engine for @qodalis terminal applications.

Downloads

136

Readme

npm version npm version npm version npm version Build Status License: MIT


Try It Online

| Framework | StackBlitz | CodeSandbox | Gitpod | |-----------|------------|-------------|--------| | Angular | Open in StackBlitz | Open in CodeSandbox | Open in Gitpod | | React | Open in StackBlitz | Open in CodeSandbox | Open in Gitpod | | Vue | Open in StackBlitz | Open in CodeSandbox | Open in Gitpod | | Vanilla | Open in StackBlitz | Open in CodeSandbox | Open in Gitpod |


Help command

Packages

| Package | Description | |---------|-------------| | @qodalis/cli-core | Shared interfaces, models, and types | | @qodalis/cli | Framework-agnostic terminal engine (50+ built-in commands) | | @qodalis/angular-cli | Angular wrapper | | @qodalis/react-cli | React wrapper | | @qodalis/vue-cli | Vue 3 wrapper |

Quick Start

Angular

npm install @qodalis/angular-cli
import { CliModule } from '@qodalis/angular-cli';

@NgModule({
  imports: [CliModule],
})
export class AppModule {}

Add styles to angular.json:

{
  "styles": [
    "node_modules/@qodalis/angular-cli/src/assets/styles.css"
  ]
}
<!-- Full terminal -->
<cli [options]="cliOptions" />

<!-- Collapsible panel -->
<cli-panel />

React

npm install @qodalis/react-cli
import '@qodalis/react-cli/styles.css';
import { Cli } from '@qodalis/react-cli';

function App() {
  return <Cli style={{ width: '100vw', height: '100vh' }} />;
}

Vue

npm install @qodalis/vue-cli
<script setup lang="ts">
import '@qodalis/vue-cli/styles.css';
import { Cli } from '@qodalis/vue-cli';
</script>

<template>
  <Cli :style="{ width: '100vw', height: '100vh' }" />
</template>

Configuration (all frameworks)

Pass options to customize the terminal:

const options = {
  welcomeMessage: {
    message: '-- your custom welcome message --',
    show: 'daily', // 'never', 'once', 'daily', 'always'
  },
  usersModule: {
    enabled: true,
  },
};

Built-in Commands

System

| Command | Aliases | Description | |---------|---------|-------------| | help | man | Show all commands or help for a specific command | | version | ver | Display CLI version and documentation link | | hotkeys | shortcuts, keys | Show keyboard shortcuts | | history | hist | Browse and clear command history | | theme | themes | Apply, customize, and save terminal themes (interactive selection with live preview) | | feedback | support | Report bugs or request features on GitHub | | pkg | packages | Install, update, remove, and browse packages |

Utilities

| Command | Aliases | Description | |---------|---------|-------------| | clear | cls | Clear the terminal (or Ctrl+L) | | echo | print | Print text to the terminal | | eval | calc, js | Evaluate JavaScript expressions | | sleep | wait | Pause execution for N milliseconds | | time | date | Show current local and UTC time | | uptime | — | Show session uptime | | uname | sysinfo | System and browser information | | screen | display | Screen, viewport, and terminal dimensions | | open | — | Open a URL in a new browser tab | | alias / unalias | — | Create and remove command aliases | | yes | — | Output a string repeatedly | | seq | sequence | Print number sequences | | cal | calendar | Display a monthly calendar |

Developer Tools

| Command | Aliases | Description | |---------|---------|-------------| | base64 | b64 | Encode / decode Base64 | | json | — | Format, minify, and validate JSON | | url | — | Encode, decode, and parse URLs | | jwt | — | Decode and inspect JWT tokens | | hash | — | SHA-256, SHA-1, SHA-384, SHA-512 hashes | | hex | — | Hex encode/decode and base conversion (2-36) | | color | colour | Convert between hex, rgb, hsl with preview | | random | rand | Random numbers, strings, UUIDs, coin flip, dice | | lorem | lipsum | Generate placeholder text | | timestamp | ts, epoch | Convert between Unix timestamps and dates | | convert | conv | Unit conversion (length, weight, temperature, data) | | clipboard | cb, pbcopy | Copy to / paste from clipboard |

Users

| Command | Aliases | Description | |---------|---------|-------------| | whoami | me | Display current user | | su | switch-user | Switch user session | | adduser | useradd | Add a new user | | listusers | users | List all users |

Package Manager

Install additional commands at runtime from npm — no rebuild needed.

Install packages

pkg browse                     # Browse available packages
pkg add guid                   # Install a package
pkg remove guid                # Remove a package
pkg update                     # Update all packages
pkg update [email protected]          # Pin a specific version
pkg check                      # Check for updates
pkg versions guid              # Show all published versions
pkg source set                 # Interactively select a package source (CDN)
pkg source set unpkg           # Set package source directly

Available Packages

Utility Plugins

| Package | Command | Description | |---------|---------|-------------| | @qodalis/cli-data-explorer | data-explorer | Interactive query console for SQL, MongoDB, Redis, Elasticsearch | | @qodalis/cli-guid | guid | Generate and validate UUIDs | | @qodalis/cli-regex | regex | Regular expression testing | | @qodalis/cli-qr | qr | QR code generation | | @qodalis/cli-speed-test | speed-test | Internet speed test | | @qodalis/cli-curl | curl | HTTP requests (GET, POST, PUT, DELETE) | | @qodalis/cli-password-generator | generate-password | Password generation | | @qodalis/cli-string | string | String manipulation (case, trim, reverse, slug, wc, etc.) | | @qodalis/cli-todo | todo | Task management | | @qodalis/cli-browser-storage | local-storage, cookies | Browser storage operations | | @qodalis/cli-text-to-image | text-to-image | Generate images from text | | @qodalis/cli-files | ls, cat, nano, mkdir, touch, rm | Virtual filesystem | | @qodalis/cli-yesno | yesno | Interactive yes/no confirmation prompts | | @qodalis/cli-server-logs | server logs | Live server log streaming with level filtering | | @qodalis/cli-server-jobs | server jobs | Manage server-side background jobs | | @qodalis/cli-users | whoami, adduser, login | User management and authentication | | @qodalis/cli-chart | chart | Render bar, line, and sparkline charts | | @qodalis/cli-cron | cron | Schedule and manage recurring commands | | @qodalis/cli-csv | csv | Parse, filter, sort, and convert CSV data | | @qodalis/cli-markdown | md | Render Markdown content in the terminal | | @qodalis/cli-encode | base64, url, hex, html | Encode/decode Base64, URL, hex, HTML entities | | @qodalis/cli-scp | scp | Secure copy — transfer files between local and remote | | @qodalis/cli-wget | wget | Download files from URLs | | @qodalis/cli-stopwatch | stopwatch | Interactive stopwatch and countdown timer |

Game Plugins

| Package | Command | Description | |---------|---------|-------------| | @qodalis/cli-snake | snake | Classic Snake game | | @qodalis/cli-tetris | tetris | Tetris | | @qodalis/cli-2048 | 2048 | 2048 sliding puzzle | | @qodalis/cli-minesweeper | minesweeper | Minesweeper | | @qodalis/cli-wordle | wordle | Wordle word game | | @qodalis/cli-sudoku | sudoku | Sudoku puzzle |

Language Packs

| Package | Language | |---------|----------| | @qodalis/cli-lang-es | Spanish | | @qodalis/cli-lang-fr | French | | @qodalis/cli-lang-de | German | | @qodalis/cli-lang-it | Italian | | @qodalis/cli-lang-pt | Portuguese | | @qodalis/cli-lang-ro | Romanian | | @qodalis/cli-lang-ru | Russian | | @qodalis/cli-lang-zh | Chinese | | @qodalis/cli-lang-ja | Japanese | | @qodalis/cli-lang-ko | Korean |

Any npm package with UMD support can also be loaded:

pkg add lodash
eval _.map([1, 2, 3], n => n * 2)

Server Integration

Connect the frontend terminal to a backend server for server-side command execution, interactive shell sessions, filesystem access, and event streaming. Three official backend implementations are available:

| Server | Package | Port | Tech Stack | |--------|---------|------|------------| | .NET | Qodalis.Cli | 8046 | ASP.NET Core, .NET 8 | | Node.js | @qodalis/cli-server | 8047 | Express, TypeScript, node-pty | | Python | qodalis-cli-server | 8048 | FastAPI, uvicorn |

All three implement the same API surface:

| Endpoint | Method | Purpose | |----------|--------|---------| | /api/cli/versions | GET | Version discovery | | /api/v1/cli/commands | GET | List registered command processors | | /api/v1/cli/execute | POST | Execute a CLI command | | /api/v1/cli/execute/stream | POST | Execute with SSE streaming output | | /ws/v1/cli/events | WS | Server-push event streaming | | /ws/v1/cli/shell | WS | Interactive PTY shell session | | /api/cli/fs/* | Various | Filesystem operations (ls, cat, upload, download, mkdir, rm) |

Connecting to a Server

import { CliOptions } from '@qodalis/cli-core';

const options: CliOptions = {
  servers: [
    { name: 'node', url: 'http://localhost:8047' },
    { name: 'dotnet', url: 'http://localhost:8046' },
    { name: 'python', url: 'http://localhost:8048' },
  ],
};

// Angular: <cli [options]="options" />
// React:   <Cli options={options} />
// Vue:     <Cli :options="options" />

SSE Streaming Execution

The frontend automatically uses SSE streaming when the server supports it, with transparent fallback to the legacy POST endpoint. Streaming processors emit output chunks as they execute rather than buffering the full response.

Resilience

The frontend includes built-in resilience features:

  • WebSocket auto-reconnect with exponential backoff (up to 5 attempts, max 30s delay)
  • Periodic health checks for disconnected servers (30s interval)
  • HTTP retry on transient fetch failures (1 retry with 1s delay)
  • Configurable request timeout per server (default 30s)

Server Plugins

| Plugin | Servers | Description | |--------|---------|-------------| | Background Jobs | .NET, Node.js, Python | Scheduled and recurring job execution with cron/interval support | | Admin Dashboard | .NET, Node.js | React-based web UI for server management — commands, jobs, plugins, logs, filesystem, events, and an embedded terminal | | AWS Cloud | .NET, Python | S3, EC2, Lambda, DynamoDB, IAM, ECS, SQS, SNS, CloudWatch with multi-profile credential management | | Data Explorer | .NET, Node.js, Python | SQL, MongoDB, Redis, Elasticsearch, and custom data source providers |

Docker

Run all three servers with Docker Compose from the workspace root:

docker compose up --build

Creating a CLI Plugin

Quick Start

Scaffold a complete plugin project with a single command:

npx @qodalis/create-cli-plugin

The interactive prompts will ask for:

| Prompt | Description | Example | |--------|-------------|---------| | Plugin name | Lowercase, no spaces, no cli- prefix (added automatically) | weather | | Description | Short description of the plugin | Weather forecasts | | Processor class name | PascalCase name for the command processor class | Weather |

You can also skip the prompts by passing arguments directly:

npx @qodalis/create-cli-plugin --name weather --description "Weather forecasts" --processor-name Weather

Or install globally:

npm install -g @qodalis/create-cli-plugin
create-cli-plugin

Standalone vs Monorepo Mode

The tool auto-detects whether you're inside the web-cli monorepo:

| Mode | Detection | Output directory | Package manager | |------|-----------|-----------------|-----------------| | Standalone | Any directory outside web-cli | ./qodalis-cli-<name>/ | npm or pnpm (auto-detected) | | Monorepo | Inside web-cli workspace | packages/plugins/<name>/ | pnpm (workspace) |

In monorepo mode, the tool also:

  • Creates project.json (Nx build + test targets)
  • Creates tsconfig.spec.json (Karma/Jasmine test config)
  • Updates tsconfig.base.json with the path alias @qodalis/cli-<name> -> dist/<name>

Generated Project Structure

qodalis-cli-weather/                    # or packages/plugins/weather/ in monorepo
  package.json                          # npm package with CJS/ESM/UMD exports
  tsup.config.ts                        # Build config (library + IIFE bundles)
  tsconfig.json                         # TypeScript config
  README.md                             # Auto-generated README
  src/
    public-api.ts                       # Public exports + ICliModule declaration
    cli-entrypoint.ts                   # IIFE entrypoint for browser runtime loading
    lib/
      version.ts                        # LIBRARY_VERSION + API_VERSION constants
      index.ts                          # Barrel re-exports
      processors/
        cli-weather-command-processor.ts # Command processor (your main logic goes here)
    tests/
      index.spec.ts                     # Jasmine test scaffold

Step-by-Step Workflow

1. Scaffold the plugin

npx @qodalis/create-cli-plugin --name weather

2. Implement your command processor

Edit src/lib/processors/cli-weather-command-processor.ts:

import {
    CliProcessCommand,
    DefaultLibraryAuthor,
    ICliCommandProcessor,
    ICliExecutionContext,
} from '@qodalis/cli-core';
import { LIBRARY_VERSION } from '../version';

export class CliWeatherCommandProcessor implements ICliCommandProcessor {
    command = 'weather';
    description = 'Weather forecasts';
    author = DefaultLibraryAuthor;
    version = LIBRARY_VERSION;

    // Sub-commands
    processors?: ICliCommandProcessor[] = [
        {
            command: 'forecast',
            description: 'Get weather forecast for a city',
            parameters: [
                {
                    name: 'city',
                    aliases: ['c'],
                    description: 'City name',
                    required: true,
                    type: 'string',
                },
                {
                    name: 'days',
                    aliases: ['d'],
                    description: 'Number of days',
                    required: false,
                    type: 'number',
                    defaultValue: '3',
                },
            ],
            processCommand: async (command, context) => {
                const city = command.args['city'];
                const days = parseInt(command.args['days'] ?? '3');
                context.writer.writeln(`Forecast for ${city} (${days} days):`);
                context.writer.writeSuccess('Sunny, 25°C');
            },
        },
        {
            command: 'current',
            description: 'Get current weather',
            acceptsRawInput: true,    // command.value = text after 'current'
            valueRequired: true,       // error if no value provided
            processCommand: async (command, context) => {
                context.writer.writeln(`Current weather in ${command.value}: Sunny, 25°C`);
            },
        },
    ];

    // Default handler (runs when user types just 'weather')
    async processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void> {
        context.executor.showHelp(command, context);
    }
}

3. Build the plugin

Standalone:

cd qodalis-cli-weather
npm run build          # or: npx tsup

Monorepo:

pnpm nx build weather

Build output goes to dist/weather/ with three bundles:

  • public-api.js (CJS) + public-api.mjs (ESM) + public-api.d.ts (types)
  • umd/index.js (IIFE — self-contained browser bundle for runtime pkg add)

4. Test the plugin

Standalone: Add your preferred test runner.

Monorepo:

pnpm nx test weather

5. Publish to npm

cd dist/weather         # or: cd qodalis-cli-weather/dist
npm publish --access public

Users can then install your plugin at runtime in any Qodalis CLI terminal:

pkg add @qodalis/cli-weather
weather forecast --city "New York"

The ICliModule Export

Every plugin exports an ICliModule object in public-api.ts. This is how frameworks register your plugin:

import { ICliModule } from '@qodalis/cli-core';
import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
import { API_VERSION } from './lib/version';

export const weatherModule: ICliModule = {
    apiVersion: API_VERSION,         // must be >= 2
    name: '@qodalis/cli-weather',
    processors: [new CliWeatherCommandProcessor()],
};

ICliModule also supports optional lifecycle hooks and configuration:

export const weatherModule: ICliModule = {
    apiVersion: 2,
    name: '@qodalis/cli-weather',
    processors: [new CliWeatherCommandProcessor()],
    dependencies: ['@qodalis/cli-curl'],     // boot other modules first
    priority: 0,                              // boot order (lower = first)
    configure(config) { /* ... */ return this; },
    onInit(context) { /* before processors initialize */ },
    onAfterBoot(context) { /* after all modules boot */ },
    onDestroy(context) { /* teardown */ },
};

The IIFE Entrypoint

src/cli-entrypoint.ts enables runtime loading via pkg add. It calls bootCliModule() which registers the module with the global window.__cliModuleRegistry:

import { bootCliModule, ICliModule } from '@qodalis/cli-core';
import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
import { API_VERSION } from './lib/version';

const module: ICliModule = {
    apiVersion: API_VERSION,
    name: '@qodalis/cli-weather',
    processors: [new CliWeatherCommandProcessor()],
};

bootCliModule(module);

Execution Context API

The ICliExecutionContext passed to processCommand provides:

| Property | Description | |----------|-------------| | context.writer | Terminal output — writeln(), writeInfo(), writeSuccess(), writeError(), wrapInColor() | | context.reader | User input — readLine(), readPassword(), readConfirm(), readSelect(), readMultiSelect(), readNumber() | | context.executor | Command execution — showHelp(command, context) | | context.clipboard | Clipboard — write(), read() | | context.state | Persistent key-value store | | context.progressBar | Progress bar widget | | context.spinner | Spinner widget | | context.terminal | Raw xterm.js Terminal instance | | context.onAbort | Subject<void> for Ctrl+C cancellation | | context.enterFullScreenMode() | Switch to full-screen TUI mode | | context.createInterval() / context.createTimeout() | Managed timers (auto-cleaned on abort) |

Registering Plugins in Your App

Angular (via providers)

import { CliModule, resolveCliModuleProvider } from '@qodalis/angular-cli';
import { weatherModule } from '@qodalis/cli-weather';

@NgModule({
  imports: [CliModule],
  providers: [resolveCliModuleProvider(weatherModule)],
})
export class AppModule {}

Angular (via template input)

import { weatherModule } from '@qodalis/cli-weather';

export class AppComponent {
  modules = [weatherModule];
}
<cli [modules]="modules" />

React

import { CliConfigProvider, Cli } from '@qodalis/react-cli';
import { weatherModule } from '@qodalis/cli-weather';

function App() {
  return (
    <CliConfigProvider modules={[weatherModule]}>
      <Cli />
    </CliConfigProvider>
  );
}

Vue

<script setup lang="ts">
import { CliConfigProvider, Cli } from '@qodalis/vue-cli';
import { weatherModule } from '@qodalis/cli-weather';
</script>

<template>
  <CliConfigProvider :modules="[weatherModule]">
    <Cli />
  </CliConfigProvider>
</template>

Data Explorer

The @qodalis/cli-data-explorer plugin adds an interactive, full-screen REPL for querying data sources (SQL, MongoDB, Redis, Elasticsearch, and custom providers) directly from the terminal.

Setup

Install and register the plugin, then configure backend servers:

import { dataExplorerModule } from '@qodalis/cli-data-explorer';

// Add to your modules array
const modules = [dataExplorerModule, /* ... other modules */];

// Configure at least one server with data explorer providers
const options: CliOptions = {
  servers: [
    { name: 'node', url: 'http://localhost:8047' },
    { name: 'dotnet', url: 'http://localhost:8046' },
    { name: 'python', url: 'http://localhost:8048' },
  ],
};

Or install at runtime without a rebuild:

pkg add data-explorer

Usage

data-explorer

Select a server and data source, then enter the full-screen REPL:

data-explorer> SELECT * FROM users WHERE active = true;

3 rows (12ms)
┌────┬───────┬──────────────┐
│ id │ name  │ email        │
├────┼───────┼──────────────┤
│  1 │ Alice │ [email protected] │
│  2 │ Bob   │ [email protected]   │
│  3 │ Carol │ [email protected] │
└────┴───────┴──────────────┘

data-explorer> \format json
Output format set to: json

data-explorer> db.users.find({"age": {"$gt": 25}})
[
  { "_id": "abc", "name": "Alice", "age": 30 },
  { "_id": "def", "name": "Bob", "age": 28 }
]

REPL Commands

| Command | Description | |---------|-------------| | \format <table\|json\|csv\|raw> | Switch output format | | \schema | Show database schema (tables, columns, types) | | \templates | List available query templates | | \use <name> | Load a template query | | \history | Show query history | | \clear | Clear screen | | \help | Show all commands | | \quit / \q | Exit |

Use Up/Down arrows for history navigation, Escape or Ctrl+C to exit.

Extending with Inline Commands

For quick one-off commands without creating a full plugin, implement ICliCommandProcessor directly in your app:

import {
  ICliCommandProcessor,
  CliProcessCommand,
  ICliExecutionContext,
} from '@qodalis/cli-core';

export class GreetCommandProcessor implements ICliCommandProcessor {
  command = 'greet';
  description = 'Greet someone by name';
  acceptsRawInput = true;
  valueRequired = true;

  async processCommand(
    command: CliProcessCommand,
    context: ICliExecutionContext,
  ): Promise<void> {
    context.writer.writeln(`Hello, ${command.value}!`);
  }
}

Register it with your framework (Angular: resolveCommandProcessorProvider(GreetCommandProcessor), React/Vue: pass via processors prop), or wrap it in an inline ICliModule:

const myModule: ICliModule = {
  apiVersion: 2,
  name: 'my-app-commands',
  processors: [new GreetCommandProcessor()],
};
~$ greet World
Hello, World!

Using the Engine Directly

For advanced use cases or non-framework environments, use CliEngine directly:

import { CliEngine } from '@qodalis/cli';

const engine = new CliEngine(document.getElementById('terminal')!, {
  welcomeMessage: { message: 'Welcome!', show: 'always' },
});

engine.registerProcessors([new GreetCommandProcessor()]);
await engine.start();

Features

  • Multi-framework — Angular, React, Vue, or vanilla JS
  • 38 official plugins — 24 utility, 6 games, 10 language packs
  • Command chaining with &&, ||, |, and >> operators
  • Command history with arrow key navigation
  • Tab-like completions and keyboard shortcuts (Ctrl+C, Ctrl+L, Escape)
  • 29 built-in themes with custom color support
  • Tabs & split panes — multiple terminals in tabs with horizontal splitting
  • User sessions with multi-user support
  • State persistence across sessions
  • Interactive prompts with live preview (select menus with real-time feedback)
  • Full-screen mode API for rich TUI commands (games, editors, pagers)
  • Progress bars, spinners, and text animations
  • Runtime package installation from npm
  • Server integration with SSE streaming, auto-reconnect, and health checks
  • Admin dashboard for server management (React SPA)
  • Data explorer for SQL, MongoDB, Redis, and Elasticsearch

Contributing

  1. Fork this repository
  2. Create a branch for your feature or bugfix
  3. Submit a pull request

License

MIT