@monorepo-tooling/sync-ts-project-refs
v0.1.3
Published
<!-- markdownlint-disable MD034 MD029 -->
Readme
stspr (sync-ts-project-refs)
stspr is a monorepo tool that keeps TypeScript project references (references) in sync with your pnpm workspace dependencies (workspace:*).
It scans your workspace packages, reads package.json dependency graphs, and updates each package’s tsconfig.json (and optional tsconfig.*.json) so that TypeScript builds and editor tooling can understand project boundaries.
What it does
- Adds/removes
referencesin tsconfig files based onworkspace:*dependencies - Supports solution-style root aggregation (a root “solution” tsconfig that references all packages)
- Supports per-package canonical tsconfig (what other packages should reference)
- Supports per-tsconfig overrides (extra/skip refs, include deps refs, exclude a tsconfig)
- Preserves comments in
tsconfig.json(JSONC) - Supports CI checks (
--check) and previews (--dry-run)
Requirements
- A pnpm workspace with
pnpm-workspace.yaml - Packages that should participate must have a
tsconfig.json - Workspace dependencies must use
workspace:*(or otherworkspace:ranges)
Zero configuration required — stspr works out of the box with sensible defaults. Configuration files are optional and only needed for advanced use cases.
Installation
Install from npm:
# pnpm
pnpm add -D @monorepo-tooling/sync-ts-project-refs
# npm
npm install -D @monorepo-tooling/sync-ts-project-refs
# yarn
yarn add -D @monorepo-tooling/sync-ts-project-refsThis package provides two equivalent commands: stspr and sync-ts-project-refs
CLI usage
Run
stsprPreview changes
stspr --dry-run --verboseCI check (no writes, non-zero if changes needed)
stspr --checkOptions
--help, -h: show help--dry-run, -d: compute changes but do not write files--check: verify no changes needed (like--dry-run+ fail if changes would be made)--verbose, -v: print detailed processing info--workspace-root, -r <path>: run against a specific workspace root (otherwise auto-detect via searching forpnpm-workspace.yaml)
Configuration files (optional)
All configuration files below are optional. stspr uses sensible defaults and will work without any configuration. Use these files only when you need to customize behavior.
All config keys are camelCase.
Root config: stspr.root.yaml
Location: workspace root (next to pnpm-workspace.yaml)
Purpose:
- Configure transitive deps handling
- Configure global hard excludes (packages / tsconfigs)
- Configure which root solution tsconfig to update, and add/skip refs on that file
# yaml-language-server: $schema=https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/stspr.root.schema.json
graph:
includeIndirectDeps: false
filters:
# pnpm-workspace style glob patterns, supports "!glob"
# If a path matches, it is HARD excluded regardless of per-package/per-tsconfig config.
excludePackages: []
excludeTsconfigs: []
rootSolution:
# Root solution tsconfig to update. If it doesn't exist, stspr skips root updating.
tsconfigPath: ./tsconfig.json
# Include sibling root tsconfig.*.json as references (discovery)
includeSiblings: true
# References that apply ONLY to the root solution tsconfig file
references:
add: []
skip: []Package config: stspr.package.yaml
Location: package root (next to package.json)
Purpose:
- Exclude a package from processing
- Configure canonical tsconfig (what other packages should reference)
- Control which dependency sections are treated as reference edges
- Add/skip references that apply only to the canonical tsconfig
# yaml-language-server: $schema=https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/stspr.package.schema.json
exclude: false
canonicalTsconfig:
# Default: ./tsconfig.json
path: ./tsconfig.json
includeSiblings: true
# Derived default:
# - path != ./tsconfig.json => true
# - path == ./tsconfig.json => false
# standardReferencesCanonical: true
includeWorkspaceDeps: true
dependencies:
include:
dependencies: true
devDependencies: true
optionalDependencies: true
references:
add: []
skip: []Tsconfig-level config: tsconfig.stspr.yaml / tsconfig.{name}.stspr.yaml
Location: same directory as the corresponding tsconfig*.json
Naming:
tsconfig.json→tsconfig.stspr.yamltsconfig.web.json→tsconfig.web.stspr.yamltsconfig.custom.json→tsconfig.custom.stspr.yaml
# yaml-language-server: $schema=https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/tsconfig.stspr.schema.json
exclude: false
# If not set, stspr derives a sensible default based on whether the file is
# canonical/standard/sibling. You can override explicitly:
#
# - true => this tsconfig will include workspace dependency references
# - false => it won't
#
# includeWorkspaceDeps: true
references:
add: []
skip: []How references are computed (high-level)
For each package:
Standard tsconfig:
tsconfig.json- If
canonicalTsconfig.standardReferencesCanonicalis true and canonical is nottsconfig.json, stspr adds a reference fromtsconfig.json→ canonical.
- If
Canonical tsconfig:
canonicalTsconfig.path(default./tsconfig.json)- If
canonicalTsconfig.includeSiblingsis true, stspr references siblingtsconfig.*.jsonfiles (excludingtsconfig.json) - If
canonicalTsconfig.includeWorkspaceDepsis true, stspr adds workspace dependency references - Applies
stspr.package.yamlreferences.add/skip(canonical only) - Applies matching
tsconfig.*.stspr.yamlreferences.add/skip
- If
Sibling tsconfigs: other
tsconfig.*.jsonfiles in the package directory- Optional
includeWorkspaceDepscan be set per-tsconfig intsconfig.*.stspr.yaml - Applies tsconfig-level
references.add/skip
- Optional
JSON schemas (YAML IDE support)
This project ships JSON schemas for IDE autocomplete/validation.
Schema URLs (unpkg)
Notes:
The examples use
@latestfor convenience.If you prefer stability, replace
@latestwith a pinned version (typically the version you installed), e.g.@0.1.1.stspr.root.yaml: https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/stspr.root.schema.jsonstspr.package.yaml: https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/stspr.package.schema.jsontsconfig.*.stspr.yaml: https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/tsconfig.stspr.schema.json
Common recipes
“Solution-style” pattern
Even though stspr does not have a dedicated mode: solution, the solution-style pattern is still fully supported.
The idea is:
tsconfig.jsonbecomes a lightweight entry/discovery file- It helps
tsserver/ editor tooling discover othertsconfig.*.jsonviareferences. - It typically does not carry the workspace dependency reference graph itself.
- It helps
- A non-standard canonical tsconfig becomes the real graph node
- Other packages (and the root solution tsconfig) reference this file.
- This file typically does carry workspace dependency references.
- It may also reference sibling
tsconfig.*.jsonfiles for discovery.
Recommended configuration
- Pick a canonical tsconfig that is not
tsconfig.json(e.g.tsconfig.canonical.json):
# stspr.package.yaml
canonicalTsconfig:
path: ./tsconfig.canonical.json
includeSiblings: true
includeWorkspaceDeps: true- (Optional) Decide which sibling tsconfigs should also include workspace deps refs:
# tsconfig.web.stspr.yaml
includeWorkspaceDeps: true
references:
add: []
skip: []“Pure aggregator” variant (canonical does NOT include deps refs)
This is rarer, but sometimes useful if you want the canonical tsconfig to be a pure “discovery/aggregation” entry:
# stspr.package.yaml
canonicalTsconfig:
path: ./tsconfig.canonical.json
includeSiblings: true
includeWorkspaceDeps: falseThen explicitly enable deps refs on the tsconfig(s) that should carry them:
# tsconfig.build.stspr.yaml
includeWorkspaceDeps: true
references:
add: []
skip: []Non-standard canonical tsconfig (e.g. tsconfig.canonical.json)
# stspr.package.yaml
canonicalTsconfig:
path: ./tsconfig.canonical.json
includeSiblings: true
includeWorkspaceDeps: trueExclude a package entirely
# stspr.package.yaml
exclude: trueHard-exclude packages or generated tsconfigs globally
# stspr.root.yaml
filters:
excludePackages:
- 'packages/legacy-*'
- '!packages/legacy-keep'
excludeTsconfigs:
- '**/tsconfig.generated.json'Add/skip references only on the root solution tsconfig
# stspr.root.yaml
rootSolution:
references:
add:
- { path: './configs/tsconfig.shared.json' }
skip:
- { path: './packages/utils/tsconfig.json' }Troubleshooting
“Why didn’t root tsconfig update?”
- If
rootSolution.tsconfigPathdoes not exist, stspr skips root updating (by design). - If packages are missing
tsconfig.json, they are skipped. - If a package matches
filters.excludePackages, it is hard-excluded.
“My editor doesn’t autocomplete YAML keys”
Ensure the YAML file includes the $schema comment and you have a YAML extension enabled:
- VS Code YAML extension:
redhat.vscode-yaml
