# Flags

> Declare a Command's flags with the standard library's flag types, add short names and environment variables, and tell which flags were passed.

This guide covers a Command's flags. You will learn how to:

- Declare flags of any type
- Pass flag values on the command line
- Add a short name for a flag
- Read a flag from an environment variable
- Accept a flag more than once
- Tell which flags were passed

## Overview

Flags are the named options of a Command, such as `--limit 5` or `--force`. A Command declares them in its `Flags` function, each bound to a variable that `Run` reads. Help lists them with their types and defaults, and an unknown flag is a usage error with a suggestion.

`Flags` receives a `*cli.FlagSet`, which is the standard library's `flag.FlagSet` with two additions, `Alias` and `Env`. Every flag type it offers works.

## Declare flags

Declare each flag with its name, default and usage, and read the variable in `Run`:

```go
func previewCommand() *cli.Command {
	var (
		port    int
		host    string
		open    bool
		timeout time.Duration
	)
	return &cli.Command{
		Name: "preview",
		Flags: func(f *cli.FlagSet) {
			f.IntVar(&port, "port", 3000, "The port to listen on")
			f.StringVar(&host, "host", "localhost", "The host to listen on")
			f.BoolVar(&open, "open", false, "Open the browser")
			f.DurationVar(&timeout, "timeout", 30*time.Second, "How long to wait for a request")
		},
		Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
			…
		},
	}
}
```

```text title="Output"
$ act preview --help
Usage:
  act preview [flags]

Flags:
      --host string       The host to listen on (default localhost)
      --open              Open the browser
      --port int          The port to listen on (default 3000)
      --timeout duration  How long to wait for a request (default 30s)
  -h, --help              Show help
      --json              Print a single JSON result instead of text
      --no-interaction    Never prompt; use defaults
```

`TextVar` declares a flag of any type that parses itself from text, such as `netip.Addr` or a type of your own. A value that doesn't parse is a usage error naming the flag.

## Pass flag values

A flag's value follows it, after a space or an equals sign. A bool flag needs no value, and takes one only after an equals sign:

```sh
act preview --port 8080 --open
act preview --port=8080 --open=false
```

Flags may come before or after the Command's [arguments](arguments.md), and everything after `--` is an argument.

## Add a short name

`Alias` gives a flag another name. Both set the same variable, and help shows them together. Declare the flag first:

```go
			f.BoolVar(&open, "open", false, "Open the browser")
			f.Alias("open", "o")
```

```sh
act preview -o
```

## Read flags from the environment

`Env` lets an environment variable set a flag that the command line doesn't. The command line wins, then the variable, then the flag's default. Help shows the variable:

```go
			f.IntVar(&port, "port", 3000, "The port to listen on")
			f.Env("port", "PORT")
```

```text title="Output"
      --port int          The port to listen on (default 3000) [$PORT]
```

The variable's value is checked like one typed on the command line: `PORT=eighty` is a usage error that names `PORT`.

## Accept a flag more than once

`Func` calls a function for each occurrence, so a flag can collect values:

```go
			var origins []string
			f.Func("origin", "Allow requests from this origin (repeatable)", func(s string) error {
				origins = append(origins, s)
				return nil
			})
```

```sh
act preview --origin https://example.com --origin https://admin.example.com
```

## Tell which flags were passed

`c.Given` reports whether the command line, or an environment variable, set any of the flags named, or, with no names, any flag at all. Use it to tell a default from a value someone chose:

```go
			if !c.Given("port") {
				c.Info("Listening on the default port, %d", port)
			}
```

## Check flag values

A flag that must be in a range, or depends on another, is checked in `Run`. Return `cli.UsageError` so the Command exits with status `2` and points to its help:

```go
			if port < 1 || port > 65535 {
				return nil, cli.UsageError("--port must be between 1 and 65535, got %d", port)
			}
```

To require a flag, ask for it with a [prompt](prompts.md) and `cli.Required()`: a person is asked, and a script that leaves it out gets an error naming the flag.

## Flags every Command has

::::options

:::option{name="--help" type="bool"}
Shows the Command's help instead of running it. `-h` is the same.
:::

:::option{name="--json" type="bool"}
Prints a single JSON result. See [Agent mode](../../reference/agent-mode.md).
:::

:::option{name="--no-interaction" type="bool"}
Never prompts: answers come from flags and defaults. See [Prompts](prompts.md).
:::

::::

See also: [Arguments](arguments.md), [Prompts](prompts.md), [Creating Commands](commands.md)
