Configuration
You almost never need to edit any of this. npx codeloop initwrites sensible defaults that work for 95 % of projects. Open this page only when you want to override the defaults — everything below is optional.
Every CodeLoop knob is in a small set of files under .codeloop/ in your project root, plus a handful of environment variables. npx codeloop initseeds sensible defaults — this page documents everything you can change.
File layout
your-project/
├── .codeloop/
│ ├── config.json # core config (this page)
│ ├── plugins.json # custom CLI runners — see /docs/plugins
│ ├── figma.json # Figma frame map — see /docs/design-compare
│ ├── sections.json # multi-section state — see /docs/multi-section
│ ├── baselines/ # visual baselines — see /docs/visual-review
│ └── runs/ # local artifact directory (gitignored)
├── designs/ # local design references (optional)
├── .cursor/
│ ├── mcp.json # auto-generated
│ └── rules/*.mdc # auto-generated
└── .claude/
├── settings.local.json # auto-generated
└── agents/* # auto-generatedconfig.json — full reference
{
"project_type": "auto",
"runners": {
"build": { "command": "npm run build", "timeout_ms": 60000 },
"lint": { "command": "npm run lint", "timeout_ms": 30000 },
"test": { "command": "npm test", "timeout_ms": 120000 }
},
"screenshots": {
"enabled": true,
"tool": "playwright",
"base_url": "http://localhost:3000",
"wait_for": "networkidle",
"full_page": true,
"viewports": [
{ "name": "mobile", "width": 375, "height": 812 },
{ "name": "tablet", "width": 768, "height": 1024 },
{ "name": "desktop", "width": 1440, "height": 900 }
],
"urls": ["/", "/about", "/checkout"]
},
"visual_review": {
"threshold": 0.02,
"baseline_dir": ".codeloop/baselines",
"ignore_regions": [
{ "screen": "home", "rect": [0, 0, 1440, 64] }
]
},
"design_compare": {
"threshold": 0.85,
"scoring": "weighted_lab"
},
"recording": {
"enabled": true,
"max_duration_ms": 300000,
"fps": 30
},
"gate_check": {
"min_confidence": 0.94,
"require_all_tests": true,
"allow_lint_warnings": true,
"visual_severity": "warning",
"design_severity": "warning"
},
"sections": {
"enabled": false,
"spec_file": "docs/specs/_master.md",
"acceptance_dir": "docs/acceptance"
}
}Field reference
| Field | Default | Description |
|---|---|---|
project_type | "auto" | Auto-detect from project files. Override with flutter, react, nextjs, vue, angular, django, rails, xcode, android, dotnet. |
runners.<name>.command | Auto-detected | Shell command to run for this check. build, lint, and test are first-class; add custom names for additional checks. |
runners.<name>.timeout_ms | 60000 / 120000 | Hard timeout per runner. |
screenshots.enabled | true | Enable screenshot capture for UI projects. |
screenshots.tool | "playwright" | playwright, puppeteer, maestro (Flutter), simctl (iOS), adb (Android), screencapture (macOS native), powershell (Windows native). |
screenshots.base_url | http://localhost:3000 | Where the dev server lives during verify. |
screenshots.wait_for | "networkidle" | load, domcontentloaded, networkidle, or a CSS selector to wait for. |
screenshots.full_page | true | Capture the full scrollable page (vs. just the viewport). |
screenshots.viewports | mobile / tablet / desktop | Per-viewport capture matrix. |
screenshots.urls | From codeloop_discover_screens | Explicit URL list. If absent, CodeLoop crawls. |
visual_review.threshold | 0.02 | Pixel-difference fraction allowed before a diff fails. See Visual review. |
visual_review.baseline_dir | .codeloop/baselines | Where canonical baselines live. |
visual_review.ignore_regions | [] | Per-screen rectangles to exclude from diffing. Useful for timestamps, ads, A/B variants. |
design_compare.threshold | 0.85 | Minimum match score against Figma frames. See Design compare. |
design_compare.scoring | weighted_lab | pixel, weighted_lab, or structural. |
recording.enabled | true | Allow codeloop_start_recording on this project. |
recording.max_duration_ms | 300000 | Hard cap on a single recording. |
recording.fps | 30 | Target frames-per-second. |
gate_check.min_confidence | 0.94 | Minimum overall score to pass the gate. |
gate_check.require_all_tests | true | Block on any failing test, not just touched-file tests. |
gate_check.allow_lint_warnings | true | Lint warnings count as info, not blocker. |
gate_check.visual_severity | warning | Set to blocker to fail the gate on visual regressions. |
gate_check.design_severity | warning | Set to blocker to fail the gate on design drift. |
sections.enabled | false | Turn on multi-section orchestration. |
sections.spec_file | docs/specs/_master.md | Master spec path. |
sections.acceptance_dir | docs/acceptance | Per-section acceptance directory. |
Platform recipes
Flutter
{
"project_type": "flutter",
"runners": {
"build": { "command": "flutter build apk --debug" },
"test": { "command": "flutter test" },
"lint": { "command": "dart analyze" }
},
"screenshots": {
"tool": "maestro",
"device": "Pixel_6_API_33"
}
}Next.js / React
{
"project_type": "nextjs",
"runners": {
"build": { "command": "npm run build" },
"test": { "command": "npx jest" }
},
"screenshots": {
"tool": "playwright",
"base_url": "http://localhost:3000",
"urls": ["/", "/dashboard", "/settings"]
}
}Vue / Nuxt
{
"project_type": "vue",
"runners": {
"build": { "command": "npm run build" },
"test": { "command": "npx vitest run" }
}
}Django / Rails / Go (via plugin)
For non-built-in stacks, use .codeloop/plugins.jsonto wire your existing CLI test runner into the loop. Plugins behave exactly like first-party runners — failures count toward the gate and surface in the dashboard.
iOS (Xcode)
{
"project_type": "xcode",
"runners": {
"build": { "command": "xcodebuild -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'" },
"test": { "command": "xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'" }
},
"screenshots": { "tool": "simctl" }
}Android (gradle)
{
"project_type": "android",
"runners": {
"build": { "command": "./gradlew assembleDebug" },
"test": { "command": "./gradlew test" }
},
"screenshots": { "tool": "adb", "device": "emulator-5554" }
}.NET / WPF
{
"project_type": "dotnet",
"runners": {
"build": { "command": "dotnet build" },
"test": { "command": "dotnet test" }
},
"screenshots": { "tool": "powershell" }
}Environment variables
| Variable | Required | Description |
|---|---|---|
CODELOOP_API_KEY | Yes | Your CodeLoop API key. |
CODELOOP_API_URL | No | Override backend URL. Defaults to https://api.codeloop.tech. |
CODELOOP_PROJECT_DIR | No | Force the project root path. |
CODELOOP_MODE | No | cloud (default) or local (self-host). |
CODELOOP_OFFLINE | No | true skips backend calls; usage queues locally. |
CODELOOP_LOG_LEVEL | No | debug, info, warn, error. |
FIGMA_API_TOKEN | For Figma compare | Personal access token for the Figma REST API. See Design compare. |
DASHBOARD_PORT | No | Override the default 3737 port for the local dashboard. |
BACKEND_URL | No | Read by codeloop doctor to verify backend reachability. |
Plugin configuration
Drop a .codeloop/plugins.json in the project root to wire any CLI test runner into the verify suite. See the full schema in Plugin SDK. Plugin entries appear next to first-party runners in codeloop_verify output and contribute to the gate score.
Multi-section configuration
Enable sections.enabled = true and create per-section spec / acceptance files. codeloop_section_status reads and writes the state machine; see Multi-section orchestration for the full lifecycle.
Design references
Two paths:
- Figma —
.codeloop/figma.json+FIGMA_API_TOKENenv var. See Design compare. - Local PNG —
designs/<screen>/<viewport>.png. No credentials, no network.
OSS plan project marker
If you applied for the free OSS plan via /oss-application, your approval ties the API key to your repo. There is no per-project config to add — the backend resolves the plan from the key itself.
Self-host configuration
Point CODELOOP_API_URL at your stack and set CODELOOP_MODE=local. See Self-host runbook for the full Docker Compose env reference.
Next Steps
- Tool Reference — understand each tool's capabilities
- CLI reference — invoke any of these from the terminal
- Plugin SDK — wire any test runner into the loop
- FAQ — common questions