# Instagui – turn any CLI into a web GUI with one command

> Source: <https://github.com/Soutar97/instagui>
> Published: 2026-07-07 12:08:33+00:00

**Any CLI. Instant GUI. One command.**

Turn any command-line tool into a clean local web form — no config, no code changes to the tool.

```
npx instagui ffmpeg
```

That's it. instagui reads the tool's `--help`

, turns it into a web form, opens your browser, and
(when you click **Run**) executes the command locally and streams the output back — while always
showing you the exact command it will run, so it teaches you the CLI instead of hiding it.

Thousands of powerful CLIs (ffmpeg, pandoc, yt-dlp, curl, imagemagick…) are unfriendly to anyone
who doesn't live in a terminal — and even experts re-read man pages to recall flag syntax. Tools
like Gooey require the tool's *author* to change their code. instagui needs nothing from the tool: it
parses the tool's own `--help`

text with AI into a structured schema and renders that as a form.

The three demo tools ship with **bundled schemas**, so they work instantly with **no API key**:

```
npx instagui ffmpeg      # video/audio transcoding
npx instagui yt-dlp      # download media
npx instagui pandoc      # convert documents
```

For any *other* tool, instagui extracts the schema on first run using the Claude API (see
[How it stays free](#how-it-stays-free)):

```
export ANTHROPIC_API_KEY=sk-ant-...    # POSIX
$env:ANTHROPIC_API_KEY="sk-ant-..."    # Windows / PowerShell
npx instagui curl
```

Get a key at [https://console.anthropic.com](https://console.anthropic.com). The first extraction is cached, so every launch
after that is instant and free.

**Capture**— run`<tool> --help`

(falling back to`-h`

,`help`

, then the man page), reading both stdout and stderr, under a timeout and size cap so a misbehaving tool can't hang the launch.**Extract**— send the help text to the Claude API (`claude-haiku-4-5`

) and get back a validated JSON schema of the tool's options (name, flag, type, description, enum values, required, grouping) plus positional arguments. Invalid output is retried once, then fails clearly.**Serve**— render the schema as a single-page form on`http://127.0.0.1`

, grouped, with the right control per type (checkbox / dropdown / number / text).**Preview**— show the exact command as you edit the form, one-click copyable.** Run**— execute the command with`spawn`

(arguments array, never a shell string) and stream stdout/stderr live into the page until it exits.

instagui resolves a schema in this order, and only the last step costs an API call:

| Precedence | Source | Needs a key? |
|---|---|---|
| 1 | `--schema <file>` override you supply |
no |
| 2 | Your cache in `~/.instagui/` (written on first extraction) |
no |
| 3 | Bundled schemas shipped with the package (ffmpeg, yt-dlp, pandoc) | no |
| 4 | Fresh extraction via the Claude API | yes |

So the demo tools are free forever, any tool you've used once is free forever after, and you only need a key the first time you point instagui at a brand-new tool. A friendly message tells you exactly what to do if a key is needed and missing — you're never dropped into a stack trace.

`--refresh`

re-extracts and overwrites your cache entry.`--schema ./mytool.json`

uses a hand-tuned schema and skips capture**and** the AI entirely.

```
instagui <tool>                 resolve <tool>'s Schema and serve the Form (auto-opens the browser)
instagui <tool> --print         resolve and print the Schema JSON instead of serving
instagui <tool> --schema <path> use a hand-supplied Schema file (no capture, no AI)
instagui <tool> --refresh       ignore cache + bundled and re-extract fresh
instagui <tool> --help-file <p> extract from a captured help-text file
<tool> --help | instagui <tool> or pipe help text on stdin

  --port <n>     preferred port for the Form server (default 5177; falls back if busy)
  --no-open      do not auto-open the browser (still prints the URL)
  --model <id>   extraction model (default: claude-haiku-4-5)
  -v, --version  print the instagui version
  -h, --help     show help
```

instagui is a **local, single-user tool**. Be clear-eyed about what it does:

**It runs commands you compose.** The whole point is to execute a real CLI with the arguments you set in the form. Treat the form like your own terminal — don't run something you wouldn't type.**The exact command is always shown before you Run it.** No hidden arguments; preview is generated from the*same*argument array that Run executes, so what you see is what runs.**Arguments are passed as an array to** A value containing spaces, quotes,`spawn`

, never concatenated into a shell.`;`

, or`&&`

is passed verbatim as a single argument — there is no shell to interpret it, so form input can't inject extra commands.**The server binds** It is not reachable from your network.`127.0.0.1`

only.**State-changing requests fail closed.**`POST /run`

and`POST /stop`

require a matching`Origin`

header; a missing or foreign origin is rejected (CSRF protection). Exactly one run at a time, and closing the tab (dropping the stream) kills the child process — no orphans.**Your API key is never logged, echoed, or embedded in any served page.** The only data that leaves your machine is the tool's help text, sent to the Claude API for extraction. No telemetry.

Want a tool to work keyless for everyone, like the demo tools do? Bundled schemas live in
[ schemas/](/Soutar97/instagui/blob/main/schemas) and are generated from captured

`--help`

fixtures:- Capture the tool's help into
`test/fixtures/<tool>-help.txt`

. - Add the tool to
`scripts/gen-bundled-schemas.ts`

. - Regenerate with your key:
`ANTHROPIC_API_KEY=sk-ant-... npx tsx scripts/gen-bundled-schemas.ts`

(a hallucination guard + golden check run before anything is written). - Open a PR with the fixture and the generated
`schemas/<tool>.json`

.

Each generated schema is validated so every flag appears verbatim in the source help text — no
hallucinated options. See [ schemas/README.md](/Soutar97/instagui/blob/main/schemas/README.md) for provenance details.

**Node.js ≥ 22**- An
`ANTHROPIC_API_KEY`

only for extracting a tool that isn't bundled or cached.

Deliberately out of scope to keep it small and sharp: interactive/TUI programs (vim, top, REPLs);
subcommand trees (flat tools only — `git commit`

vs `git push`

is v0.2); native file-picker dialogs;
a hosted version, auth, telemetry, or a plugin system; a local-LLM option (contributions welcome).

MIT © Omar
