Skip to content
Effect Days 2026 Get your ticket

Argument

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 Added in v4.0.0 Source

Combinators

atLeast

Added in v4.0.0 Source

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/unstable/cli"
const files = Argument.string("files").pipe(Argument.atLeast(1))
files.kind // => "argument"

atMost

Added in v4.0.0 Source

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/unstable/cli"
const files = Argument.string("files").pipe(Argument.atMost(5))
files.kind // => "argument"

between

Added in v4.0.0 Source

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/unstable/cli"
const files = Argument.string("files").pipe(Argument.between(1, 5))
files.kind // => "argument"

filter

Added in v4.0.0 Source

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/unstable/cli"
const positiveInt = Argument.integer("count").pipe(
Argument.filter(
(n) => n > 0,
(n) => `Expected positive integer, got ${n}`
)
)
positiveInt.kind // => "argument"

filterMap

Added in v4.0.0 Source

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/unstable/cli"
const positiveInt = Argument.integer("count").pipe(
Argument.filterMap(
(n) => n > 0 ? Option.some(n) : Option.none(),
(n) => `Expected positive integer, got ${n}`
)
)
positiveInt.kind // => "argument"

map

Added in v4.0.0 Source

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/unstable/cli"
const port = Argument.integer("port").pipe(
Argument.map((p) => ({ port: p, url: `http://localhost:${p}` }))
)
port.kind // => "argument"

mapEffect

Added in v4.0.0 Source

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/unstable/cli"
import { ChildProcessSpawner } from "effect/unstable/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

Added in v4.0.0 Source

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/unstable/cli"
import { ChildProcessSpawner } from "effect/unstable/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

Added in v4.0.0 Source

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/unstable/cli"
const optionalVersion = Argument.string("version").pipe(Argument.optional)
optionalVersion.kind // => "argument"

orElse

Added in v4.0.0 Source

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/unstable/cli"
const value = Argument.integer("value").pipe(
Argument.orElse(() => Argument.string("value"))
)
value.kind // => "argument"

orElseResult

Added in v4.0.0 Source

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/unstable/cli"
const source = Argument.file("source").pipe(
Argument.orElseResult(() => Argument.string("url"))
)
// Returns Result<string, string>
source.kind // => "argument"

variadic

Added in v4.0.0 Source

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/unstable/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

Added in v4.0.0 Source

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/unstable/cli"
const port = Argument.integer("port").pipe(Argument.withDefault(8080))
port.kind // => "argument"

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/unstable/cli"
const filename = Argument.string("filename").pipe(
Argument.withDescription("The input file to process")
)
filename.kind // => "argument"

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/unstable/cli"
const repository = Argument.string("repository").pipe(
Argument.withFallbackConfig(Config.string("REPOSITORY"))
)
repository.kind // => "argument"

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/unstable/cli"
const filename = Argument.string("filename").pipe(
Argument.withFallbackPrompt(Prompt.text({ message: "Filename" }))
)
filename.kind // => "argument"

withSchema

Added in v4.0.0 Source

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/unstable/cli"
const input = Argument.string("input").pipe(
Argument.withSchema(Schema.NonEmptyString)
)
input.kind // => "argument"

Constructors

choice

Added in v4.0.0 Source

Creates a positional choice argument.

Signature

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

Example

(Creating a choice argument)

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

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/unstable/cli"
const logLevel = Argument.choiceWithValue("level", [
["debug", 0],
["info", 1],
["warn", 2],
["error", 3]
])
logLevel.kind // => "argument"

date

Added in v4.0.0 Source

Creates a positional date argument.

Signature

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

Example

(Creating a date argument)

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

directory

Added in v4.0.0 Source

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/unstable/cli"
const workspace = Argument.directory("workspace", { mustExist: true }) // Must exist
workspace.kind // => "argument"

file

Added in v4.0.0 Source

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/unstable/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

Added in v4.0.0 Source

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/unstable/cli"
const config = Argument.fileParse("config", { format: "json" })
config.kind // => "argument"

fileSchema

Added in v4.0.0 Source

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/unstable/cli"
const ConfigSchema = Schema.Struct({
port: Schema.Number,
host: Schema.String
})
const config = Argument.fileSchema("config", ConfigSchema)
config.kind // => "argument"

fileText

Added in v4.0.0 Source

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/unstable/cli"
const config = Argument.fileText("config-file")
config.kind // => "argument"

float

Added in v4.0.0 Source

Creates a positional float argument.

Signature

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

Example

(Creating a float argument)

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

integer

Added in v4.0.0 Source

Creates a positional integer argument.

Signature

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

Example

(Creating an integer argument)

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

none

Added in v4.0.0 Source

Creates an empty sentinel argument that always fails to parse.

Signature

declare const none: Argument<never>

Example

(Creating a sentinel argument)

import { Argument } from "effect/unstable/cli"
// Used as a placeholder or default in combinators
const noArg = Argument.none
noArg.kind // => "argument"

path

Added in v4.0.0 Source

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/unstable/cli"
const configPath = Argument.path("config")
configPath.kind // => "argument"

redacted

Added in v4.0.0 Source

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/unstable/cli"
const secret = Argument.redacted("secret")
secret.kind // => "argument"

string

Added in v4.0.0 Source

Creates a positional string argument.

Signature

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

Example

(Creating a string argument)

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

Metadata

withMetavar

Added in v4.0.0 Source

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/unstable/cli"
const port = Argument.integer("port").pipe(
Argument.withMetavar("PORT")
)
port.kind // => "argument"

Models

Argument interface

Added in v4.0.0 Source

Represents a positional command-line argument.

Gotchas

boolean is intentionally omitted from Argument constructors. Positional boolean arguments are ambiguous in CLI design since there is no flag name to negate (for example, --no-verbose). Use Flag.boolean instead, or use Argument.choice with explicit "true" / "false" strings if needed.

Signature

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