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

initbox

v0.1.0

Published

CLI tool to install apps and tools based on YAML formulas from the web

Downloads

9

Readme

🚀 Dev Setup

A CLI tool to install apps and tools based on YAML formulas downloaded from the web.

Node.js TypeScript License

Features

  • 📦 Formula-based installation - Define your dev environment in YAML
  • 🌐 Remote formulas - Host your formulas anywhere (GitHub, GitLab, S3, etc.)
  • 🧙 Interactive wizard - Inquirer-powered interactive setup
  • 🎨 Beautiful CLI - Chalk-powered colorful output
  • 📁 Category selection - Install by category or individual tasks
  • 🔗 Dependencies - Automatic dependency resolution
  • 🖥️ Cross-platform - Support for macOS, Linux (brew, apt, npm, pip, etc.)
  • 🧪 Dry run mode - Preview what will be installed
  • 📂 TypeScript tasks - 22 pre-built task classes with full type safety

Installation

# Clone the repository
git clone https://github.com/yourusername/initbox.git
cd initbox

# Install dependencies
npm install

# Build the project
npm run build

# Link globally (optional)
npm link

Usage

Interactive Mode (Default)

Run the interactive wizard to select what to install:

initbox
# or
initbox interactive

Direct Install

Install from a formula URL directly:

# Install everything
initbox install https://example.com/my-formula.yaml

# Install specific tasks
initbox install https://example.com/my-formula.yaml -t git node-lts docker

# Install by category
initbox install https://example.com/my-formula.yaml -c "JavaScript/Node" "DevOps"

# Dry run
initbox install https://example.com/my-formula.yaml --dry-run

Inspect Formula

View formula contents without installing:

initbox inspect https://example.com/my-formula.yaml

Validate Formula

Validate a formula YAML file:

initbox validate https://example.com/my-formula.yaml

Formula Structure

Formulas reference tasks by ID. By default, tasks are loaded from the bundled TypeScript task library.

Formula File (formula.yaml)

Each task entry only needs id, category, and optionally version:

name: My Dev Setup
version: "1.0.0"
description: My development environment
author: Your Name

# tasksUrl: builtin (default - uses bundled tasks)
# tasksUrl: https://example.com/tasks (for custom remote tasks)

# Optional: require sudo privileges to execute
# require-sudo: true

categories:
  - Core Tools
  - JavaScript
  - Python

tasks:
  - id: git
    category: Core Tools
    version: "^2.40.0"

  - id: node-lts
    category: JavaScript
    version: "~20.0.0"

  - id: python
    category: Python
    version: "3.x"

Version Patterns

Dev-setup supports semver-style version patterns similar to package.json. When a task is executed, it checks the currently installed version against the requested version and only installs/updates if necessary.

| Pattern | Description | Example | Matches | |---------|-------------|---------|---------| | latest | Always satisfied, no update needed | latest | Any version | | 1.2.3 | Exact version match | 1.2.3 | Only 1.2.3 | | 1.2.x | Any patch version | 1.2.x | 1.2.0, 1.2.5, 1.2.99 | | 1.x or 1.x.x | Any minor/patch version | 1.x | 1.0.0, 1.5.3, 1.99.99 | | * | Any version (wildcard) | * | Any version | | ^1.2.3 | Compatible with version (same major) | ^1.2.3 | >=1.2.3 and <2.0.0 | | ~1.2.3 | Approximately equivalent (same minor) | ~1.2.3 | >=1.2.3 and <1.3.0 |

Examples:

tasks:
  # Install any 2.x version of git
  - id: git
    category: Core
    version: "2.x"

  # Install node 20.x but at least 20.10.0
  - id: node-lts
    category: JavaScript
    version: "^20.10.0"

  # Install exactly Python 3.11.4
  - id: python
    category: Python
    version: "3.11.4"

  # Always install/update to latest
  - id: docker
    category: DevOps
    version: "latest"

Sudo Requirements

Some formulas may require root/sudo privileges to execute (e.g., for system-level installations or modifying protected directories). You can mark a formula as requiring sudo with the require-sudo flag:

name: System Setup
version: "1.0.0"
require-sudo: true

tasks:
  - id: docker
    category: DevOps

When a formula with require-sudo: true is executed:

  1. CLI check: The installer verifies if running with sudo/root privileges
  2. Clear error: If not running as sudo, a clear message is shown with the correct command
  3. Dry run bypass: Dry runs (--dry-run) skip the sudo check for safe inspection
# Running without sudo shows an error:
$ initbox install https://example.com/system-formula.yaml
❌ This formula requires sudo privileges to execute.
   Please run the command with sudo:

   sudo initbox install https://example.com/system-formula.yaml

# Run with sudo:
$ sudo initbox install https://example.com/system-formula.yaml

Bundled Tasks

The following tasks are bundled with initbox and available to any formula:

| Category | Tasks | |----------|-------| | Core Tools | git, gh, curl, jq | | JavaScript/Node | nvm, node-lts, pnpm, bun | | Python | python, poetry | | Databases | postgresql, redis | | DevOps | docker, kubectl, terraform | | Productivity | fzf, ripgrep, bat, eza, lazygit | | Testing | hello |

Task Definition Format

Each bundled task is defined as a YAML configuration file in src/tasks/{id}/task.yaml:

# src/tasks/git/task.yaml
id: git
name: Git
description: Distributed version control system
homepage: https://git-scm.com
tags:
  - essential
  - vcs
dependencies: []
versionCommand: git --version
versionParseRegex: "git version (\\d+\\.\\d+\\.\\d+)"
steps:
  - name: Install Git
    type: brew
    command: git
    platforms:
      - darwin
  - name: Install Git (Linux)
    type: apt
    command: git
    platforms:
      - linux

Tasks are loaded and registered in src/tasks/index.ts:

import Task from './task.js';
import gitYaml from './git/task.yaml?raw';

export const taskRegistry: Record<string, ITask> = {
  git: Task.fromYaml(gitYaml),
  // ... other tasks
};

Task Interface

All tasks implement the ITask interface:

interface ITask {
  getId(): string;
  getName(): string;
  getDescription(): string | undefined;
  getHomepage(): string | undefined;
  getTags(): string[];
  getDependencies(): string[];
  getSteps(): InstallStep[];
  getDefinition(): TaskInfo;
  getVersionCommand(): string | undefined;
  parseVersion(output: string): string | undefined;
  checkVersion(desiredVersion?: string): Promise<VersionCheckResult>;
}

interface VersionCheckResult {
  installed: boolean;
  currentVersion?: string;
  needsUpdate: boolean;
  message: string;
}

Step Types

| Type | Description | Example | |------|-------------|---------| | brew | Homebrew package | command: 'git' | | npm | npm global package | command: 'typescript' | | pip | pip package | command: 'flask' | | apt | apt-get package | command: 'build-essential' | | shell | Shell command | command: 'echo "Hello"' | | curl | Download and execute | command: 'https://example.com/install.sh' | | git | Git clone | command: 'https://github.com/user/repo.git' |

Step Options

{
  name: 'Install Package',
  type: 'brew',
  command: 'package-name',
  args: ['--cask'],              // Additional arguments
  optional: true,                 // Don't fail if this step fails
  platforms: ['darwin', 'linux'], // Only run on specific platforms
  env: { MY_VAR: 'value' },       // Environment variables
  cwd: '/some/path',              // Working directory
  postInstall: ['echo "Done!"'],  // Commands to run after
}

Development

# Run in development mode
npm run dev

# Type check
npm run typecheck

# Build for production
npm run build

Project Structure

initbox/
├── src/
│   ├── cli.ts                  # CLI entry point
│   ├── types/
│   │   └── formula.ts          # Formula & Task type definitions
│   ├── parser/
│   │   └── formula-parser.ts   # YAML parsing & task resolution
│   ├── executor/
│   │   ├── step-executor.ts    # Executes individual steps
│   │   └── formula-executor.ts # Orchestrates installation
│   ├── interactive/
│   │   └── wizard.ts           # Inquirer-based wizard
│   └── tasks/                  # Bundled task definitions
│       ├── base.ts             # BaseTask class & ITask interface
│       ├── task.ts             # Generic Task class with fromYaml()
│       ├── index.ts            # Task registry
│       ├── git/
│       │   ├── task.yaml       # Git task configuration
│       │   └── README.md       # Git documentation
│       ├── node-lts/
│       │   ├── task.yaml       # Node.js task configuration
│       │   └── README.md       # Node.js documentation
│       └── ...                 # 21 tasks total
├── examples/
│   ├── dev-formula.yaml        # Example formula
│   └── minimal-formula.yaml
├── dist/                       # Built output
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md

Hosting Your Formula

You only need to host a simple YAML file that references bundled tasks:

# my-team-setup.yaml
name: Team Setup
version: "1.0.0"

tasks:
  - id: git
    category: Core
  - id: node-lts
    category: Dev
  - id: docker
    category: DevOps

Host it anywhere:

  • GitHub: https://raw.githubusercontent.com/user/repo/main/formula.yaml
  • Gist: Use raw gist URLs
  • Any web server: Just serve the YAML file

Usage:

initbox install https://raw.githubusercontent.com/user/repo/main/formula.yaml

Contributing Tasks

To add a new bundled task:

  1. Create a folder: src/tasks/{task-id}/
  2. Create task.yaml with the task configuration:
id: my-task
name: My Task
description: Description here
homepage: https://example.com
tags:
  - tag1
  - tag2
dependencies: []
versionCommand: my-task --version
versionParseRegex: "v?(\\d+\\.\\d+\\.\\d+)"
steps:
  - name: Install My Task
    type: brew
    command: my-package
    platforms:
      - darwin
  - name: Install My Task (Linux)
    type: apt
    command: my-package
    platforms:
      - linux
  1. Create README.md with documentation about the tool
  2. Register in src/tasks/index.ts:
import myTaskYaml from './my-task/task.yaml?raw';

export const taskRegistry: Record<string, ITask> = {
  // ... existing tasks
  'my-task': Task.fromYaml(myTaskYaml),
};
  1. Build and test: npm run build && npm run preview

License

MIT