npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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 references in tsconfig files based on workspace:* 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 other workspace: 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-refs

This package provides two equivalent commands: stspr and sync-ts-project-refs

CLI usage

Run

stspr

Preview changes

stspr --dry-run --verbose

CI check (no writes, non-zero if changes needed)

stspr --check

Options

  • --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 for pnpm-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.jsontsconfig.stspr.yaml
  • tsconfig.web.jsontsconfig.web.stspr.yaml
  • tsconfig.custom.jsontsconfig.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.standardReferencesCanonical is true and canonical is not tsconfig.json, stspr adds a reference from tsconfig.json → canonical.
  • Canonical tsconfig: canonicalTsconfig.path (default ./tsconfig.json)

    • If canonicalTsconfig.includeSiblings is true, stspr references sibling tsconfig.*.json files (excluding tsconfig.json)
    • If canonicalTsconfig.includeWorkspaceDeps is true, stspr adds workspace dependency references
    • Applies stspr.package.yaml references.add/skip (canonical only)
    • Applies matching tsconfig.*.stspr.yaml references.add/skip
  • Sibling tsconfigs: other tsconfig.*.json files in the package directory

    • Optional includeWorkspaceDeps can be set per-tsconfig in tsconfig.*.stspr.yaml
    • Applies tsconfig-level references.add/skip

JSON schemas (YAML IDE support)

This project ships JSON schemas for IDE autocomplete/validation.

Schema URLs (unpkg)

Notes:

  • The examples use @latest for convenience.

  • If you prefer stability, replace @latest with 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.json

  • stspr.package.yaml: https://unpkg.com/@monorepo-tooling/sync-ts-project-refs@latest/schemas/stspr.package.schema.json

  • tsconfig.*.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.json becomes a lightweight entry/discovery file
    • It helps tsserver / editor tooling discover other tsconfig.*.json via references.
    • It typically does not carry the workspace dependency reference graph itself.
  • 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.*.json files for discovery.

Recommended configuration

  1. 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
  1. (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: false

Then 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: true

Exclude a package entirely

# stspr.package.yaml
exclude: true

Hard-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.tsconfigPath does 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