etch-image
v1.3.0
Published
Scriptable CLI tool for generating and editing images with OpenAI, Gemini, and FLUX
Maintainers
Readme
Quick Start
npm install -g etch-image
etch "a polished app icon for a CLI image generation tool called etch"You'll need an API key for the provider you want to use in ~/.config/etch/.env See Setup
Supported Providers
| Provider | Models | |----------|--------| | OpenAI | gpt-image-2.5-sunburstgpt-image-2.5-flaregpt-image-2gpt-image-1.5gpt-image-1gpt-image-1-mini | | Gemini | gemini-nano-banana-2.1gemini-3.1-flash-imagegemini-3.1-flash-lite-imagegemini-3-pro-imagegemini-2.5-flash-image | | FLUX (Black Forest Labs) | flux-3-imageflux-3-image-kleinflux-2-proflux-2-maxflux-2-flexflux-2-klein-9bflux-2-klein-4bflux-2-pro-previewflux-kontext-proflux-kontext-maxflux-pro-1.1flux-pro-1.1-ultraflux-dev |
Setup
npm install -g etch-imageEtch is bring-your-own-token. You provide API keys for the providers you want to use. Put them in ~/.config/etch/.env:
OPENAI_API_KEY=your_key_here
GEMINI_API_KEY=your_key_here
BFL_API_KEY=your_key_hereYou only need keys for the providers you plan to use. Keys are read from the shell environment first, then ~/.config/etch/.env.
Usage
etch [input_file ...] "prompt" [options]The last positional argument is always the prompt. Anything before it is treated as an input image:
- No input files → generate a new image from the prompt.
- One or more input files → edit those images using the prompt.
The result is saved as a PNG. Pass -o <path> to choose the file, or leave it out and Etch generates a name and outputs it in the current directory (or in output_dir from your config).
Options
| Flag | Description |
|------|-------------|
| -o, --output <path> | Where to save the image (default: an auto-named PNG in the current directory). Never overwrites an existing file unless --force is given |
| -n, --count <n> | Number of images to generate, 1 to 10 (default: 1). With -o, files get a -1, -2, ... suffix |
| --model <model> | Model to use (default: gpt-image-2.5-sunburst) |
| --size <size> | Output size; depends on the provider, see Sizes and quality |
| --quality <quality> | Quality level (OpenAI) or resolution tier (FLUX 3), see Sizes and quality |
| --background <background> | Background style (OpenAI only) |
| --open | Open the image after it is saved (default when run from a terminal) |
| --dont-open | Don't open the image after it is saved |
| --json | Print the result as a JSON object instead of text |
| --force | Overwrite the output file if it already exists |
| --models | List available models and exit |
| --sizes | List available sizes by provider and exit |
| --config | Show the config file path and effective defaults, then exit |
Sizes and quality
What --size and --quality accept depends on the model. Run etch --sizes for the list.
OpenAI
- Size:
auto,1024x1024,1536x1024,1024x1536.gpt-image-2and later also accept anyWIDTHxHEIGHT(multiples of 16, aspect ratio 1:3 to 3:1, up to3840x2160). - Quality:
auto,low,medium,high.gpt-image-2.5models also acceptxhighandmax.
Gemini
- Size:
1K,2K,4K.gemini-3.1-flash-imagealso accepts512px,gemini-3.1-flash-lite-imageonly1K, andgemini-2.5-flash-imagetakes no size. - Quality: not supported.
FLUX
- Size: an aspect ratio like
16:9, from 21:9 to 9:21.flux-3models take a fixed list of ratios (see--sizes). FLUX 2, 1.1 and dev also acceptWIDTHxHEIGHT; a ratio is converted to about 1 megapixel for these models. - Quality:
flux-3models only, as a resolution tier:768sq,1k,1.5k,2k,4k.
Configuration
Any option's default can be changed in ~/.config/etch/config.json (or $XDG_CONFIG_HOME/etch/config.json if that variable is set). A flag on the command line always wins over the config file.
{
"open": false,
"model": "gpt-image-2.5-flare",
"quality": "high",
"output_dir": "~/Pictures/etch"
}Supported settings: model, size, quality, background, count, open, output_dir. The output_dir setting only applies when -o is not given. Run etch --config to see the effective defaults.
Scripting
Only the saved paths are written to stdout, one per line. Progress and the model details go to stderr, and when stdout is not a terminal the spinner and auto-open are skipped. So the output can be captured or piped directly:
file=$(etch "a red cube")
etch "a red cube" | xargs openPass --open to open the image anyway.
With --json, stdout is a single JSON object and errors on stderr are JSON too. path is the first image and paths lists all of them:
etch --json "a red cube" | jq -r .path{"path":"/Users/you/etch-20261021-143210-k8v1.png","paths":["/Users/you/etch-20261021-143210-k8v1.png"],"mode":"generate","provider":"openai","model":"gpt-image-2.5-sunburst","size":null,"quality":null,"background":null,"inputs":[],"elapsed_ms":11840,"cost_usd":0.0412,"cost_estimated":true}Exit codes:
| Code | Meaning |
|------|---------|
| 0 | Image saved |
| 1 | Usage or config error (bad flag, invalid size, missing input file) |
| 2 | Provider error (bad API key, network, server error) |
| 3 | Request refused by the provider's content moderation |
Examples
Generate an image from a prompt:
etch "a dramatic sunset over the ocean"Save to a specific file:
etch "a dramatic sunset over the ocean" -o output/sunset.pngGenerate four variations at once:
etch "a dramatic sunset over the ocean" -n 4Edit an image:
etch source.png "make the sky purple"Use a specific model:
etch source.png "make the sky purple" --model gemini-nano-banana-2.1Specify size and quality:
etch source.png "add a sunset" --size 1536x1024 --quality highGenerate a 4K widescreen image with the top quality setting (gpt-image-2.5 models only):
etch "a city skyline at dusk" --size 3840x2160 --quality max -o output/skyline.pngUse a FLUX model:
etch "cyberpunk cityscape at night" --model flux-2-pro --size 16:9Generate a 4K image with FLUX 3:
etch "cyberpunk cityscape at night" --model flux-3-image --size 21:9 --quality 4kUse multiple input images:
etch room.jpg reference.jpg "restyle the first room to match the second" -o output/restyled.pngSave without opening the result:
etch "a minimal app icon" --dont-open