Core
Define, parse, route, and run type-safe CLI commands with Contexts and Extensions
@crustjs/core defines commands, routes and validates argv, constructs Contexts, applies Extensions, and runs Command Actions.
Install
npm install @crustjs/coreThe package supports Bun 1.4+, Node 24+, and Deno 2.8+.
Quick example
import { Crust } from "@crustjs/core";
const app = new Crust("hello")
.flags({ name: "verbose", type: "boolean", short: "v" })
.action(({ flags, stdout }) => stdout(flags.verbose ? "hello!" : "hello"))
.command("wave", (command) => command.action(({ stdout }) => stdout("o/")));
const outcome = await app.run([], { flags: { verbose: true } });
console.log(outcome.stdout); // => hello!The root action prints hello! when verbose is true. The wave command is an app-local leaf command; use defineCommand() for a reusable definition.
Context-owned flags
import { Crust as ContextApp, defineContext, defineFlag } from "@crustjs/core";
const apiKey = defineFlag("api-key", { type: "string", required: true });
const api = defineContext("api")
.flags(apiKey)
.setup(({ flags }) => ({
apiKey: flags["api-key"],
}));
const contextApp = new ContextApp("my-cli")
.provide(api())
.action(async ({ ctx, stdout }) => stdout((await ctx.api).apiKey));
const contextOutcome = await contextApp.run([], { flags: { "api-key": "secret" } });
console.log(contextOutcome.stdout); // => secretA Context can own the flags needed by its setup. .provide() installs that Context on the current command and commands added later; see Contexts.
Runtime exports
The API overview lists every runtime export of the package root.
Types
The root barrel exports the command, Context, Extension, input, snapshot, and error types used by applications. See Types for their fields and constraints.
| Type | Reference |
|---|---|
ArgDef / FlagDef | ArgDef and FlagDef |
ContextBag / ContextBuilder / ContextFactory / ContextSetup | Context types |
Extension / ExtensionBuilder / ExtensionFactory | Extension types |
CommandSnapshot / ArgSnapshot / FlagSnapshot | Command Snapshots |
BuildFile / BuildArtifacts (Extension build hooks) | BuildFile and BuildArtifacts |
BuildReport | BuildReport |
RootMetaKey | RootMetaKey |
MergeFlags | MergeFlags |
MergeContext | MergeContext |
InvocationOptions / ExecuteOptions | Invocation I/O |
The root barrel is the full supported export list.
Typed invocation
const outcome = await app.run(["wave"]);
if (outcome.status === "completed") console.log(outcome.stdout); // => o/run() returns a captured outcome after cleanup. See run() input and I/O for typed paths, structured input, validation, output capture, and failure behavior.
Tooling subpath
import { defineExtensionId } from "@crustjs/core";
import { buildCommandDocumentation, visibleSectionsFor } from "@crustjs/core/tooling";
const snapshot = await app.snapshot();
const documentation = buildCommandDocumentation(snapshot);
const visible = visibleSectionsFor(snapshot, defineExtensionId("acme:web-docs"));| Export | Role |
|---|---|
BUILD_OUT_DIR_ENV / SNAPSHOT_PATH_ENV | Environment variable names for the first-party subprocess protocol |
buildCommandDocumentation() | Builds a renderer-ready documentation tree from a Command Snapshot |
formatDefault() / formatDescription() | Formats input defaults and descriptions |
isListed() / sectionsFor() / visibleSectionsFor() | Filters commands and sections for an Extension identity |
isInstalledCommandName() / INSTALLED_COMMAND_NAME_RULE | Checks and describes the installed command name rule |
CommandDocumentation / DocumentationArg / DocumentationFlag / UsageSegment | Documentation model types |
CommandSnapshot | Same type as the root export, for tooling-only imports |
parseFlagValues() / FlagEnvironment | Resolves flags from their env bindings without argv |
@crustjs/core/tooling contains build- and render-time helpers for Command Snapshots, documentation trees, section filtering, and formatting. They move in lockstep with first-party tooling. Application authoring and invocation APIs stay at the package root. SNAPSHOT_PATH_ENV and BUILD_OUT_DIR_ENV name the variables crust build sets when it runs a source entry to prepare its snapshot; do not set them in your CLI.
An installed command name uses letters, digits, ., _, and -, and starts with a letter or digit. crust build applies this rule to bin keys, create-crust to project names, and completion() to the root command name, which crust build requires to match the installed command.
parseFlagValues(flags, env) reuses terminal flag conversion without argv: environment splitting, choices, parsers or built-in coercion, defaults, requiredness, and Standard Schemas. Invalid definitions reject with DEFINITION; value failures reject with PARSE or VALIDATION and may quote raw input. @crustjs/env aggregates and redacts those failures for environment validation.