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;
  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
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 first positional argument names the command. With none, --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;
  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 August 6, 2026

Was this page helpful?