Skip to content

Let devtools reuse compatible TypeScript and Vite installs - #254

Merged
SandroMaglione merged 1 commit into
mainfrom
devtools-dependency-ranges
Nov 1, 2026
Merged

SandroMaglione merged 1 commit into
mainfrom
devtools-dependency-ranges

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

@typeonce/effect-machine-devtools listed "typescript": "6.0.3" and "vite": "8.1.5" as exact dependencies, so every consumer installed a second TypeScript and Vite at exactly those versions. This PR changes them to ranges and keeps them as dependencies:

  • typescript: 6.0.3 → >=5.9.0 <7.0.0
  • vite: 8.1.5 → ^8.1.5

The devtools README's Compatibility section now explains what the CLI brings with it and why TypeScript 7 is excluded. The root README has no install commands, so it is unchanged.

Decision: ranged dependencies, not peers

How devtools uses each package:

  • typescript is used only in src/internal/projectInspector.ts, for syntactic discovery (ts.createSourceFile, ts.forEachChild, node guards, and ts.transpileModule for syntax diagnostics). It never type-checks the consumer project, so the consumer's compiler version doesn't matter to it.
  • vite is the CLI's server and bundler engine. devServer.ts runs createServer rooted at the devtools package, staticSite.ts runs build with configFile: false, and the evaluation worker runs a middleware-mode server with ssrLoadModule. Both CLI commands (effect-machine and effect-machine build) need it, so it is not optional.

Why not peers:

  • TypeScript 7 does not ship the JavaScript compiler API. The "." export of typescript@7.0.2 is just lib/version.cjs. With a peer, a TS 7 project (e.g. one on 7.0.2) would get an unsatisfied-peer warning, and pnpm would link the project's TS 7. Then import ts from "typescript" would load no compiler and the CLI would crash. As a dependency with <7.0.0, such a project gets a private 5.9–6.x copy and the CLI keeps working.
  • Vite is an internal engine, not an integration with the consumer's Vite config. A peer would force projects that don't use Vite (Next.js, plain Node) to add it. On a Vite 7 project it would warn and link an untested Vite major into the CLI. ^8.1.5 dedupes with a project's Vite 8 and otherwise installs a private copy.
  • The existing devtools:pack-check fixture installs devtools with neither package. The CLI is designed to need no setup, and this keeps that.

The lower bound 5.9.0 covers the APIs used, which have been stable for many releases. It lets a 5.9 project dedupe to a single TypeScript. I verified it at runtime (below).

Changeset

  • Added or updated for a library or package-metadata change: .changeset/devtools-dependency-ranges.md, patch for @typeonce/effect-machine-devtools. This deviates from the "minor" originally proposed for this item. That proposal assumed a move to peers, which would change what consumers install. With ranged dependencies, consumers install nothing new, which .changeset/README.md classes as a compatible improvement (patch). The fixed group releases all four packages together.
  • Not required because this PR does not change a publishable package

Validation

  • pnpm check: 92 files / 901 tests, all tstyche suites, pack:check, test:consumer, devtools:pack-check (fresh install resolves the newest in-range TypeScript and Vite), and the other pack checks.
  • Lockfile: workspace tests still resolve typescript@6.0.3 and vite@8.1.5. Only the specifiers changed.
  • Manual smoke run from the repo: pnpm devtools build --root ../.. --include "packages/devtools/src/internal/browser/{example-machine,*-example}.ts" built a static site with 14 machines. A live server started with the same include served / and returned 14 Ready results from /api/machines, then stopped on SIGINT.
  • Packed-consumer smoke test (packed core and devtools tarballs, then effect-machine build):
    • Project on typescript@5.9.3 + vite@8.1.5: a single typescript@5.9.3 and a single vite@8.1.5 were installed (deduped), and the build succeeded.
    • Project on typescript@7.0.2: devtools got its own typescript@6.0.3 next to the project's 7.0.2, and the build succeeded.
  • Automated type-performance measurement passed or was not required (no TypeScript source change)
  • Automated runtime- and memory-performance measurement passed or was not required (no runtime change)

🤖 Generated with Claude Code

The devtools CLI pinned typescript 6.0.3 and vite 8.1.5 exactly, so every
consumer installed a second copy at exactly those versions. Depend on
typescript >=5.9.0 <7.0.0 and vite ^8.1.5 instead. Both stay regular
dependencies: the CLI must work with zero setup, and TypeScript 7 does not
ship the JavaScript compiler API that project inspection parses with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SandroMaglione
SandroMaglione force-pushed the devtools-dependency-ranges branch from 070dbbf to 36dc410 Compare November 1, 2026 09:11
@SandroMaglione
SandroMaglione merged commit 697c6cb into main Nov 1, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the devtools-dependency-ranges branch November 1, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant