{"slug": "show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers", "title": "Show HN: Scriptable CLI tool for generating images using popular providers", "summary": "A developer released etch-image, a scriptable command-line tool published to npm that generates and edits images through the OpenAI, Gemini and FLUX (Black Forest Labs) APIs, installed with `npm install -g etch-image`. Etch is bring-your-own-token: users supply OPENAI_API_KEY, GEMINI_API_KEY or BFL_API_KEY in ~/.config/etch/.env, and the tool defaults to the gpt-image-2.5-sunburst model, supports 1 to 10 images per run via -n, and writes only saved file paths to stdout while progress goes to stderr. The tool matters to developers building image generation into scripts and pipelines because it exposes provider-specific size and quality options — OpenAI sizes up to 3840x2160, Gemini 1K/2K/4K, and FLUX 3 resolution tiers from 768sq to 4k — through a single CLI with JSON output and configurable defaults in ~/.config/etch/config.json.", "body_md": "Scriptable CLI tool for generating and editing images with OpenAI, Gemini, and FLUX.\n\n```\nnpm install -g etch-image\netch \"a polished app icon for a CLI image generation tool called etch\"\n```\n\nYou'll need an API key for the provider you want to use in `~/.config/etch/.env` See [Setup](#setup)\n\n| Provider | Models | \n|---|---|\n| OpenAI |  | \n| Gemini |  | \n| FLUX (Black Forest Labs) |  | \n\n```\nnpm install -g etch-image\n```\n\nEtch is bring-your-own-token. You provide API keys for the providers you want to use. Put them in `~/.config/etch/.env`:\n\n```\nOPENAI_API_KEY=your_key_here\nGEMINI_API_KEY=your_key_here\nBFL_API_KEY=your_key_here\n```\n\nYou only need keys for the providers you plan to use. Keys are read from the shell environment first, then `~/.config/etch/.env`.\n\n```\netch [input_file ...] \"prompt\" [options]\n```\n\nThe last positional argument is always the prompt. Anything before it is treated as an input image:\n\n- **No input files** → generate a new image from the prompt.\n- **One or more input files** → edit those images using the prompt.\n\nThe 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).\n\n| Flag | Description | \n|---|---|\n| `-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| `-n, --count <n>` | Number of images to generate, 1 to 10 (default: 1). With `-o` , files get a`-1` ,`-2` , ... suffix | \n| `--model <model>` | Model to use (default: `gpt-image-2.5-sunburst` ) | \n| `--size <size>` | Output size; depends on the provider, see [Sizes and quality](#sizes-and-quality) | \n| `--quality <quality>` | Quality level (OpenAI) or resolution tier (FLUX 3), see [Sizes and quality](#sizes-and-quality) | \n| `--background <background>` | Background style (OpenAI only) | \n| `--open` | Open the image after it is saved (default when run from a terminal) | \n| `--dont-open` | Don't open the image after it is saved | \n| `--json` | Print the result as a JSON object instead of text | \n| `--force` | Overwrite the output file if it already exists | \n| `--models` | List available models and exit | \n| `--sizes` | List available sizes by provider and exit | \n| `--config` | Show the config file path and effective defaults, then exit | \n\nWhat `--size` and `--quality` accept depends on the model. Run `etch --sizes` for the list.\n\n**OpenAI**\n\n- Size: `auto` ,`1024x1024` ,`1536x1024` ,`1024x1536` .`gpt-image-2` and later also accept any`WIDTHxHEIGHT` (multiples of 16, aspect ratio 1:3 to 3:1, up to`3840x2160` ).\n- Quality: `auto` ,`low` ,`medium` ,`high` .`gpt-image-2.5` models also accept`xhigh` and`max` .\n\n**Gemini**\n\n- Size: `1K` ,`2K` ,`4K` .`gemini-3.1-flash-image` also accepts`512px` ,`gemini-3.1-flash-lite-image` only`1K` , and`gemini-2.5-flash-image` takes no size.\n- Quality: not supported.\n\n**FLUX**\n\n- Size: an aspect ratio like `16:9` , from 21:9 to 9:21.`flux-3` models take a fixed list of ratios (see`--sizes` ). FLUX 2, 1.1 and dev also accept`WIDTHxHEIGHT` ; a ratio is converted to about 1 megapixel for these models.\n- Quality: `flux-3` models only, as a resolution tier:`768sq` ,`1k` ,`1.5k` ,`2k` ,`4k` .\n\nAny 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.\n\n```\n{\n  \"open\": false,\n  \"model\": \"gpt-image-2.5-flare\",\n  \"quality\": \"high\",\n  \"output_dir\": \"~/Pictures/etch\"\n}\n```\n\nSupported 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.\n\nOnly 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:\n\n```\nfile=$(etch \"a red cube\")\netch \"a red cube\" | xargs open\n```\n\nPass `--open` to open the image anyway.\n\nWith `--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:\n\n```\netch --json \"a red cube\" | jq -r .path\n{\"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}\n```\n\nExit codes:\n\n| Code | Meaning | \n|---|---|\n| `0` | Image saved | \n| `1` | Usage or config error (bad flag, invalid size, missing input file) | \n| `2` | Provider error (bad API key, network, server error) | \n| `3` | Request refused by the provider's content moderation | \n\nGenerate an image from a prompt:\n\n```\netch \"a dramatic sunset over the ocean\"\n```\n\nSave to a specific file:\n\n```\netch \"a dramatic sunset over the ocean\" -o output/sunset.png\n```\n\nGenerate four variations at once:\n\n```\netch \"a dramatic sunset over the ocean\" -n 4\n```\n\nEdit an image:\n\n```\netch source.png \"make the sky purple\"\n```\n\nUse a specific model:\n\n```\netch source.png \"make the sky purple\" --model gemini-nano-banana-2.1\n```\n\nSpecify size and quality:\n\n```\netch source.png \"add a sunset\" --size 1536x1024 --quality high\n```\n\nGenerate a 4K widescreen image with the top quality setting (`gpt-image-2.5` models only):\n\n```\netch \"a city skyline at dusk\" --size 3840x2160 --quality max -o output/skyline.png\n```\n\nUse a FLUX model:\n\n```\netch \"cyberpunk cityscape at night\" --model flux-2-pro --size 16:9\n```\n\nGenerate a 4K image with FLUX 3:\n\n```\netch \"cyberpunk cityscape at night\" --model flux-3-image --size 21:9 --quality 4k\n```\n\nUse multiple input images:\n\n```\netch room.jpg reference.jpg \"restyle the first room to match the second\" -o output/restyled.png\n```\n\nSave without opening the result:\n\n```\netch \"a minimal app icon\" --dont-open\n```\n\nThe repo ships a plugin that teaches Claude Code and Codex how to use Etch: ask for an image in a session and the agent runs `etch` for you, names the file sensibly, and reports the cost. It needs `etch` installed and an API key configured as described in Setup.\n\nClaude Code:\n\n```\n/plugin install etch --marketplace michaeldmueller/etch-image\n```\n\nCodex:\n\n```\ncodex plugin marketplace add michaeldmueller/etch-image\ncodex plugin add etch@etch-image\n```\n\nBoth read the same skill, in `plugins/etch/skills/etch/SKILL.md`. To use it as a standalone skill instead, copy that folder to `~/.claude/skills/etch` or `~/.agents/skills/etch`.", "url": "https://wpnews.pro/news/show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers", "canonical_source": "https://github.com/michaeldmueller/etch-image", "published_at": "2026-11-04 14:42:54+00:00", "updated_at": "2026-11-04 14:51:18.621356+00:00", "lang": "en", "topics": ["ai-tools", "generative-ai", "developer-tools", "ai-products"], "entities": ["etch-image", "OpenAI", "Gemini", "FLUX", "Black Forest Labs", "npm", "gpt-image-2.5-sunburst"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers", "markdown": "https://wpnews.pro/news/show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers.md", "text": "https://wpnews.pro/news/show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers.txt", "jsonld": "https://wpnews.pro/news/show-hn-scriptable-cli-tool-for-generating-images-using-popular-providers.jsonld"}}