CLI entrypoints with clap + Effect

Rust’s standard answer for parsing is clap. For id_effect, treat the binary as a thin shell:

  1. Parse argv into a struct (#[derive(clap::Parser)]).
  2. Assemble layers / MapConfigProvider / other R values from flags and environment.
  3. Run your program Effect<A, E, R> with run_blocking (or an async driver when you integrate Tokio).
  4. Exit with [std::process::ExitCode] using id_effect_cli helpers (see the next sections).

This mirrors Effect.ts @effect/cli: declarative argument models composed into a single program — here the “program” is an Effect value rather than a Future chain.

Returning ExitCode keeps main testable and avoids calling std::process::exit deep inside library code:

use clap::Parser;
use id_effect_cli::{run_main, RunMainConfig};

#[derive(Parser)]
struct Cli {
    #[arg(long)]
    name: String,
}

fn main() -> std::process::ExitCode {
    let cli = Cli::parse();
    let eff = my_app(cli.name);
    run_main(eff, my_env(), RunMainConfig::with_tracing())
}

my_app returns an Effect<…>; my_env() is whatever R your effect needs (often a Context built from Layer stacks).

Workspace helpers

The id_effect_cli crate (same repository) provides:

Template

See the checked-in example examples/cli-minimal (--token …, Secret via id_effect_config).

Further reading