PoseForge docs
How PoseForge works, how to run it, and how to extend it with a new generation engine.
PoseForge is a local-first photo studio. It takes a person you have saved and a pose you have chosen, and returns that person in that pose — along with portraits, family compositions, and print-ready document photos.
Your workspace, database, and generated files live on your machine. There is no PoseForge account or hosted gallery. ComfyUI can keep inference fully local; cloud and signed-in CLI engines send only the references and prompt you choose to their provider.
Start here
User guide
Studio, ID Photos, libraries, engines, privacy, and troubleshooting.
Troubleshooting
Fix setup, database, pose-library, engine, and generation problems.
Compatibility
Tested operating systems, engine requirements, and local hardware guidance.
Metrics reference
What every cost, token, reliability, latency, and usage number means.
Architecture
The stack, the data model, and how a generation flows from request to file.
Engine interface
The adapter contract. Read this first if you are adding a generation engine.
Contributing
Local setup, migrations, tests, and what a good pull request looks like.
Security
Why API keys live in the database, what leaves your machine, and how to report an issue.
The shape of the system
One Node.js server owns the complete local application:
| Surface | Path | Owns |
|---|---|---|
| Express | /api/*, /storage/* | The API, generation queue, engine adapters, and file storage |
Next.js (web/) | Page and asset routes | The entire user interface |
The UI holds no business logic of its own. Every rule about what makes a valid generation lives in the Express layer and is enforced there; the React app mirrors those rules only to give faster feedback, never to replace them.
Running PoseForge
npm run setup # dependencies, embedded PGlite, migrations, and bundled poses
npm run dev # start the complete development serverOpen localhost:3000. The API is available from the same origin under /api.
Where the numbers come from
The Metrics dashboard reads one table: generations. Every run records its
engine, status, timestamps, and a usage_metrics JSON blob holding token
counts and cost.
Cost is shown as recorded where the provider returns real usage, and as an estimate otherwise — the dashboard tells you which share is which, because an estimate that looks like a measurement is worse than no number at all.