Zest

Images

On this page

In edit mode, click a picture (or anything with a background image) and choose Replace image. The picker opens on the tab you used last. It is ordered the way we think you should look: what you already have, then free images, then generation.

Whatever you pick is copied into the page's assets/ folder and the page points at the copy. The page never loads an image from another site, so it works offline, works inside a Claude Artifact (which blocks outside images), and does not tell anyone who is reading it.

This project

Every image in the folder Zest serves, newest first. Generated images say so, and images whose licence needs a credit say that too. Reuse before you make something new.

Library

A starter shelf of images that are CC0 or in the public domain, from museum and NASA collections: botanical plates, paper and texture, maps and charts, landscape and sky, architecture, pattern, earth and space, objects and instruments. Free to use for anything, no credit needed.

The library loads from a CDN. Offline, Zest shows the copy from your last visit, or the list that shipped with the plugin. See library/README.md to add images.

Openverse searches 800 million+ openly licensed images, with no key. "Only images I can use commercially" is on by default. Some licences (Creative Commons BY and its variants) require the creator's name on the page: the picker says so, Zest records the credit in .zest/provenance.json, and Check reminds you until the name is on the page.

Pexels searches free stock photos once you add a free PEXELS_API_KEY. No credit required.

Openverse limits searches without an account. If you hit the limit, Zest says so; try again in a few minutes or use the library.

Generate

Uses your own key and is billed by the provider. Zest picks the provider you have a key for.

OpenAIGoogle
KeyOPENAI_API_KEYGEMINI_API_KEY (or GOOGLE_API_KEY)
Models tried, in ordergpt-image-2, gpt-image-1.5, gpt-image-1gemini-2.5-flash-image, gemini-3-pro-image-preview
Pin oneZEST_OPENAI_IMAGE_MODELZEST_GOOGLE_IMAGE_MODEL
Good to knowOpenAI asks organizations to verify before using image models. Zest tells you if that is the problem.Image models usually need billing turned on for the key's project.

If a model is not available to your account, Zest moves to the next one. If the API rejects a setting, Zest drops it and tries once more.

Options

Nothing lands on your page until you pick it. Every generation is kept in .zest/candidates/ with its prompt and model, and the Generate tab lists earlier candidates for the page. Picking one copies it into assets/generated/ and records how it was made in .zest/provenance.json.

Logos. Ask for a real company's logo and Zest stops to say why that is a bad idea: a generated logo is a drawing of someone's trademark, and it is never quite right. Use the file the company publishes (their press page, or Wikimedia Commons). If it is your own mark or an invented one, generate anyway.

Upload

Drop a file, paste an image, choose a file, or paste an image address. Zest copies it into assets/. SVGs that carry scripts are refused.

You do not need the picker for your own image. In edit mode, click an image and press ⌘V (Ctrl+V) to replace it with whatever picture is on your clipboard, such as a screenshot you just took. Or drag a file from your desktop onto any image on the page. Either way the picture is saved to assets/ and the page points at the file, with one Undo.

Placeholders

A page can leave a slot for a picture it does not have yet: any element with a data-placeholder attribute, naming the concept it carries (data-concept), a size (data-size) and a note (data-note, or its own text). Click it and the picker opens on Place a picture, with the concept and the heading above the slot in its header. A team's own image source opens on that concept, with related art beside the candidates (what the concept already looks like elsewhere, each with a line saying where). Preview on the page shows the pick in the slot; Place it writes it: the placeholder becomes an <img> that keeps the placeholder's class and data attributes, so the page's size rules still apply, with one Undo. The pick is recorded as a placement (what, from where, which asset, which concept, which slot, who, when) in .zest/placements.json, or in the team's own ledger when the extension keeps one.

Images written into the page

A page from a generator sometimes carries its pictures inside the HTML as text (src="data:image/png;base64,…"). It works, but a 1 MB photo becomes 1.3 MB of text that your agent reads every time it opens the file, before it reads a word of your page. Check flags any over 20 KB, and Localize moves each one into assets/ as a real file, named from its alt text. Small ones, like an icon, stay where they are. When you need a single file again, Bundle puts them back in a copy and leaves your working file alone.

After you place it

Suggest a change to this page