oscli

Getting started

Install oscli, define one flow, and ship a typed CLI in a few lines.

oscli is a TypeScript-first CLI framework published on npm. You define prompts and flags once with a builder API, run your flow, then read typed values from cli.storage and cli.flags.

Install

Use the package manager you already use.

npm install @oscli-dev/oscli

Your first CLI

Start with the smallest possible CLI. This example stays under 10 lines and is complete.

src/cli.ts
import { createCLI } from "@oscli-dev/oscli";

const cli = createCLI(() => ({ description: "my tool" }));

await cli.run(async () => {
  cli.success("Done.");
});

Use this shape when you want a single-command CLI with no prompts yet.

Build a prompt-driven CLI

Add prompts, run them once, and read the resolved values from cli.storage.

src/cli.ts
import { createCLI } from "@oscli-dev/oscli";

const cli = createCLI((b) => ({
  description: "project setup",
  prompts: {
    project: b.text().label("Project").default("my-app"),
    framework: b
      .select({ choices: ["react", "vue", "svelte"] as const })
      .label("Framework"),
    approved: b.confirm().label("Continue?").default(true),
  },
}));

await cli.run(async () => {
  cli.intro("project setup");
  await cli.prompt.project();
  await cli.prompt.framework();
  await cli.prompt.approved();

  cli.success(`Created ${cli.storage.project}`);
  cli.outro("Done.");
});

Grow the same CLI

You can add JSON mode and return a machine-readable result without changing the rest of the flow.

src/cli.ts
const cli = createCLI((b) => ({
  description: "project setup",
  prompts: {
    project: b.text().label("Project"),
  },
  json: true, 
}));

await cli.run(async () => {
  await cli.prompt.project();
  cli.setResult({ project: cli.storage.project }); 
});

Run that command with --json to suppress decorative output and print only the JSON result.

Suggested layout

You do not need a special folder structure, but this is a clean starting point.

cli.ts
package.json
tsconfig.json

Setup flow

Use this order when you are starting a new CLI.

Install the package

Add @oscli-dev/oscli to your project.

Define prompts and flags

Put your builder definitions inside createCLI() so types are inferred once and reused everywhere.

Run the flow

Call await cli.run(...), resolve prompts, and read values from cli.storage and cli.flags.

oscli installs cleanly with npm, pnpm, Yarn, and Bun. The published package targets Node 18+ at runtime.

Use these pages next.

On this page