Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Argument unstable

Defines typed positional arguments for Effect CLI applications.

Arguments consume ordered values after a command name and its flags, then parse them into the types a command handler expects. This module includes constructors for common argument shapes, plus helpers for optional or variadic arguments, schema validation, transformations, defaults, config fallbacks, and prompts for missing values.

33 exports Since v4.0.0 Source

Combinators

atLeast

unstable
Since v4.0.0

Creates a variadic argument that requires at least n values.

Signature

declare const atLeast: {
<A>(min: number): (self: Argument<A>) => Argument<readonly Array<A>>;
<A>(self: Argument<A>, min: number): Argument<readonly Array<A>>;
}

Example Requiring a minimum number of values

import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.atLeast(1))
files.kind // => "argument"

atMost

unstable
Since v4.0.0

Creates a variadic argument that accepts at most n values.

Signature

declare const atMost: {
<A>(max: number): (self: Argument<A>) => Argument<readonly Array<A>>;
<A>(self: Argument<A>, max: number): Argument<readonly Array<A>>;
}

Example Limiting the maximum number of values

import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.atMost(5))
files.kind // => "argument"

between

unstable
Since v4.0.0

Creates a variadic argument that accepts between min and max values.

Signature

declare const between: {
<A>(min: number, max: number): (self: Argument<A>) => Argument<readonly Array<A>>;
<A>(self: Argument<A>, min: number, max: number): Argument<readonly Array<A>>;
}

Example Requiring a range of values

import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.between(1, 5))
files.kind // => "argument"

filter

unstable
Since v4.0.0

Filters parsed values, failing with a custom error message if the predicate returns false.

Signature

declare const filter: {
<A>(predicate: (a: A) => boolean, onFalse: (a: A) => string): (self: Argument<A>) => Argument<A>;
<A>(self: Argument<A>, predicate: (a: A) => boolean, onFalse: (a: A) => string): Argument<A>;
}

Example Filtering parsed values

import { Argument } from "effect/cli"
const positiveInt = Argument.Int("count").pipe(
Argument.filter(
(n) => n > 0,
(n) => `Expected positive integer, got ${n}`
)
)
positiveInt.kind // => "argument"

filterMap

unstable
Since v4.0.0

Filters and transforms parsed values, failing with a custom error message if the filter function returns None.

Signature

declare const filterMap: {
<A, B>(f: (a: A) => Option<B>, onNone: (a: A) => string): (self: Argument<A>) => Argument<B>;
<A, B>(self: Argument<A>, f: (a: A) => Option<B>, onNone: (a: A) => string): Argument<B>;
}

Example Filtering and mapping parsed values

import { Option } from "effect"
import { Argument } from "effect/cli"
const positiveInt = Argument.Int("count").pipe(
Argument.filterMap(
(n) => n > 0 ? Option.some(n) : Option.none(),
(n) => `Expected positive integer, got ${n}`
)
)
positiveInt.kind // => "argument"

map

unstable
Since v4.0.0

Transforms the parsed value of a positional argument.

Signature

declare const map: {
<A, B>(f: (a: A) => B): (self: Argument<A>) => Argument<B>;
<A, B>(self: Argument<A>, f: (a: A) => B): Argument<B>;
}

Example Mapping parsed values

import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe(
Argument.map((p) => ({ port: p, url: `http://localhost:${p}` }))
)
port.kind // => "argument"

mapEffect

unstable
Since v4.0.0

Transforms the parsed value of a positional argument using an effectful function.

Signature

declare const mapEffect: {
<A, B>(f: (a: A) => Effect<B, CliError, Environment>): (self: Argument<A>) => Argument<B>;
<A, B>(self: Argument<A>, f: (a: A) => Effect<B, CliError, Environment>): Argument<B>;
}

Example Validating values effectfully

import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"
import { Argument, CliError } from "effect/cli"
import { ChildProcessSpawner } from "effect/process"
const CliTestLayer = Layer.mergeAll(
FileSystem.layerNoop({}),
Path.layer,
Stdio.layerTest({}),
Layer.succeed(Terminal.Terminal, Terminal.make({
columns: Effect.succeed(80),
rows: Effect.succeed(24),
readInput: Effect.die("unused"),
readLine: Effect.die("unused"),
display: () => Effect.void
})),
Layer.succeed(
ChildProcessSpawner.ChildProcessSpawner,
ChildProcessSpawner.make(() => Effect.die("unused"))
)
)
const files = Argument.String("files").pipe(
Argument.mapEffect((file) =>
file.endsWith(".txt")
? Effect.succeed(file)
: Effect.fail(
new CliError.UserError({
cause: new Error(`Unsupported file extension: ${file}`),
userMessage: "Only .txt files allowed"
})
)
)
)
const [, value] = await Effect.runPromise(
files.parse({ arguments: ["notes.txt"], flags: {} }).pipe(Effect.provide(CliTestLayer))
)
value // => "notes.txt"

mapTryCatch

unstable
Since v4.0.0

Transforms the parsed value of a positional argument using a function that may throw.

Signature

declare const mapTryCatch: {
<A, B>(f: (a: A) => B, onError: (error: unknown) => string): (self: Argument<A>) => Argument<B>;
<A, B>(self: Argument<A>, f: (a: A) => B, onError: (error: unknown) => string): Argument<B>;
}

Example Mapping values that may throw

import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"
import { Argument } from "effect/cli"
import { ChildProcessSpawner } from "effect/process"
const CliTestLayer = Layer.mergeAll(
FileSystem.layerNoop({}),
Path.layer,
Stdio.layerTest({}),
Layer.succeed(Terminal.Terminal, Terminal.make({
columns: Effect.succeed(80),
rows: Effect.succeed(24),
readInput: Effect.die("unused"),
readLine: Effect.die("unused"),
display: () => Effect.void
})),
Layer.succeed(
ChildProcessSpawner.ChildProcessSpawner,
ChildProcessSpawner.make(() => Effect.die("unused"))
)
)
const json = Argument.String("data").pipe(
Argument.mapTryCatch(
(str) => JSON.parse(str),
(error) =>
`Invalid JSON: ${error instanceof Error ? error.message : String(error)}`
)
)
const [, value] = await Effect.runPromise(
json.parse({ arguments: ['{"enabled":true}'], flags: {} }).pipe(Effect.provide(CliTestLayer))
)
value // => { enabled: true }

optional

unstable
Since v4.0.0

Makes a positional argument optional.

Signature

declare function optional<A>(arg: Argument<A>): Argument<Option<A>>

Example Making an argument optional

import { Argument } from "effect/cli"
const optionalVersion = Argument.String("version").pipe(Argument.optional)
optionalVersion.kind // => "argument"

orElse

unstable
Since v4.0.0

Provides a fallback argument to use if this argument fails to parse.

Signature

declare const orElse: {
<B>(that: LazyArg<Argument<B>>): <A>(self: Argument<A>) => Argument<B | A>;
<A, B>(self: Argument<A>, that: LazyArg<Argument<B>>): Argument<A | B>;
}

Example Providing a fallback argument

import { Argument } from "effect/cli"
const value = Argument.Int("value").pipe(
Argument.orElse(() => Argument.String("value"))
)
value.kind // => "argument"
Since v4.0.0

Provides a fallback argument, wrapping results in Result to distinguish which succeeded.

Signature

declare const orElseResult: {
<B>(that: LazyArg<Argument<B>>): <A>(self: Argument<A>) => Argument<Result<A, B>>;
<A, B>(self: Argument<A>, that: LazyArg<Argument<B>>): Argument<Result<A, B>>;
}

Example Returning which fallback succeeded

import { Argument } from "effect/cli"
const source = Argument.File("source").pipe(
Argument.orElseResult(() => Argument.String("url"))
)
// Returns Result<string, string>
source.kind // => "argument"

variadic

unstable
Since v4.0.0

Creates a variadic positional argument that accepts multiple values.

Signature

declare const variadic: {
(options?: VariadicParamOptions): <A>(self: Argument<A>) => Argument<readonly Array<A>>;
<A>(self: Argument<A>, options?: VariadicParamOptions): Argument<readonly Array<A>>;
}

Example Accepting multiple values

import { Argument } from "effect/cli"
// Accept any number of files
const anyFiles = Argument.String("files").pipe(Argument.variadic)
// Accept at least 1 file
const atLeastOneFile = Argument.String("files").pipe(
Argument.variadic({ min: 1 })
)
// Accept between 1 and 5 files
const limitedFiles = Argument.String("files").pipe(
Argument.variadic({ min: 1, max: 5 })
)
const kinds = [anyFiles.kind, atLeastOneFile.kind, limitedFiles.kind] // => ["argument", "argument", "argument"]

withDefault

unstable
Since v4.0.0

Provides a default value for a positional argument.

Signature

declare const withDefault: {
<B>(defaultValue: B | Effect<B, CliError, Environment>): <A>(self: Argument<A>) => Argument<B | A>;
<A, B>(self: Argument<A>, defaultValue: B | Effect<B, CliError, Environment>): Argument<A | B>;
}

Example Providing a default value

import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe(Argument.withDefault(8080))
port.kind // => "argument"
Since v4.0.0

Adds a description to a positional argument.

Signature

declare const withDescription: {
<A>(description: string): (self: Argument<A>) => Argument<A>;
<A>(self: Argument<A>, description: string): Argument<A>;
}

Example Adding an argument description

import { Argument } from "effect/cli"
const filename = Argument.String("filename").pipe(
Argument.withDescription("The input file to process")
)
filename.kind // => "argument"
Since v4.0.0

Adds a fallback config that is loaded when a required argument is missing.

Signature

declare const withFallbackConfig: {
<B>(config: Config<B>): <A>(self: Argument<A>) => Argument<B | A>;
<A, B>(self: Argument<A>, config: Config<B>): Argument<A | B>;
}

Example Loading a fallback config

import { Config } from "effect"
import { Argument } from "effect/cli"
const repository = Argument.String("repository").pipe(
Argument.withFallbackConfig(Config.String("REPOSITORY"))
)
repository.kind // => "argument"
Since v4.0.0

Adds a fallback prompt that is shown when a required argument is missing.

Signature

declare const withFallbackPrompt: {
<B>(prompt: FallbackPrompt<B>): <A>(self: Argument<A>) => Argument<B | A>;
<A, B>(self: Argument<A>, prompt: FallbackPrompt<B>): Argument<A | B>;
}

Example Showing a fallback prompt

import { Argument, Prompt } from "effect/cli"
const filename = Argument.String("filename").pipe(
Argument.withFallbackPrompt(Prompt.String({ message: "Filename" }))
)
filename.kind // => "argument"

withSchema

unstable
Since v4.0.0

Validates parsed values against a Schema.

Signature

declare const withSchema: {
<A, B>(schema: ConstraintCodec<B, A, Environment, unknown>): (self: Argument<A>) => Argument<B>;
<A, B>(self: Argument<A>, schema: ConstraintCodec<B, A, Environment, unknown>): Argument<B>;
}

Example Validating parsed values with a schema

import { Schema } from "effect"
import { Argument } from "effect/cli"
const input = Argument.String("input").pipe(
Argument.withSchema(Schema.NonEmptyString)
)
input.kind // => "argument"

Constructors

Since v4.0.0

Creates a positional choice argument with custom value mapping.

Signature

declare function ChoiceWithValue<Choices extends readonly Array<readonly [string, any]>>(name: string, choices: Choices): Argument<Choices[number][1]>

Example Mapping choices to values

import { Argument } from "effect/cli"
const logLevel = Argument.ChoiceWithValue("level", [
["debug", 0],
["info", 1],
["warn", 2],
["error", 3]
])
logLevel.kind // => "argument"

Date

unstable
Since v4.0.0

Creates a positional date argument.

Signature

declare function Date(name: string): Argument<Date>

Example Creating a date argument

import { Argument } from "effect/cli"
const startDate = Argument.Date("start-date")
startDate.kind // => "argument"

Directory

unstable
Since v4.0.0

Creates a positional directory path argument.

Signature

declare function Directory(name: string, options?: {
readonly mustExist?: boolean;
}): Argument<string>

Example Creating a directory path argument

import { Argument } from "effect/cli"
const workspace = Argument.Directory("workspace", { mustExist: true }) // Must exist
workspace.kind // => "argument"

File

unstable
Since v4.0.0

Creates a positional file path argument.

Signature

declare function File(name: string, options?: {
readonly mustExist?: boolean;
}): Argument<string>

Example Creating file path arguments

import { Argument } from "effect/cli"
const inputFile = Argument.File("input", { mustExist: true }) // Must exist
const outputFile = Argument.File("output", { mustExist: false }) // Must not exist
const kinds = [inputFile.kind, outputFile.kind] // => ["argument", "argument"]

FileParse

unstable
Since v4.0.0

Creates a positional argument that reads a file and parses its content.

Details

The parser is chosen from the explicit format option or, when omitted, the file extension. The parsed value is unknown; use fileSchema when the parsed content should also be decoded with a Schema.

Signature

declare function FileParse(name: string, options?: FileParseOptions): Argument<unknown>

Example Parsing file content

import { Argument } from "effect/cli"
const config = Argument.FileParse("config", { format: "json" })
config.kind // => "argument"

FileSchema

unstable
Since v4.0.0

Creates a positional argument that reads and validates file content using a schema.

Signature

declare function FileSchema<A>(name: string, schema: ConstraintDecoder<A, Environment>, options?: {
readonly errorFormatter?: Formatter<string>;
readonly format?: "json" | "ini" | "toml" | "yaml";
}): Argument<A>

Example Validating file content with a schema

import { Schema } from "effect"
import { Argument } from "effect/cli"
const ConfigSchema = Schema.Struct({
port: Schema.Number,
host: Schema.String
})
const config = Argument.FileSchema("config", ConfigSchema)
config.kind // => "argument"

FileText

unstable
Since v4.0.0

Creates a positional argument that reads file content as a string.

Signature

declare function FileText(name: string): Argument<string>

Example Reading file text

import { Argument } from "effect/cli"
const config = Argument.FileText("config-file")
config.kind // => "argument"

Finite

unstable
Since v4.0.0

Creates a positional argument that parses finite numbers.

Signature

declare function Finite(name: string): Argument<number>

Example Parsing a finite number

import { Argument } from "effect/cli"
const ratio = Argument.Finite("ratio")
ratio.kind // => "argument"

Int

unstable
Since v4.0.0

Creates a positional integer argument.

Signature

declare function Int(name: string): Argument<number>

Example Creating an integer argument

import { Argument } from "effect/cli"
const count = Argument.Int("count")
count.kind // => "argument"

Literals

unstable
Since v4.0.0

Creates a positional choice argument.

Signature

declare function Literals<Choices extends readonly Array<string>>(name: string, choices: Choices): Argument<Choices[number]>

Example Creating a choice argument

import { Argument } from "effect/cli"
const environment = Argument.Literals("environment", ["dev", "staging", "prod"])
environment.kind // => "argument"

Never

unstable
Since v4.0.0

An argument that always fails to parse.

Signature

declare const Never: Argument<never>

Example Creating a sentinel argument

import { Argument } from "effect/cli"
const noArg = Argument.Never
noArg.kind // => "argument"

Path

unstable
Since v4.0.0

Creates a positional path argument.

Signature

declare function Path(name: string, options?: {
mustExist?: boolean;
pathType?: "either" | "file" | "directory";
}): Argument<string>

Example Creating a path argument

import { Argument } from "effect/cli"
const configPath = Argument.Path("config")
configPath.kind // => "argument"

Redacted

unstable
Since v4.0.0

Creates a positional redacted argument that obscures its value.

Signature

declare function Redacted(name: string): Argument<Redacted<string>>

Example Creating a redacted argument

import { Argument } from "effect/cli"
const secret = Argument.Redacted("secret")
secret.kind // => "argument"

String

unstable
Since v4.0.0

Creates a positional string argument.

Signature

declare function String(name: string): Argument<string>

Example Creating a string argument

import { Argument } from "effect/cli"
const filename = Argument.String("filename")
filename.kind // => "argument"

Metadata

withMetavar

unstable
Since v4.0.0

Sets a custom metavar (placeholder name) for the argument in help documentation.

Details

The metavar is displayed in usage text to indicate what value the user should provide. For example, <FILE> shows FILE as the metavar.

Signature

declare const withMetavar: {
<A>(metavar: string): (self: Argument<A>) => Argument<A>;
<A>(self: Argument<A>, metavar: string): Argument<A>;
}

Example Setting a metavar

import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe(
Argument.withMetavar("PORT")
)
port.kind // => "argument"

Models

Argument

interface unstable
Since v4.0.0

Represents a positional command-line argument.

Gotchas

For booleans, use Flag.Boolean or Argument.Literals with "true" and "false".

Signature

interface Argument<A> extends Param<typeof Param.argumentKind, A> {}