Jest for prompts.
Test-driven prompting for teams shipping LLM features. Local-first. Multi-provider. Self-hostable dashboard.
- Test-driven prompting. Write assertions before you ship a prompt. Catch regressions the moment a model update or a prompt tweak silently breaks an answer.
- Local-first. Your tests, your machine, your data.
ollama/llama3.2is a first-class citizen โ iterate for free, hit paid models only when you need them. - Multi-provider. The same test file runs against Anthropic, OpenAI, Gemini, and Ollama. Compare answers side-by-side in the dashboard.
- Self-hostable dashboard. Run history, compare view, trend charts.
Binds to
127.0.0.1โ no third-party in the loop, no SaaS lock-in.
npm install -g promptforge-cli
cd my-llm-project
promptforge-cli init # interactive scaffolder
promptforge-cli run # execute tests
promptforge-cli ui # open the dashboard# prompts/triage.test.yaml
prompt: ./triage.md
providers:
- anthropic/claude-sonnet-4-6
- openai/gpt-4o-mini
- ollama/llama3.2
tests:
- name: classifies billing complaint
vars:
message: "I was charged twice for my subscription"
assert:
- type: jsonSchema
schema:
type: object
required: [category, urgency, suggested_reply]
properties:
category: { enum: [billing, technical, account, other] }
urgency: { enum: [low, medium, high] }
- type: contains
value: billing
- type: semanticSimilarity
expected: "I'll escalate this for a refund review"
threshold: 0.75
- type: llmJudge
criteria: "Response is empathetic and offers next steps"
threshold: 4
- type: cost
max: 0.002
- type: latency
maxMs: 3000Run it:
$ promptforge-cli run
๐งช PromptForge CLI v0.1.0
โ prompts/triage.test.yaml
โ classifies billing complaint (anthropic/claude-sonnet-4-6) 412ms $0.0008
โ classifies billing complaint (openai/gpt-4o-mini) 298ms $0.0001
โ classifies billing complaint (ollama/llama3.2) 189ms
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
FAIL SUMMARY
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
prompts/triage.test.yaml
โญโ โ classifies billing complaint ยท ollama/llama3.2 โโฎ
โ โ
โ semanticSimilarity โ similarity 0.68 below 0.75 โ
โ expected "I'll escalate this for a refund โ
โ review" โ
โ similarity 0.680 โ
โ threshold 0.750 โ
โ received "What's up? How can I help?" โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Tests 1 failed, 2 passed, 3 total
Providers anthropic, openai, ollama
Cost
anthropic/claude-sonnet-4-6 $0.0008
openai/gpt-4o-mini $0.0001
Duration 1.2s
Run kf8c-Qx2Vm
Run `promptforge-cli ui` to investigate โ
| Provider | Models | Env var |
|---|---|---|
| Anthropic | anthropic/claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5 |
ANTHROPIC_API_KEY |
| OpenAI | openai/gpt-4o, gpt-4o-mini, gpt-4-turbo |
OPENAI_API_KEY |
gemini/gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash |
GOOGLE_API_KEY |
|
| Ollama | ollama/<any-local-model> |
OLLAMA_HOST (optional) |
| Mock | mock |
โ |
| Assertion | What it checks |
|---|---|
contains / notContains |
Substring match |
regex |
Pattern match |
jsonSchema |
Ajv-validated structured output |
semanticSimilarity |
Cosine similarity to a reference string (local embeddings) |
llmJudge |
Scored rubric from a configurable judge model |
snapshot |
Drift detection against the first passing run |
cost / latency |
Budget guardrails |
custom |
TypeScript function assertions (in .test.ts files) |
| Flag | Output |
|---|---|
| (default) | Colorized CLI with spinner + boxed failure diagnostics |
--reporter json |
Machine-readable JSON to stdout |
--reporter junit |
JUnit XML to promptforge-cli-results.xml (or --output <path>) |
promptforge-cli run [paths...] Execute tests
promptforge-cli watch [paths...] Re-run on change (a/f/p/โต/q)
promptforge-cli init Interactive scaffolder
promptforge-cli ui Launch the dashboard (127.0.0.1:3939)
promptforge-cli compare <a> <b> Diff two runs - run IDs, 'latest', 'previous', and 'previous:<runId>' work
promptforge-cli snapshot --update Accept current outputs as golden
promptforge-cli snapshot --clear Delete snapshots by pattern
promptforge-cli list Show discovered tests
A local, read-only web UI over .promptforge/db.sqlite. Runs list,
expandable run detail, side-by-side compare, trend charts, test
explorer with pass-history sparklines.
- Getting Started
- Test Files โ YAML and TypeScript
- Assertions Reference
- Providers Reference
- CLI Reference
- Dashboard Guide
- CI Integration
- How PromptForge CLI Compares
- Known Issues
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLI โ
โ run ยท watch ยท init ยท snapshot ยท compare ยท ui ยท list โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ Config Loader โโโโโโโโโโถโ YAML + TS โ
โ + discovery โ โ test discovery โ
โโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ
โ Test Runner โโโโ Events: onTestStart, โ
โ โ โ onTestFinish, โฆ โ
โโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโ
โ Providers โโAssertionsโโ Reporters โโ Storage โ
โโโโโโโโโโโโโคโโโโโโโโโโโโคโโโโโโโโโโโโคโ (SQLite) โ
โ anthropic โโ contains โ โ cli โโ runs โ
โ openai โโ regex โ โ json โโ results โ
โ gemini โโ jsonSchemaโ โ junit โโ snapshots โ
โ ollama โโ semSim โ โโโโโโโโโโโโโโโโโโโฌโโโโโโโ
โ mock โโ llmJudge โ โ
โโโโโโโโโโโโโโ snapshot โ โโโโโโผโโโโโโโโโ
โ cost โ โ Dashboard โ
โ latency โ โ (Vite+React)โ
โ custom โ โ + Hono API โ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโ
examples/customer-support/โ triage classifier withjsonSchema+contains+semanticSimilarity+ cost/latency budgets.examples/code-review/โ reviewer prompt graded onsemanticSimilaritywith cost guardrails.examples/extraction/โ resume parser with strictjsonSchema+snapshotdrift detection.
See docs/known-issues.md for the full list. Summary:
- Transitive vulnerability in
protobufjsreached via@xenova/transformers. Mitigated at the resolution level via anoverridespin to^7.5.5;npm audit --omit=devreports zero production vulnerabilities. Impact on non-mitigated installs is limited to loading untrusted ONNX models (PromptForge CLI only loads from pinned HuggingFace repositories). - Node 20
tsx/esm/api.register()emits a one-timeExperimentalWarning. Silence viaNODE_OPTIONS="--no-warnings=ExperimentalWarning". Clean on Node 22+. - Windows programmatic SIGINT bypasses user signal handlers (Node
platform quirk). Real-terminal
Ctrl-Cworks correctly.
See CONTRIBUTING.md. TL;DR: clone, npm install,
npm run typecheck, ship a PR for one concern at a time.
See ROADMAP.md. Parallel execution, live-updating dashboard, dataset fixtures, provider plugins, cost-budget bail โ in roughly that order.