PumaPrompter is a reusable library of AI image-prompt fragments. Organise prompt snippets in a tree, then assemble a finished prompt from the nodes you enable. No server, no account, no telemetry.
It's built for booru-tag prompts — the comma-separated, lowercase, underscored_tags used by e621, Danbooru, and the image models trained on their tagging.
Four dialects per node — every node carries parallel content in e621 tags, Booru (Danbooru) tags, Gelbooru tags, and free-form Prose, switched from the selector above the editor. Switching changes what you edit and assemble, the tag vocabulary behind autocomplete + highlighting (Prose has none — it's plain text), and the .e621/.booru/.gelbooru/.prose suffix on the wordmark. Coloured pips on a tree row show which dialects the node already holds text in.
Fragment tree — nest snippets however you like (Character › Kade › Street casual). Each node carries an optional positive and negative snippet.
Ancestor-chain assembly — an enabled node pulls in every non-empty snippet from the root down to it, in order; empty-snippet nodes just group things without adding text.
Enable vs. focus — a node's checkbox controls whether it's in the prompt; clicking its name only focuses it for editing. Enabling a node drops any enabled ancestor or descendant so a chain is never emitted twice — a swept-in ancestor shows dimmed with a locked checkbox. You can edit one node's snippet while several are enabled and watch the prompt update.
Negative prompts — the negative pane gathers the negative tags from your whole selection and their ancestors, removes duplicates, and joins them into one comma-separated set.
Section breaks — mark a node and a <break>, is inserted before its block, so distinct subjects don't bleed together; a <break> divider in the tree marks and removes it.
Tag autocomplete — in a tag dialect, typing surfaces a popularity-ranked list matching your text anywhere in a tag (wolf also finds gray_wolf), colour-coded by category. Three sets are built in — e621 (~101k), Danbooru (~141k), and Gelbooru (~234k) — and a newer export can be imported per dialect (Storage tab).
Valid-tag highlighting — in a tag dialect, any token that's a real tag gets a category-tinted highlight behind the text, so an unhighlighted token reads as a typo at a glance.
Comma-format check — the snippet and assembled fields flag the two comma mistakes that never render (a comma with no space after, or a doubled/empty comma) and offer a one-click Fix commas.
Editable build pane — tweak the assembled text before copying; an edited flag and ↺ Regenerate track divergence from the tree, and each header shows an approximate token + character count, flagging any <break> section over ~75 tokens.
Libraries — keep separate prompt sets as workspace tabs, with undo/redo across tree edits, and back every library up to a single .pumapack (Import or drag-drop restores it).
Tree editing — add, rename, duplicate, and delete nodes; reorder and re-nest by drag (mouse or long-press) or keyboard; a filter box narrows the tree by node name or positive snippet.
Every keyboard shortcut is on the Keyboard tab.
How assembly works
Each enabled node is built by walking the path from the root down to that node and joining each node's snippet in order. Nodes with an empty snippet are skipped, so organising categories (like Character or Outfit) can exist purely to group things without adding text.
Put shared text high, specifics low. A character's base description lives on the character node; a particular outfit lives on the outfit node. Selecting the outfit yields character + outfit together.
Use duplication for variants. Duplicate a node to fork "variant 1 / variant 2" without retyping the shared parent text.
Keep cross-cutting facets at the top level. Children of one node are alternatives — pick one. Anything you'd combine with the rest (pose, expression, camera, light, scene, style) belongs in its own empty top-level group, because two enabled siblings under a text-carrying parent would each re-emit that parent's tags. The seeded Starter library is laid out this way.
Selecting a parent assembles just the path to that parent — a quick way to grab a base description on its own.
Everything below the selected node is ignored; only the ancestors and the node itself contribute.
Multiple subjects & breaks
Tick a node's checkbox to include it (or ⌘/Ctrl-click the row). Each enabled node contributes its ancestor-chain text, in tree order. A subject (one character, a prop, the scenery) can be several nodes — so breaks are manual: mark a node with the — button and a line reading <break>, is inserted before it. In many image models a break token starts a fresh chunk, so distinct subjects don't bleed into each other. Everything between two markers is one subject; place a marker at the start of each new character/prop/scene. To remove a marker, click its <break> divider in the tree (or press the — button again). The focused (accent-barred) node is the one whose snippets the editors edit.
Where your libraries live
Every library is stored in your browser's localStorage, on this device and this browser only. Nothing is uploaded anywhere.
This is the whole database. If you clear site data, use a private window, switch browsers, or lose the device, your libraries are gone. Back up regularly.
Backing up
The Export button saves every library to a single .pumapack file; ⌘/Ctrl+S saves a quick copy. Restore either with Import, or by dragging the file onto the window.
Tag dictionaries
Each tag dialect has a built-in vocabulary — e621 (~101,000 tags), Booru / Danbooru (~141,000 tags), and Gelbooru (~234,000 tags) — served from this site and loaded on demand. Import below replaces the active dialect's set with a newer export (a .csv of name,category,post_count rows, or a plain list of tag names) — stored locally in this browser (IndexedDB) and never uploaded. Switch the Dialect selector to manage another set. Prose has no dictionary.
Using the built-in e621 set.
Clear all local data
Danger zone. This erases every PumaPrompter library in this browser. Export a backup first.
Type DELETE EVERYTHING to confirm:
?
Open this help
Tab / Enter
Complete the highlighted tag suggestion (while typing in a snippet)
↑ / ↓
Move between tree nodes, or between tag suggestions when the list is open
→ / ←
Expand / collapse (or jump to first child / parent)
Space / Enter
Toggle whether the node is included in the prompt
Alt + ↑ / ↓
Reorder the node among its siblings
Alt + → / ←
Nest under previous sibling / lift out to parent
Home / End
First / last node
F2 / double-click
Rename the focused / clicked node
Delete
Delete the focused node (confirms first)
⌘/Ctrl + Z
Undo a tree edit (outside text fields)
⌘/Ctrl + ⇧ + Z
Redo
⌘/Ctrl + S
Save a quick .pumapack backup
Esc
Cancel a rename · close a dialog
About PumaPrompter
PumaPrompter is a lightweight, portable, offline tool for collecting and assembling AI image-prompt fragments, built for booru-tag prompts in four switchable dialects — e621 tags, Booru (Danbooru) tags, Gelbooru tags, and free-form Prose, each node carrying all four side by side. It runs entirely in your browser, with your prompt library kept on your own device.