Skip to content
zodline
Esc
navigateopen⌘Jpreview
On this page

API

Every export of zodline — defineOptions, defineCommand, defineConfig, processConfig, ZodlineError and the types.

Everything is exported from the package root.

import {
  defineCommand,
  defineConfig,
  defineOptions,
  processConfig,
  ZodlineError,
} from 'zodline';

import type {
  CommandDefinition,
  DefineConfig,
  OptionsDefinition,
  ProcessResult,
} from 'zodline';

defineOptions

function defineOptions<T extends z.ZodObject>(
  schema: T,
  aliases?: Record<string, string>,
): OptionsDefinition<T>;

Pairs an options schema with an alias map. Returns { schema, aliases } unchanged — the function exists to capture T so the schema type flows into defineCommand.

PropType
schemaz.ZodObject

One key per option, in camelCase.

Typez.ZodObject
aliases?Record<string, string>

Maps a short flag to a schema key, e.g. { n: "name" }.

TypeRecord<string, string>
const options = defineOptions(
  z.object({
    name: z.string().describe('Name to greet'),
    loud: z.boolean().default(false).describe('Use uppercase'),
  }),
  { n: 'name', l: 'loud' },
);

defineCommand

function defineCommand<TOptions, TArgs>(config: {
  description?: string;
  examples?: string[];
  options?: TOptions;
  args?: TArgs;
  action: (options, args) => void | Promise<void>;
}): CommandDefinition<…>;

Describes one command. Returns its input; the generics make options and args inside action inferred rather than any.

PropType
description?string

Shown in the help screens.

Typestring
examples?string[]

Example invocations, printed verbatim in the per-command help.

Typestring[]
options?OptionsDefinition

The result of defineOptions().

TypeOptionsDefinition
args?z.ZodType

Schema applied to the positional argument array.

Typez.ZodType
action(options, args) => void | Promise<void>

Never invoked by processConfig — you call it.

Type(options, args) => void | Promise<void>

defineConfig

function defineConfig<TCommands>(config: DefineConfig<TCommands>): DefineConfig<TCommands>;

Collects commands and CLI metadata.

PropType
meta?{ name?: string; version?: string; description?: string }

Identity used by the help screens and --version.

Type{ name?: string; version?: string; description?: string }
commandsRecord<string, CommandDefinition>

Keys are the names users type.

TypeRecord<string, CommandDefinition>
defaultCommand?CommandDefinition

Runs when no command name is given. Never receives positional arguments.

TypeCommandDefinition

processConfig

function processConfig<TCommands>(
  config: DefineConfig<TCommands>,
  args: string[],
): ProcessResult;

Parses and validates args, then returns the matched command with its typed options and args. Does not call the action.

Pass process.argv.slice(2) — the array must not include the node binary or the script path.

const result = processConfig(config, process.argv.slice(2));
await result.command.action(result.options, result.args);

Control flow

Parse flags

argv is split into flags and positional arguments.

Resolve the command

The longest run of leading positional arguments that matches a command name wins, so config set is matched by my-cli config set. With no positional arguments, --version and --help are handled (both exit 0), then defaultCommand, then a ZodlineError.

Per-command help

--help after a command name prints its options and exits 0.

Validate

Options run through the options pipeline; positional arguments run through the args schema.

Throws

Condition Error
No command and no defaultCommand ZodlineError: No command specified.
Unknown command ZodlineError: Unknown command: <name>
Unknown option ZodlineError: Unknown option: --<name>
Options schema failure ZodError
Args schema failure Error: Argument validation failed: …

ZodlineError

class ZodlineError extends Error {
  name: 'ZodlineError';
}

Thrown for parse-level problems: no command, unknown command, unknown option. Schema failures are Zod’s errors, not this one.

if (error instanceof ZodlineError) {
  console.error(error.message);
  process.exit(2);
}

Types

OptionsDefinition

interface OptionsDefinition<T extends z.ZodObject = z.ZodObject> {
  schema: T;
  aliases?: Record<string, string> | undefined;
}

CommandDefinition

interface CommandDefinition<TOptions extends z.ZodObject, TArgs extends z.ZodType | undefined> {
  description?: string;
  examples?: string[];
  options?: OptionsDefinition<TOptions>;
  args?: TArgs;
  action: (
    options: TOptions extends z.ZodObject ? z.infer<TOptions> : {},
    args: TArgs extends z.ZodType ? z.infer<TArgs> : undefined,
  ) => void | Promise<void>;
}

DefineConfig

interface DefineConfig<TCommands extends Record<string, CommandDefinition>> {
  meta?: {
    name?: string;
    version?: string;
    description?: string;
  };
  commands: TCommands;
  defaultCommand?: CommandDefinition;
}

ProcessResult

interface ProcessResult<TCommand extends CommandDefinition> {
  command: TCommand;
  options: z.infer<TCommand['options']['schema']>;
  args: z.infer<TCommand['args']>;
}

options resolves to {} for a command without options; args resolves to undefined for a command without an args schema.

Last updated on September 20, 2026

Was this page helpful?