Browse pages
Configuration
Configuration is every value a workspace sets outside code: version pins, backend and frontend settings, environment access, secrets, and toolchain versions. This page states where each value lives, who owns it, and when a bad value fails. It applies to anyone who adds a setting, a dependency, or a tool to the workspace.
Stack: any
Layer: workspace
Concepts#
Settings and Environment#
A backend section binds to a named settings type: one class that names each field, its range, and its format, validated when the application starts. A frontend reads its environment through one validated module that separates server-only values from browser-visible ones. Tracked files carry only safe defaults and placeholders; real values live in user secrets locally and on the deployment platform when hosted.
Pins and Repeatability#
A repeatable build resolves the same versions on every machine. The manifest, litespec.manifest.json, pins the baseline stack, one root lockfile pins the JavaScript graph, and the toolchain pins name the package manager and Node.js releases. With every version pinned in one owned place, two checkouts of the same commit build the same result.
Standards#
Validate Backend Configuration at Startup#
ruleruleguidancelitespec/workspace/config#validate-backend-configuration-at-startupA backend configuration section MUST bind to a named settings type validated for required fields, ranges, and formats at startup.
Why
A missing or malformed setting fails somewhere: at startup with a named field, or at the first request that needs it with a downstream error. Binding each section to a validated settings type fails at startup, while the deployment can still stop. Reading a required setting through a raw configuration lookup defers the failure to the first request that needs it.
Checka reviewer answers
Reviewed forEach backend section binds a settings type that fails startup on a missing field, a bad range, or a bad format; read the settings types beside the backend host.
Marked guidance: a reviewer answers this question.
Validate Frontend Environment Access#
ruleruleguidancelitespec/workspace/config#validate-frontend-environment-accessA frontend MUST read environment variables through one validated module separating server-only from browser-visible values, at src/lib/env.ts through the framework alias.
Why
A frontend bundle ships to the browser, so every value it reads is public. One validated module at src/lib/env.ts separates server-only values from browser-visible ones in a single place a reviewer can read. Browser-visible names use the framework prefix, so an unprefixed value stays out of the bundle.
Checka reviewer answers
Reviewed forEach frontend reads environment values only through src/lib/env.ts, with server-only values apart from browser-visible ones.
Marked guidance: a reviewer answers this question.
Keep Secrets Outside Source Control#
ruleruleguidancelitespec/workspace/config#keep-secrets-outside-source-controlA tracked configuration file MUST contain only safe defaults and placeholders.
Why
A tracked file reaches every clone and stays in history after deletion. Local development uses user secrets and hosted environments use the deployment platform, so no real value needs to be tracked. Safe defaults and placeholders keep the tracked file runnable as documentation.
Checka reviewer answers
Reviewed forEach tracked configuration file carries only safe defaults and placeholders; real values live in user secrets or the deployment platform.
Marked guidance: a reviewer answers this question.
Use One Frontend Dependency Graph#
ruleruleguidancelitespec/workspace/config#use-one-frontend-dependency-graphA TypeScript workspace MUST use one root package.json, pnpm-workspace.yaml, and pnpm-lock.yaml.
Why
One root manifest and one lockfile resolve one version of each package for the whole workspace. A nested lockfile lets one application resolve a different version than the workspace CI installs, so local builds and CI builds disagree about the same code. One graph keeps every install identical.
Checka reviewer answers
Reviewed forThe workspace holds one root package.json, pnpm-workspace.yaml, and pnpm-lock.yaml, with no nested lockfile tracked.
Marked guidance: a reviewer answers this question.
Pin the JavaScript Toolchain#
ruleruleguidancelitespec/workspace/config#pin-the-javascript-toolchainRoot package.json MUST declare the manifest pnpm stack release in packageManager and a Node.js engine matching the manifest node stack release.
Why
Different Node.js or pnpm releases resolve, build, and lint differently. Declaring the manifest pnpm release in packageManager and a matching Node.js engine keeps every developer and CI on the same toolchain. CI provisions that Node.js release and invokes the declared pnpm release, so local and CI resolve identically.
Checka reviewer answers
Reviewed forRoot package.json declares packageManager and a Node.js engine matching the manifest releases; CI provisions the same releases.
Marked guidance: a reviewer answers this question.
Pin the React Version in the ESLint Flat Config#
ruleruleguidancelitespec/workspace/config#pin-the-react-version-in-the-eslint-flat-configWhen the workspace holds a React frontend, its ESLint flat config MUST set a concrete settings.react.version rather than leave it at detect.
Why
Version detection calls context APIs that the pinned ESLint release removed, so detect fails under the pinned toolchain. A concrete settings.react.version skips detection entirely and lints against the version the workspace ships.
Checka reviewer answers
Reviewed forEach React ESLint flat config sets a concrete settings.react.version.
Marked guidance: a reviewer answers this question.
Conventions#
Keep Environment Examples Beside Applications#
conventiondefaultguidancelitespec/workspace/config#keep-environment-examples-beside-applicationsKeep a .env.example beside each frontend and deployable host listing required names and safe values.
ReplacementA project that documents its environment centrally records its own example location in its project documentation.
Why
A new developer copies the example to start, and a reviewer reads it to learn which names the application needs. Beside the frontend or host it documents, next to the options module that reads those names, the example changes in the same edit as the names. Anywhere else, it goes stale without anyone noticing.
Checka reviewer answers
Reviewed forEach frontend and deployable host directory holds a .env.example with required names and safe values; where replaced, the project documentation names the central example location.
Marked guidance: a reviewer answers this question.
Keep Local Overrides Untracked#
conventiondefaultguidancelitespec/workspace/config#keep-local-overrides-untrackedKeep developer overrides in ignored local files or a platform secret store.
ReplacementA project that shares override defaults records its own override files and their safe contents in its project documentation.
Why
Developer overrides differ per machine by nature: ports, paths, local endpoints. Committing them turns one developer's setup into everyone's default. Ignored local files or a platform secret store keep overrides personal, and no second committed source competes with the deployment platform for the same value.
Checka reviewer answers
Reviewed forDeveloper overrides live in ignored local files or a platform secret store, with no second tracked environment-specific source.
Marked guidance: a reviewer answers this question.
Keep Logging Configuration Provider-Neutral#
conventiondefaultguidancelitespec/workspace/config#keep-logging-configuration-provider-neutralEmit structured logs through standard logging abstractions and keep exporter configuration in hosts.
ReplacementA project committed to one log backend records its own logging setup in its host configuration.
Why
Application code writes through standard logging abstractions, and each host configures its exporter. Application code then carries no provider choice, so switching a log backend stays inside deployment settings instead of touching every call site.
Checka reviewer answers
Reviewed forApplication source logs through standard abstractions, with exporter configuration in hosts; where replaced, the host configuration names the project's own logging setup.
Marked guidance: a reviewer answers this question.
Keep Documentation Directories Out of Build-Artifact Ignore Rules#
conventiondefaultguidancelitespec/workspace/config#keep-documentation-directories-out-of-build-artifact-ignore-rulesExclude a documentation directory from a build-artifact ignore rule that matches it by accident.
ReplacementA project that renames around the clash records its own directory names in its project documentation.
Why
Platform .gitignore templates match broad names, and a documentation directory with such a name silently stops being tracked. Excluding the documentation directory from the rule keeps records tracked, and git check-ignore confirms each record is visible.
Example
[Oo]utput/
!docs/<directory>/
!docs/<directory>/*.yaml
!docs/<directory>/*.mdConfirm with git check-ignore docs/<directory>/<file>.yaml that no record is ignored.
Checka reviewer answers
Reviewed forEach documentation directory stays tracked; git check-ignore reports no match for the record paths under docs/.
Marked guidance: a reviewer answers this question.
Reference Example#
This informative example demonstrates litespec/workspace/config#validate-backend-configuration-at-startup and litespec/workspace/config#keep-secrets-outside-source-control.
The EmailSettings type binds the Email section and validates its endpoint and sender during startup; the application injects it as a settings type instead of reading raw configuration. The tracked file carries only placeholders, and the consumer workspace secret store supplies the credential.