npm install @cli-forge/parserA type-safe argument parser for Node.js with full TypeScript inference.
This is the low-level parsing engine that powers cli-forge. Use this package directly if you need fine-grained control over argument parsing without the higher-level command management features.
Installation
npm install @cli-forge/parser
Quick Start
import { parser } from '@cli-forge/parser';
const args = parser()
.option('name', { type: 'string', required: true })
.option('port', { type: 'number', default: 3000 })
.option('verbose', { type: 'boolean', alias: ['v'] })
.parse(['--name', 'my-app', '--port', '8080', '-v']);
// args is fully typed:
// { name: string; port: number; verbose: boolean }
console.log(args.name); // 'my-app'
console.log(args.port); // 8080
console.log(args.verbose); // true
Features
- Full TypeScript inference - Types accumulate as you chain
.option()calls - Multiple option types -
string,number,boolean,array,object - Value sources - CLI args, environment variables, config files, defaults
- Validation -
choices,validate,required,conflicts,implies - Config file support - JSON/YAML with inheritance via
extends - Coercion - Transform values during parsing
Option Types
String
parser().option('name', {
type: 'string',
description: 'User name',
default: 'anonymous',
});
Number
parser().option('port', {
type: 'number',
description: 'Port number',
default: 3000,
});
Boolean
parser().option('verbose', {
type: 'boolean',
alias: ['v'],
description: 'Enable verbose output',
});
// Supports: --verbose, --verbose true, --no-verbose
Array
parser().option('files', {
type: 'array',
items: 'string',
description: 'Input files',
});
// Supports: --files a b c, --files a,b,c, --files a --files b
Object
parser().option('config', {
type: 'object',
properties: {
host: { type: 'string', default: 'localhost' },
port: { type: 'number', required: true },
ssl: { type: 'boolean' },
},
});
// Supports: --config.host example.com --config.port 443 --config.ssl
Positional Arguments
parser()
.positional('input', { type: 'string', required: true })
.positional('output', { type: 'string' })
.parse(['input.txt', 'output.txt']);
Validation
Choices
parser().option('level', {
type: 'string',
choices: ['debug', 'info', 'warn', 'error'],
});
Custom Validation
parser().option('port', {
type: 'number',
validate: (value) => {
if (value < 1 || value > 65535) {
throw new Error('Port must be between 1 and 65535');
}
return true;
},
});
Conflicts and Implies
parser()
.option('quiet', { type: 'boolean' })
.option('verbose', {
type: 'boolean',
conflicts: ['quiet'],
})
.option('output', {
type: 'string',
implies: { format: 'json' },
});
Environment Variables
parser().option('apiKey', {
type: 'string',
env: 'API_KEY',
});
// Will read from process.env.API_KEY if --apiKey not provided
Configuration Files
parser()
.configFile('myapp.config.json')
.option('port', { type: 'number' })
.parse([]);
Config files support inheritance:
{
"extends": "./base-config.json",
"port": 8080
}
Coercion
Transform values during parsing:
parser().option('date', {
type: 'string',
coerce: (value) => new Date(value),
});
Type Inference
The parser tracks types as options are added:
const p = parser()
.option('name', { type: 'string' }) // { name?: string }
.option('port', { type: 'number' }) // { name?: string; port?: number }
.option('required', { type: 'string', required: true }); // { name?: string; port?: number; required: string }
Related Packages
cli-forge- High-level CLI builder with commands, middleware, and documentation generation
Documentation
Full documentation available at: https://craigory.dev/cli-forge/
License
ISC
API EXPORTS
Functions
chainfunctionApplies a series of functions to an initial value, passing the result of each function to the next. Used to convert code that looks like: ```typescript const a = addB(addC({ a: 'a' })); ``` to: ```typescript const a = chain({ a: 'a' }, addB, addC); ``` See [composable-options](/examples/composable-options) for an example of how this can be used.
detectLocalefunctionDetects the current locale from the system. Uses Intl.DateTimeFormat to determine the user's locale.
fromCamelCaseToDashedfunctionfromCamelOrDashedCaseToConstCasefunctionfromDashedToCamelCasefunctiongetBinfunctiongetEnvironmentProviderfunctionReturn the current global EnvironmentProvider.
getEnvKeyfunctiongetFileSystemProviderfunctionReturn the current global FileSystemProvider.
hideBinfunctionisArrayOptionConfigfunctionisBooleanOptionConfigfunctionisNumberOptionConfigfunctionisObjectOptionConfigfunctionisOneOfOptionConfigfunctionisStringOptionConfigfunctionmakeComposableOptionfunctionA composition helper to be used with chain.
parserfunctionSmall helper function to create a new parser instance.
readDefaultValuefunctionresolveLocalizedTextfunctionResolves a localized text value from a dictionary.
setEnvironmentProviderfunctionReplace the global EnvironmentProvider. Call before parsing to redirect all env-var reads/writes.
setFileSystemProviderfunctionReplace the global FileSystemProvider. Call before parsing to redirect all file-system operations.
supportsNegationfunctionCheck if a config supports boolean-like negation (--no-flag). True for boolean options and oneOf options containing a boolean valueType.
tryParseValuefunctionClasses
ArgvParserclassThe main parser class. This class is used to configure and parse arguments. parser is a small helper function to create a new parser instance.
MemoryEnvironmentProviderclassAn in-memory environment provider for testing, browser playgrounds, or any context where real process state should not be touched.
MemoryFileSystemProviderclassAn in-memory file-system provider backed by a `Record<string, string>`. Files are keyed by their full path; directories are inferred.
NodeEnvironmentProviderclassDefault provider that delegates to Node's `process` global.
NodeFileSystemProviderclassDefault file-system provider that delegates to Node's `fs` and `path`.
ValidationFailedErrorclassInterfaces
EnvironmentProviderinterfaceAbstracts access to environment variables and the working directory. The parser uses this interface for every `process.env` read/write and `process.cwd()` call, which means consumers can supply a custom implementation (e.g. an in-memory provider for browser playgrounds).
FileSystemProviderinterfaceAbstracts file-system and path operations so the parser and CLI layer can run in environments without Node's `fs` / `path` modules (e.g. browsers with an in-memory virtual FS).
ReadonlyArgvParserinterfaceTypes
AliasConfigtypeArrayOptionConfigtypeConfiguration for array options. Arrays are parsed from comma separated, space separated, or multiple values. e.g. `--foo a b c`, `--foo a,b,c`, or `--foo a --foo b --foo c`
BaseTypetypeMap an option config to its base TypeScript type. Uses structural typing to avoid circular imports.
BooleanOptionConfigtypeCommonOptionConfigtypeDefaulttypeDefaultValueWithDescriptiontypeDefaultValueWithFactorytypeEnvOptionConfigtypeDefines the option configuration passed to ArgvParser.env.
ExpandtypeForce TypeScript to fully expand a type. This helps with deferred type evaluation in recursive types.
ExpandDeeptypeDeeply expand a type, including nested objects.
InferChoicetypeInfer the choice type from an option config. Choices can be an array (including readonly) or a function returning an array.
InferCoercetypeInfer the coerced type. If coerce function exists, use its return type. Otherwise fall back to the provided fallback type. Uses optional property matching `coerce?:` to handle configs where coerce is defined as optional (like ObjectOptionConfig). Special handling: - [R] extends [never]: When coerce is missing/undefined, R infers as never - R extends undefined: When coerce explicitly returns undefined
InternaltypeInternalOptionConfigtypeLocalizationDictionarytypeLocalization dictionary type for translating option keys and other text. Each key maps to an object with a "default" value and optional locale-specific translations.
LocalizationFunctiontypeLocalization function type for custom translation logic. This allows integration with existing localization libraries like i18next.
MakeUndefinedPropertiesOptionaltypeMakes properties whose type includes `undefined` optional. This allows omitting properties like `{ foo?: string | undefined }` from object literals instead of requiring `{ foo: undefined }`. Uses `Pick` to avoid producing empty `{}` intersection members in TypeDoc output. When one side has no matching keys, `Pick<T, never>` collapses to `{}` inside a two-part `& {}` — the mapped type wrapper `{ [K in keyof ...]: ... }` forces TypeScript to flatten the intersection into a single object type, eliminating the empty half entirely and keeping tooltips clean.
NumberArrayOptionConfigtypeNumberOptionConfigtypeObjectOptionConfigtypeObjectValueTypetypeCompute the full value type for an object option.
OneOfArrayValueTypetypeOneOfBooleanValueTypetypeOneOfNumberValueTypetypeOneOfOptionConfigtypeConfiguration for a `oneOf` option that accepts multiple value types. Each entry in `valueTypes` defines a type the option can accept. At parse time, non-boolean parsers are tried in array order; boolean is always tried last (but has exclusive claim on bare flags, negation, and the literals `true`/`false`).
OneOfStringValueTypetypeOneOfValueTypeEntrytypeA single entry in the `valueTypes` array.
OptionConfigtypeConfigures an option for the parser. See subtypes for more information. - StringOptionConfig - NumberOptionConfig - ArrayOptionConfig - BooleanOptionConfig - OneOfOptionConfig
OptionConfigToTypetypeConverts an OptionConfig to the TypeScript type for the parsed value. Uses shared type resolution logic from type-resolution.ts.
ParsedArgstypeBase type for parsed arguments.
ParserOptionstypeExtra options for the parser
PlainDefaultValuetypeResolveOneOfEntrytypeResolve the TypeScript type for a single valueTypes entry. Forces distribution so each union member is resolved independently. Without this, InferChoice from one entry can swallow other entries.
ResolveOneOfValueTypestypeResolve the union type for the entire `valueTypes` tuple. Maps each entry to its resolved type and produces a union.
ResolveOptionTypetypeResolve a single option config to its final type. Priority: choices > coerce > base type For array options, choices narrow the element type rather than replacing the entire type. e.g. `{ type: 'array', items: 'string', choices: ['a', 'b'] as const }` resolves to `('a' | 'b')[]`, not `'a' | 'b'`.
ResolvePropertiestypeResolve all properties of an object option to their types. Each property becomes its resolved type, wrapped with optional handling. Special case: when TProperties is `any` (from `OptionConfig<any, any, any, any>`), we return `unknown` to avoid creating an index signature that would hide the actual properties inferred from the value.
StringArrayOptionConfigtypeStringOptionConfigtypeUnknownOptionConfigtypeAn OptionConfig with generic parameters set for maximum compatibility. Uses `any` for all type parameters to allow maximum assignability.
WithOptionaltypeWrap a resolved type with undefined if the option is optional. Required options or options with defaults are never undefined. Uses `'key' extends keyof TConfig` instead of `TConfig extends { key: unknown }` to properly detect OPTIONAL properties. The latter check fails for optional properties because `{ default?: X }` doesn't guarantee `default` exists.