Peinture: a browser-based image generator that keeps its tokens local
A general-purpose AI image generation framework that supports Hugging Face, Gitee, Model Scope, and more.
At a glance
- What is it?
- Peinture is a React and TypeScript single page app that generates and edits images through Hugging Face, Gitee AI, Model Scope and A4F, with custom OpenAI-compatible providers allowed, and it runs in three modes from fully local to fully proxied. Tokens and history stay in the browser, and there is an official Docker image that serves the built app through Nginx.
- Who is it for?
- Peinture suits someone who wants a self-hosted image generation front end where the API tokens never leave the browser, or who needs several Chinese and international model providers behind one interface with a shared gallery. It does not suit a team that needs a stable API, a licence to build on, or a guarantee that a specific model name keeps working, since the project has no releases, no stated licence and a last push on 2026-06-18.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 127 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One interface over four model providers
Peinture is a general purpose AI image generation framework, and the description of what it does is a list of providers rather than a list of features. It draws on generative models from Hugging Face, Gitee AI, Model Scope and A4F to create images from text prompts in seconds, and you can add custom OpenAI-compatible providers to extend it.
The multi-provider architecture is the core of the product. Switching between Hugging Face, Gitee AI, Model Scope and A4F is done from the interface, and the model catalogue spans a wide range. The generation models named are GPT Image 2, Nano Banana 2, Z-Image Turbo, Qwen Image, Ovis Image, FLUX.1 in the Schnell, Dev and Krea variants, and FLUX.2. The text and optimisation models listed are OpenAI 5.4, Gemini 3.1 Pro, DeepSeek V4 and Qwen 3, which are used for prompt work rather than for pixels.
Gitee AI and Model Scope are Chinese platforms, and that shapes part of the design. Gitee AI requires a token and provides a daily free quota for generated images, Model Scope requires a token, and A4F requires a token. Hugging Face works out of the box on public quotas, with a token recommended for heavy use or peak times.
The technical stack is React 19 built with Vite, styled with Tailwind CSS, with Lucide React for the icons and Zustand with persistence for state. The dependency list in package.json is short: React and React DOM, Zustand, Sonner for the toasts, react-zoom-pan-pinch for the image editor, and opfs-tools for the browser file system.
Local, server and hydration are three different deployments
The service mode setting is the most consequential design choice in the application, because it determines where the API calls are made and therefore who pays for them.
Local mode runs entirely in the browser using public APIs, so the request goes from the browser straight to the provider and no token is needed for the ones with public quotas. Server mode connects to a private backend for proxying requests, which means a token can live on a server instead of in the browser. Hydration is the hybrid, combining local logic with server capabilities.
For a self-hosted deployment, the server mode is the interesting one, and the Docker image is built around it. The Dockerfile has two stages. The builder stage uses node:20-alpine, enables pnpm through corepack, copies the package.json and the pnpm lock file, installs with the frozen lockfile flag, copies the source, and then sets a build-time environment variable:
ENV VITE_PROXY_URL=/proxyThat variable points the built application at the internal Nginx proxy rather than at a public host, and it is the mechanism by which server mode works in a container. The second stage serves the built files with Nginx, copies the custom nginx.conf over the default site configuration, and copies the dist directory into the Nginx html directory.
The Docker Compose file in the repository is the simpler variant. It builds from the local context, names the container peinture, publishes port 80 and restarts unless stopped. The documentation notes that the built-in Nginx securely handles SPA routing and image CORS proxying, and separately warns that for a static deployment on any other server you need to redirect 404s to index.html so client-side routing works.
Storage is local first, with object storage as an option
The storage design is where the privacy claim lives, and it is worth reading carefully rather than taking the badge at face value.
There are two options. Local storage uses OPFS, the Origin Private File System, described as high-performance persistent local storage within the browser. Cloud storage connects to S3-compatible storage, with AWS, R2 and MinIO named, or to WebDAV, to sync creations across devices.
The privacy claim is stated as history and credentials being stored locally in the browser's LocalStorage, with no user tracking. Taken at face value, that means the API tokens you paste into the settings screen never leave the machine, which is a genuine advantage over a hosted image generator where the token has to be given to somebody else's server. The exception is server mode, where the proxy needs a token, and the point of that mode is that the token lives on your own backend rather than in a third party's database.
The file system choice is a technical decision with a practical edge to it. OPFS gives an application a real file system inside the browser, so images can be written to and read from disk without holding everything in memory or in local storage as base64 blobs, and it survives a reload because the data is persistent rather than cached.
The cloud gallery is what makes the tool usable across devices. With S3 or WebDAV configured, the images you generated on a laptop are reachable from another machine, and the S3-compatible route means the object store does not have to be an AWS bucket.
Editing, motion and the prompt tools around the generator
The application is more than a prompt box, and the extra features are the reason to run your own instance rather than using a hosted tool.
The image editor modifies existing images with the Qwen-Image-Edit model, with brush and rectangle selection, reference image support of up to three, and AI-assisted prompt optimisation. Live Motion transforms a static image into a dynamic five second cinematic video using the Wan 2.2 model, which is supported on Hugging Face and Gitee AI. That last point is the practical limit of the model ecosystem: not every provider carries every model, so a feature can exist in the interface and still be unavailable for the provider you have configured.
Prompt engineering is integrated rather than bolted on. There is an AI prompt enhancer that expands a simple idea into a detailed description, and an auto translation feature for optimising prompts for English-centric models like FLUX. For a user whose native prompt language is not the one the model expects, that is not a convenience but the difference between a usable result and noise.
The generation controls are the standard set exposed in the interface: adjustable inference steps, seed control, guidance scale, and an HD mode offering four times upscaling.
No licence, no releases, and a live demo to compare against
The maintenance facts are thin, and the honest framing is that this is a working application rather than a library.
The licence is recorded as unknown, and there is no LICENSE file among the top level entries, which run from .dockerignore and .env.local.example through App.tsx, the components, hooks, services, store, views and tests directories, the Docker files and the config files. The default under copyright applies, so there is no explicit permission to copy, modify or redistribute it. For a project you might want to fork and adapt, that is the first thing to sort out.
The repository is not archived, the default branch is main, and the last push was on 2026-06-18, four months before the current date. There are no GitHub releases, and the package version in the metadata is 1.4.0 with the package marked as private, so it is not published to a registry. The package name is peinture, and the homepage is peinture.u14.app, which is also where the screenshots and the hosted demo live.
That last point is useful. The demo is a live deployment of the application, so you can compare a hosted instance against your own before deciding to run it, and you can see which providers and models are actually responding rather than trusting a feature list.
The development setup is conventional. Node 18 or higher with npm, yarn or pnpm, then a clone, npm install, and npm run dev, which serves on port 5173. The scripts are the standard Vite set, with dev, build and preview, plus eslint and a vitest test script with a watch variant, and the configs for PostCSS, Tailwind, ESLint, Vite and Vitest are all at the root. The dependency versions are current, with React 19.2, Vite 6.2, Tailwind 3.4, TypeScript 5.8 and Vitest 4.1.
Deployment is offered in four ways, from Vercel as the recommended one, through Cloudflare Pages, to a static CDN with a manual dist upload, and the Docker image.
Editorial conclusion
Peinture suits someone who wants a self-hosted image generation front end where the API tokens never leave the browser, or who needs several Chinese and international model providers behind one interface with a shared gallery. It does not suit a team that needs a stable API, a licence to build on, or a guarantee that a specific model name keeps working, since the project has no releases, no stated licence and a last push on 2026-06-18. Before deploying it, read the .env.local.example and the three service modes, and put the Nginx image behind your own authentication, because the app itself stores no user accounts.
Frequently asked questions
What is Peinture?
It is a general purpose AI image generation framework built with React, TypeScript and Tailwind CSS, that creates and edits images from text prompts using models from Hugging Face, Gitee AI, Model Scope and A4F, and that also accepts custom OpenAI-compatible providers.
What are the three service modes in Peinture?
Local mode runs entirely in the browser using public APIs, server mode connects to a private backend for proxying requests, and hydration is the hybrid combining local logic with server capabilities.
Where does Peinture store my images and API tokens?
Local storage uses OPFS, the Origin Private File System, in the browser, and history and credentials are kept in the browser's LocalStorage with no user tracking. For syncing across devices you can connect S3-compatible storage such as AWS, R2 or MinIO, or WebDAV.
How do I run Peinture locally?
You need Node.js 18 or higher and npm, yarn or pnpm. Clone the repository, run npm install, then npm run dev and open http://localhost:5173. For a container, the image is ghcr.io/amery2010/peinture:latest, run with docker run -d -p 80:80, and the Dockerfile builds with Vite and serves the result through Nginx.
Which models does Peinture use for editing and video?
The image editor uses the Qwen-Image-Edit model, with brush and rectangle selection, up to three reference images and AI-assisted prompt optimisation. Live Motion turns a still image into a five second video using Wan 2.2, which is supported on Hugging Face and Gitee AI.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/amery2010-peinture)Was this useful?