Skip to main content

What We Learned

STRATT’s monorepo pattern is standalone packages with no root workspace config. Each package has its own package.json, tsconfig.json, and test setup. The first two packages (@stratt/schema, @stratt/fingerprint) had zero inter-dependencies. @stratt/graph broke this isolation deliberately: it imports types and functions from both siblings. The question was whether "file:../schema" in package.json would resolve cleanly without a Bun workspace root. It did. bun install resolved both file: dependencies, TypeScript found the types, and bun run typecheck passed on the first attempt. No root package.json needed.

Why This Matters

The layered architecture (L0 identity, L1 schema, L3 graph) requires upward dependencies. If the first bridge had required restructuring the monorepo, every future layer would inherit that cost. The file: protocol keeps the flat structure intact while enabling explicit, versioned cross-package imports.

Pattern

"dependencies": {
  "@stratt/schema": "file:../schema",
  "@stratt/fingerprint": "file:../fingerprint"
}
This resolves at bun install time. TypeScript sees the sibling’s src/index.ts (via "types": "src/index.ts" in the sibling’s package.json). No path aliases, no root tsconfig, no build step.

Limitation

file: dependencies are local-only. When these packages are published to npm, the protocol switches to version ranges. The current pattern works for development and CI; publish-time packaging will need a workspace or release script.