GitPedia

Argh

Rust derive-based argument parsing optimized for code size

From google·Updated June 13, 2026·View on GitHub·

**Argh is an opinionated Derive-based argument parser optimized for code size** The project is written primarily in Rust, distributed under the BSD 3-Clause "New" or "Revised" License license, first published in 2020. It has gained significant community traction with 1,927 stars and 98 forks on GitHub. Key topics include: argh, argument-parser, arguments, positional-arguments, rust.

Latest release: 0.1.10Bump version to 0.1.10
January 11, 2023View Changelog →

Argh

Argh is an opinionated Derive-based argument parser optimized for code size

crates.io
license
docs.rs
Argh

Derive-based argument parsing optimized for code size and conformance
to the Fuchsia commandline tools specification

The public API of this library consists primarily of the FromArgs
derive and the from_env function, which can be used to produce
a top-level FromArgs type from the current program's commandline
arguments.

Basic Example

rust
use argh::FromArgs; #[derive(FromArgs)] /// Reach new heights. struct GoUp { /// whether or not to jump #[argh(switch, short = 'j')] jump: bool, /// how high to go #[argh(option)] height: usize, /// an optional nickname for the pilot #[argh(option)] pilot_nickname: Option<String>, } fn main() { let up: GoUp = argh::from_env(); }

./some_bin --help will then output the following:

Usage: cmdname [-j] --height <height> [--pilot-nickname <pilot-nickname>]

Reach new heights.

Options:
  -j, --jump        whether or not to jump
  --height          how high to go
  --pilot-nickname  an optional nickname for the pilot
  --help, help      display usage information

The resulting program can then be used in any of these ways:

  • ./some_bin --height 5
  • ./some_bin -j --height 5
  • ./some_bin --jump --height 5 --pilot-nickname Wes

Switches, like jump, are optional and will be set to true if provided.

Options, like height and pilot_nickname, can be either required,
optional, or repeating, depending on whether they are contained in an
Option or a Vec. Default values can be provided using the
#[argh(default = "<your_code_here>")] attribute, and in this case an
option is treated as optional.

rust
use argh::FromArgs; fn default_height() -> usize { 5 } #[derive(FromArgs)] /// Reach new heights. struct GoUp { /// an optional nickname for the pilot #[argh(option)] pilot_nickname: Option<String>, /// an optional height #[argh(option, default = "default_height()")] height: usize, /// an optional direction which is "up" by default #[argh(option, default = "String::from(\"only up\")")] direction: String, } fn main() { let up: GoUp = argh::from_env(); }

Custom option types can be deserialized so long as they implement the
FromArgValue trait (automatically implemented for all FromStr types).
If more customized parsing is required, you can supply a custom
fn(&str) -> Result<T, String> using the from_str_fn attribute:

rust
use argh::FromArgs; #[derive(FromArgs)] /// Goofy thing. struct FiveStruct { /// always five #[argh(option, from_str_fn(always_five))] five: usize, } fn always_five(_value: &str) -> Result<usize, String> { Ok(5) }

Positional arguments can be declared using #[argh(positional)].
These arguments will be parsed in order of their declaration in
the structure:

rust
use argh::FromArgs; #[derive(FromArgs, PartialEq, Debug)] /// A command with positional arguments. struct WithPositional { #[argh(positional)] first: String, }

The last positional argument may include a default, or be wrapped in
Option or Vec to indicate an optional or repeating positional argument.

Subcommands are also supported. To use a subcommand, declare a separate
FromArgs type for each subcommand as well as an enum that cases
over each command:

rust
use argh::FromArgs; #[derive(FromArgs, PartialEq, Debug)] /// Top-level command. struct TopLevel { #[argh(subcommand)] nested: MySubCommandEnum, } #[derive(FromArgs, PartialEq, Debug)] #[argh(subcommand)] enum MySubCommandEnum { One(SubCommandOne), Two(SubCommandTwo), } #[derive(FromArgs, PartialEq, Debug)] /// First subcommand. #[argh(subcommand, name = "one")] struct SubCommandOne { #[argh(option)] /// how many x x: usize, } #[derive(FromArgs, PartialEq, Debug)] /// Second subcommand. #[argh(subcommand, name = "two", short = 't')] struct SubCommandTwo { #[argh(switch)] /// whether to fooey fooey: bool, }

Advanced Description

You can define a complex help output that includes an Examples section.
Use a {command_name} placeholder.

rust
#[derive(FromArgs, Debug)] #[argh( description = "{command_name} is a tool to reach new heights.\n\n\ Start exploring new heights:\n\n\ \u{00A0} {command_name} --height 5 jump\n\ ", example = "\ {command_name} --height 5\n\ {command_name} --height 5 j\n\ {command_name} --height 5 --pilot-nickname Wes jump" )] pub struct CliArgs { /// how high to go #[argh(option)] height: usize, /// an optional nickname for the pilot #[argh(option)] pilot_nickname: Option<String>, /// command to execute #[argh(subcommand)] pub command: Command, }

Output:

Usage: goup --height <height> [--pilot-nickname <pilot-nickname>] <command> [<args>]

goup is a tool to reach new heights.

Start exploring new heights:

  goup --height 5 jump

Options:
  --height          how high to go
  --pilot-nickname  an optional nickname for the pilot
  --help, help      display usage information

Commands:
  jump  j           whether or not to jump

Examples:
  goup --height 5
  goup --height 5 j
  goup --height 5 --pilot-nickname Wes jump

How to debug the expanded derive macro for argh

The argh::FromArgs derive macro can be debugged with the cargo-expand crate.

Expand the derive macro in examples/simple_example.rs

See argh/examples/simple_example.rs for the example struct we wish to expand.

First, install cargo-expand by running cargo install cargo-expand. Note this requires the nightly build of Rust.

Once installed, run cargo expand with in the argh package and you can see the expanded code.

Note

This is not an officially supported Google product.

Contributors

Showing top 12 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from google/argh via the GitHub API.Last fetched: 6/13/2026