rules_typescript¶
An opinionated Bazel ruleset for TypeScript, optimised for the Oxc + Vite toolchain rather than broad compatibility with every JS build tool. If your stack is TypeScript, Vite, and a Vite-based framework — this replaces tsc, your bundler, and your dev server with a single hermetic build. If you need tsc compatibility or non-Vite toolchains, see aspect-build/rules_ts (comparison).
Oxc compiles. tsgo type-checks. Vite bundles. Gazelle generates BUILD files. Write .ts, run Gazelle, bazel build //.... No node_modules/. No system Node. Just Bazelisk.
Built for the Vite Ecosystem¶
This ruleset is designed around Vite as the bundler and dev server. Any framework that ships a Vite plugin works:
| Framework | Support | How |
|---|---|---|
| React + Vite | Full | SPA bundling, React Fast Refresh HMR, CSS modules |
| Remix | Full | Client bundle with route-based code splitting |
| TanStack Start | Full | Client + SSR server bundles |
| SvelteKit | Config defined | Via @sveltejs/kit/vite plugin |
| Solid Start | Config defined | Via @solidjs/start/vite plugin |
Frameworks that don't use Vite (e.g., Next.js with webpack/turbopack) are not a priority.
Key Ideas¶
- Oxc compiles — Rust-based TypeScript/JSX transformer.
.js+.js.map+.d.tsper file. Hundreds of files in milliseconds. - tsgo type-checks — Go port of TypeScript runs as a validation action. Type errors fail
bazel build. - Vite bundles — production bundles with tree-shaking, code splitting, minification. App mode (HTML + hashed assets) and lib mode.
- Isolated declarations — explicit return types on exports make
.d.tsa per-file syntactic transform. Change implementation without changing API → no downstream recompilation. - Gazelle generates everything — BUILD files, bundler targets, dev server targets, framework detection, codegen auto-detection.
- Zero prerequisites — only Bazelisk needed. Node.js, pnpm, Go, Rust all fetched hermetically. No
node_modules/in the source tree.
Install¶
Add to MODULE.bazel:
bazel_dep(name = "rules_typescript", version = "0.1.0")
register_toolchains("@rules_typescript//ts/toolchain:all")
bazel_dep(name = "gazelle", version = "0.47.0")
Add to .bazelrc:
build --incompatible_strict_action_env
build --nolegacy_external_runfiles
build --output_groups=+_validation
Quick Example¶
Write TypeScript with explicit return types on exports:
Generate BUILD files and build:
Gazelle produces:
Supported Platforms¶
| Platform | Status |
|---|---|
| Linux x86_64 | Supported |
| Linux ARM64 | Supported |
| macOS x86_64 | Supported |
| macOS ARM64 | Supported |
Documentation¶
- Quick Start — new project or migrating an existing one
- Isolated Declarations — why this makes builds fast
- IDE Setup — VS Code and WebStorm integration
- npm Dependencies — pnpm lockfile integration
- Testing with vitest —
ts_test, snapshots, watch mode - Bundling —
ts_bundlewith Vite or custom bundlers - Monorepo Layout — package boundaries and cross-package deps
- Gazelle Reference — directives,
gazelle_ts.json, framework detection - Rules Reference — all rule attributes and providers
License¶
MIT