Preview config
Field-level reference for the `preview` section of `.143/config.json`.
Use the preview section when reviewers need a live app alongside the transcript and diff. The shape can stay small for one service or expand to multiple services, infrastructure, secrets, and network policy.
143 supports two shapes:
- Single-service shorthand with top-level
command,cwd,port,env, andready. - Multi-service config with
primaryandservices.
Do not mix the two shapes in one config.
Repos may also wrap preview configs in a named config map:
{
"preview": {
"default": "web",
"configs": {
"web": { "name": "Web", "command": ["npm", "run", "dev"], "port": 3000, "credentials": { "mode": "none" }, "network": { "mode": "managed" } },
"docs": { "name": "Docs", "command": ["npm", "run", "dev"], "port": 3001, "credentials": { "mode": "none" }, "network": { "mode": "managed" } }
}
}
}Use preview.default to auto-select one config. If there are multiple configs and no default, callers must provide a preview config name.
Top-level fields
preview.defaultstringpreview.configsobjectpreview.versionstringpreview.namestringpreview.primarystringpreview.installobjectpreview.servicesobjectpreview.infrastructureobjectpreview.resourcesobjectpreview.secretsobject | object[]preview.credentialsobjectpreview.networkobjectrequiredpreview.progressivebooleanpreview.commandstring[]preview.cwdstringpreview.portintegerpreview.envobjectpreview.readyobjectInstall fields
preview.install.commandstring[]requiredpreview.install.cwdstringdefault: .preview.install.lockfilesstring[]preview.install.clean_pathsstring[]preview.install.verify_pathsstring[]preview.install.cache.enabledbooleandefault: truepreview.install.cache.pathsstring[]preview.install.cache.build.enabledbooleandefault: truepreview.install.cache.build.pathsstring[]preview.install.timeout_secondsintegerdefault: 420Install caches are keyed from the install command, declared lockfiles, the platform sandbox cache ABI, and effective cache paths. They speed up preview startup without replacing source files from the session workspace. Routine 143 deploys do not change the ABI; platform operators bump it only when sandbox OS/toolchain/runtime compatibility changes.
Use preview.install for dependency installation only. Source-dependent builds belong in service commands, where they run against the current workspace on every start.
Inferred dependency cache paths:
| Dependency file | Inferred cache path |
|---|---|
package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, bun.lock, bun.lockb | node_modules |
poetry.lock, uv.lock, Pipfile.lock, pdm.lock, requirements.txt, requirements-dev.txt | .venv |
go.mod, go.sum | vendor |
Inference is relative to the dependency file directory. For example, services/api/poetry.lock infers services/api/.venv, and go.mod infers vendor.
Do not cache source directories, secret files, .git, .143/cache, .143/cache/preview-install, or any parent/glob path that can include preview install markers. requirements.txt is safe only when dependencies are pinned. For stale dependencies, change lockfiles or temporarily set cache.enabled: false.
Build-artifact cache
Build-artifact caches are separate from install artifacts. They are restored after install and saved asynchronously after services report ready. JS lockfiles infer Turborepo cache directories; add other content-addressed caches, such as .next/cache, with preview.install.cache.build.paths.
Only cache build directories whose tool validates entries by content hash. A stale build cache should degrade to a partial miss, not serve wrong output.
Service fields
commandstring[]requiredcwdstringportintegerrequiredenvobjectready.http_pathstringready.timeout_secondsintegerdefault: 90Constraints:
- At most 4 services per preview config.
- Ports must be unique.
portmust be in the range1024to65535.ready.http_pathmust start with/and use safe URL path characters.
Infrastructure fields
templatestringrequiredinit_scriptstringinject_envobjectinject_intostring[]Supported templates:
| Template | Default port |
|---|---|
postgres-17 | 5432 |
postgres-16 | 5432 |
redis-7 | 6379 |
mysql-8 | 3306 |
Supported inject_env placeholders are {{username}}, {{password}}, {{host}}, {{port}}, and {{database}}.
Secret bundle fields
New preview configs should prefer preview.secrets. The legacy preview.credentials shape remains supported for env-var-only credential sets.
preview.secrets.bundlestringrequiredpreview.secrets.servicesstring[]requiredpreview.secrets.envstring[]preview.secrets.filesstring[]preview.secrets may be a single object or an array of objects. The repo config never contains secret values. It only declares the bundle name, service scope, and expected output names. A bundle may deliver multiple environment variables and one generated file.
Admin-managed bundle outputs support:
| Output format | Use |
|---|---|
env | Inject named env vars into scoped services. |
json | Generate a JSON file from structured content or from one managed secret value containing the whole JSON document. The resolved value must parse as JSON. |
raw | Generate a file from one complete secret value, useful for PEM blocks or other non-JSON blobs. |
For a whole JSON file such as development.conf.json, store the raw JSON document as the managed secret value and configure the file output as:
{
"type": "file",
"path": "development.conf.json",
"format": "json",
"value": "secret:development_conf_json"
}Do not base64-encode JSON just to preserve quotes or newlines. 143 writes generated files as bytes and handles runtime shell transport internally.
Credential fields
preview.credentials.modestringpreview.credentials.credential_setstringpreview.credentials.envstring[]preview.credentials.inject_intostring[]Secret values do not belong in .143/config.json. Put public, non-secret values in service env; reference secrets with preview.secrets or legacy preview.credentials.
Network fields
preview.network.modestringrequiredpreview.network.destinationsstring[]Resource fields
preview.resources.requests.cpustringpreview.resources.requests.memorystringpreview.resources.requests.ephemeral-storagestringpreview.resources.limits.cpustringpreview.resources.limits.memorystringpreview.resources.limits.ephemeral-storagestringPlatform-injected environment
Every service receives:
| Variable | Use |
|---|---|
HOST | Defaults to 0.0.0.0 so frameworks bind where the preview gateway can reach them. |
ONEFORTYTHREE | Always true. Use this to detect that the process is running on 143. This name is reserved; preview configs and secret bundle env outputs that declare it fail validation. |
ONEFORTYTHREE_ENV | Always preview for preview runtimes. Use this to disable background consumers, schedulers, profilers, telemetry exporters, and other work that is not required to serve the preview. This name is reserved; preview configs and secret bundle env outputs that declare it fail validation. |
PREVIEW_ORIGIN | Public preview URL. Use this for external base URLs, redirects, callbacks, and absolute links. |
Trust rules
Preview config is repository content. For fields that can expose secrets or network access, 143 reads from the base branch rather than an agent diff.
For non-connected previews, service runtime fields can come from the session diff. For connected previews, launch behavior is pinned to the base branch. A preview is connected when preview.secrets is present, preview.credentials.mode is not none, or preview.network.destinations is non-empty.
Runtime freshness
143 can live-update ordinary source changes through the preview's dev server. Dependency, preview config, build config, environment config, and schema changes require a preview refresh. Refreshes reuse install, package-manager, and build caches when their keys still match.
For task-based examples and behavior details, see Preview environments. For repo-wide setup, see Repo config.