Overview
What crust is, why crust exists, and where to start.
What is Crust?
Crust is a TypeScript-first, Bun-native framework for building command-line applications. You declare commands with a chainable builder, and Crust provides end-to-end type safety through type inference. Everything beyond the core ships as composable modules, so you opt into first-class features and primitives only as you need them.
Why Crust?
Most CLI tools in the TypeScript ecosystem are either minimal arg parsers that leave you wiring everything together, or heavyweight frameworks that bring more complexity than you need.
Crust sits in the sweet spot: more structured than a bare parser, lighter than a full framework, and designed so you only pull in what you actually use.
Quick example
A greet command with a defaulted positional, a --shout/-s boolean flag, a wave subcommand, and --help wired by the help Extension:
import { Crust } from "@crustjs/core";
import { help } from "@crustjs/extensions";
const app = new Crust("greet")
.extend(help())
.args({ name: "name", type: "string", default: "world" })
.flags({ name: "shout", type: "boolean", short: "s" })
.action(({ args, flags, stdout }) => {
const line = `Hello, ${args.name}!`;
stdout(flags.shout ? line.toUpperCase() : line);
})
.command("wave", (command) => command.action(({ stdout }) => stdout("👋")));
await app.execute();
$ greet Ada --shout
HELLO, ADA!
$ greet --helpPhilosophy
- Zero-dependency core. The core has no runtime package dependencies.
- Declarative command trees. Define commands, arguments, flags, and subcommands together. Crust handles parsing and routing.
- Composable features. Add optional modules as you need them, including standalone libraries you can use without the framework.
- End-to-end type safety. Types flow from definitions to actions, Contexts, and programmatic invocation, with no manual annotations, decorators, or codegen.
- Compile-time validation first. Check statically known definitions through TypeScript, without repeating those checks at runtime. Reserve runtime validation for terminal input and definitions that cannot be checked statically.
- One source of truth. Reuse command definitions for parsing, inferred types, and generated help, completion scripts, manual pages, and agent documentation.
- Explicit extension points. Add application-wide behavior through Extensions with flags, commands, lifecycle hooks, and build hooks.
Feature highlights
- Commands and input parsing. Nested commands, arguments and flags with aliases, defaults, choices, Standard Schema validation, and inferred types.
- Extensions. Shared flags, commands, and lifecycle hooks, plus official extensions for help, version, typo suggestions, and update notices.
- Dependency injection. Typed Contexts with lazy initialization and automatic cleanup.
- Generated from your definitions. Shell completion for Bash, Zsh, and Fish, manual pages, and agent skills.
- Terminal UI. Styling, interactive prompts, and progress indicators, with non-interactive fallbacks. Full-screen apps through OpenTUI (Bun only).
- Testing helpers. Capture output and exit codes, or drive interactive commands with simulated input.
- Build and distribution. Standalone Bun or Deno executables, or a Node.js bundle.
Roadmap
Curious about what's coming next? Check out the Roadmap to see what we're working on, what's planned, and where you can contribute.
Community
Have questions or want to chat about Crust? Join our Discord community to connect with other developers, get help, and stay up to date.