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

invoket

v0.1.6

Published

TypeScript task runner for Bun - uses type annotations to parse CLI arguments

Readme

invoket

A TypeScript task runner for Bun that uses type annotations to parse CLI arguments.

Features

  • Type-safe CLI parsing — TypeScript types determine how arguments are parsed
  • Zero configuration — Just write a Tasks class with typed methods
  • JSON support — Object and array parameters are automatically parsed from JSON
  • Namespace support — Organize tasks with db:migrate style namespaces
  • Rest parameters — Support for ...args variadic parameters
  • Auto-generated help — JSDoc descriptions become CLI help text

Installation

bun link invoket

Quick Start

invt                    # Show help
invt hello World 3      # Run task with args
invt db:migrate up      # Run namespaced task
invt --version          # Show version

Writing Tasks

Create a tasks.ts file with a Tasks class:

import { Context } from "invoket/context";

interface SearchParams {
  query: string;
  limit?: number;
}

/**
 * Project build and deployment tasks
 */
export class Tasks {
  /** Say hello with a name and repeat count */
  async hello(c: Context, name: string, count: number) {
    for (let i = 0; i < count; i++) {
      console.log(`Hello, ${name}!`);
    }
  }

  /** Search with JSON parameters */
  async search(c: Context, entity: string, params: SearchParams) {
    console.log(`Searching ${entity}: ${params.query}`);
  }

  /** Install packages (rest params) */
  async install(c: Context, ...packages: string[]) {
    for (const pkg of packages) {
      await c.run(`npm install ${pkg}`);
    }
  }
}

Namespaces

Organize related tasks into namespaces:

class DbNamespace {
  /** Run database migrations */
  async migrate(c: Context, direction: string = "up") {
    await c.run(`prisma migrate ${direction}`);
  }

  /** Seed the database */
  async seed(c: Context) {
    await c.run("prisma db seed");
  }
}

export class Tasks {
  db = new DbNamespace();
}

Call with invt db:migrate up or invt db.seed.

Type Mapping

| TypeScript | CLI Display | Example Input | |------------|-------------|---------------| | name: string | <name> | hello | | name: string = "default" | [name] | hello (optional) | | count: number | <count> | 42 | | force: boolean | <force> | true or 1 | | params: SomeInterface | <params> | '{"key": "value"}' | | items: string[] | <items> | '["a", "b", "c"]' | | ...args: string[] | [args...] | a b c (variadic) |

CLI Flags

| Flag | Description | |------|-------------| | -h, --help | Show help with all tasks | | <task> -h | Show help for a specific task | | -l, --list | List available tasks | | --version | Show version |

Task-Specific Help

Get detailed help for any task:

invt hello -h
# Usage: invt hello <name> <count>
#
# Say hello with a name and repeat count
#
# Arguments:
#   name            string     (required)
#   count           number     (required)

invt db:migrate --help
# Usage: invt db:migrate [direction]
#
# Run database migrations
#
# Arguments:
#   direction       string     (optional)

Context API

Every task receives a Context object as the first parameter:

async deploy(c: Context, env: string) {
  // Run shell commands
  await c.run("npm run build");
  
  // Capture output
  const { stdout } = await c.run("git rev-parse HEAD", { hide: true });
  
  // Ignore errors
  await c.run("rm -f temp.txt", { warn: true });
  
  // Echo command before running
  await c.run("npm test", { echo: true });
  
  // Change directory temporarily
  for await (const _ of c.cd("subdir")) {
    await c.run("ls");
  }
  
  // Sudo
  await c.sudo("apt update");
  
  // Access config
  console.log(c.config);  // { echo: false, warn: false, ... }
  
  // local() is alias for run()
  await c.local("echo hello");
}

Context Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | echo | boolean | false | Print command before execution | | warn | boolean | false | Don't throw on non-zero exit | | hide | boolean | false | Capture output instead of printing | | cwd | string | process.cwd() | Working directory |

RunResult

interface RunResult {
  stdout: string;
  stderr: string;
  code: number;
  ok: boolean;      // code === 0
  failed: boolean;  // code !== 0
}

Private Methods

Methods starting with _ are private and won't appear in help or be callable:

export class Tasks {
  async publicTask(c: Context) { }
  async _privateHelper(c: Context) { }  // Hidden
}

Testing

bun test

Requirements

  • Bun >= 1.0.0