Skip to content

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.ts per 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.ts a 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:

// src/math.ts
export function add(a: number, b: number): number {
  return a + b;
}

Generate BUILD files and build:

bazel run //:gazelle
bazel build //...

Gazelle produces:

ts_compile(
    name = "math",
    srcs = ["math.ts"],
    visibility = ["//visibility:public"],
)

Supported Platforms

Platform Status
Linux x86_64 Supported
Linux ARM64 Supported
macOS x86_64 Supported
macOS ARM64 Supported

Documentation

License

MIT