A small, privacy-first text-to-image tool: type a prompt, get an image. Bring your own provider.
Project description
🖼️ Limn
to limn: to depict or describe; to paint.
A small, privacy-first tool that turns a text description into an image. Type a prompt, get a picture — no account, minimal options, bring your own provider.
pip install limn
limn "a red bicycle against a brick wall" -o bike.png
- Type a description → get an image. That's the whole thing.
- No account, private by default. Your prompts and images are yours. The only network egress is the generation request to the provider you chose.
- Bring your own provider — self-hosted (SwarmUI / any OpenAI-compatible endpoint) or a cloud key (Google Imagen, OpenAI / DALL·E). Swap with one setting.
- Minimal by design. Prompt, size, count, seed. Want power? Install something bigger — Limn stays lean.
Quick start
Pick whichever provider you already have:
# Self-hosted SwarmUI (free, your GPU)
export SWARMUI_BASE_URL=https://image.example.org
export SWARMUI_TOKEN=... # only if fronted by auth
limn "watercolour fox" --provider swarmui
# Any OpenAI-compatible /v1/images endpoint (LocalAI, ...)
export OPENAI_BASE_URL=http://localhost:8080/v1
limn "watercolour fox" --provider openai-compatible
# Google Imagen (cheap, ~$0.02/image on the Fast tier)
export GEMINI_API_KEY=...
limn "watercolour fox" --provider gemini
# OpenAI Images
export OPENAI_API_KEY=...
limn "watercolour fox" --provider openai
Then set your provider once so you never pass --provider again:
limn --init-config # writes a commented ./limn.yaml template
mv limn.yaml ~/.limn.yaml # personal defaults, used everywhere
Usage
limn "a red bicycle against a brick wall" -o bike.png
limn "watercolour fox" --provider swarmui --size 1024x1024 --count 4 --seed 42
| Option | What |
|---|---|
-p, --provider |
swarmui, openai-compatible, openai, gemini |
-m, --model |
Model name (provider-specific) |
-s, --size |
e.g. 1024x1024 (Imagen maps to the nearest aspect ratio) |
-n, --count |
Number of images (1–10) |
--seed |
Reproducibility, where the backend supports it (SwarmUI) |
--negative |
Negative prompt, where supported (SwarmUI) |
-o, --out |
Output file; default is a slug of the prompt, never overwritten |
-c, --config |
Explicit config file |
limn models asks your provider which models it offers (SwarmUI requires
picking one — e.g. limn "a fox" -m juggernautXL_v9). The web UI and desktop
Settings have a matching "fetch models" button.
Config
Layered, later wins: built-in defaults → ~/.limn.yaml (your provider + keys,
set once) → ./limn.yaml → CLI flags. Secrets are referenced as ${VAR} so no
plaintext keys live in files:
provider: swarmui
size: [1024, 1024]
providers: # keep several configured; swap with `provider:`
swarmui:
base_url: https://image.example.org
model: juggernautXL_v9
api_key: "${SWARMUI_TOKEN}"
gemini:
model: imagen-4.0-fast-generate-001
Web UI
pip install "limn[serve]"
limn serve # opens http://127.0.0.1:5466/ in your browser
One page: type a prompt → Generate → the image appears → Save (to disk), Again (regenerate), or Delete. The session gallery lives in the server process's memory only — nothing touches disk until you click Save.
Binds 127.0.0.1 by default. Binding any other host requires a token
(--token, or one is generated and printed); useful flags: --port,
--out-dir, --no-browser.
Hosting a shared demo
limn serve --demo (or LIMN_DEMO=1) runs a friction-free public instance
with guardrails instead of a token: 10 images/hour per IP, provider/model
locked to the server config, one ≤1024px image per request, server-side Save
disabled (visitors download instead), gallery entries expire after 15 min,
and the page shows an "install locally" banner. See
docs/demo-deploy.md.
Desktop app
A native app (Tauri) for people who don't live in a terminal: install, pick
your provider in Settings (server URL / API key — bring your own), type,
generate. First launch bootstraps a private Python runtime via uv (~a
minute, no system Python needed); images save to Pictures/Limn. Installers
for macOS / Windows / Linux are built by CI from desktop/ —
grab them from the GitHub releases page. Builds are unsigned for now: on
macOS right-click → Open the first time; on Windows "More info → Run anyway".
Roadmap
CLI, web UI (limn serve), hostable demo mode, and the
desktop app — all four SPEC surfaces are in.
📄 See SPEC.md for the full specification.
Companion to slide-stream, which shares the same image-provider approach.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file limn-0.4.1.tar.gz.
File metadata
- Download URL: limn-0.4.1.tar.gz
- Upload date:
- Size: 240.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ac77a19bf523085aee5dda9bc5fed856afbca6ab4fae27c56c2bfb2b659ec2d
|
|
| MD5 |
2292c8fc9fad42cc225017ec5b7c1c63
|
|
| BLAKE2b-256 |
f7baa836afc94f6b3ff0345de90f0866d0e3d911e92a52bc1792ac93130cc115
|
File details
Details for the file limn-0.4.1-py3-none-any.whl.
File metadata
- Download URL: limn-0.4.1-py3-none-any.whl
- Upload date:
- Size: 27.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9f070dfad59192583177d9a262283b230e45062335046a150ba15e9db79a8f2
|
|
| MD5 |
4a732ccc58ce351a466bc7fa2dde5bce
|
|
| BLAKE2b-256 |
43ea17af180635cd75c93789a96b6d95cb63699c22427ce9fa5a1c0512387fae
|