Runtime Support
dreamcli runs on Node.js, Bun, and Deno without code changes. A thin RuntimeAdapter interface abstracts the platform-specific edges.
Supported Runtimes
| Runtime | Status | Package |
|---|---|---|
| Node.js >= 22.22.2 | Supported | @kjanat/dreamcli (npm) |
| Bun >= 1.3 | Supported | @kjanat/dreamcli (npm) |
| Deno >= 2.6.0 | Supported | @kjanat/dreamcli (JSR) |
These minimums are the tested support floor, declared in the package engines field. As a dependency, your package manager enforces them at install time; DreamCLI does not hard-fail the host CLI at runtime when the version is lower.
How It Works
The core framework never imports platform-specific APIs directly. Instead, a RuntimeAdapter provides:
argv— command-line argumentsenv— environment variablescwd— current working directorystdin— line reader for interactive promptsreadStdin— full piped stdin reader for.stdin()argumentsexit— process exitisTTY— terminal detectionstdinIsTTY— interactive stdin detectiongetTerminalSize— current stdout columns and rows when availableonTerminalResize— terminal resize subscription when supportedreadFile/stat/homedir/configDir— filesystem access
Runtime detection is automatic — dreamcli picks the right adapter at startup.
Terminal Width
When cli().run() renders help, DreamCLI uses the runtime adapter's terminal width if stdout is a TTY and no explicit help width is configured. Direct formatHelp() calls and cli().execute() keep the deterministic 80-column fallback.
Node and Bun use process.stdout.getWindowSize() when available, falling back to process.stdout.columns / rows. Deno uses Deno.consoleSize(). Resize subscriptions use stdout resize on Node/Bun and SIGWINCH on Deno Unix platforms.
Set a fixed width with .help({ width }) or runtime help: { width } when tests or generated output need stable wrapping.
Explicit Adapter
import {
createAdapter,
createNodeAdapter,
} from '@kjanat/dreamcli/runtime';
const adapter = createAdapter(); // auto-detect
const nodeAdapter = createNodeAdapter(); // explicitDeno Permissions
On Deno, the adapter handles permission-safe access to the Deno namespace. If permissions are missing, features degrade gracefully with clear error messages.
deno run --allow-read --allow-env mycli.ts deployTesting Runtime Seams
For command behavior tests, runCommand() is process-free and injects runtime state directly:
import { runCommand } from '@kjanat/dreamcli/testkit';
const result = await runCommand(regionCmd, [], {
env: { MY_REGION: 'test' },
});When you need adapter-level control (argv, filesystem reads, exit behavior), use createTestAdapter() with cli().run({ adapter }).
What's Next?
- Testing — in-process test harness
- Getting Started — installation per runtime