Skip to main content
Bazel gives JavaScript and TypeScript projects fast, incremental builds with correct caching, even across large monorepos with hundreds of packages. Its hermetic build engine guarantees reproducibility for teams that need reliability at scale.
Stuck?

Create a new project

1

Install the Aspect CLI.

brew install aspect-build/aspect/aspect
For more details, see Aspect CLI.
2

Add the init command.

aspect axl add gh:aspect-build/aspect-workflows-template
3

Initialize your project.

aspect init # select JavaScript

Explore Bazel

Package management with pnpm

rules_js consumes a pnpm-lock.yaml lockfile to create a correct node_modules tree. Unlike npm or yarn lockfiles, pnpm's lockfile format is expressive enough for Bazel to resolve the dependency graph without ever running a package manager itself. rules_js can also provide the pnpm binary itself, so every developer on your team uses the same version. Aspect recommends you migrate to pnpm before adopting Bazel. Your .npmrc file should include:
hoist=false
See the pnpm guide for details.
Remember to run pnpm install after changing package.json. Bazel reads directly from pnpm-lock.yaml, so lockfile changes won’t be picked up until you update it.

Automatically updating the lockfile

If you’d rather not run pnpm install manually, rules_js can update pnpm-lock.yaml for you. Set update_pnpm_lock = true in npm_translate_lock and Bazel runs pnpm install whenever its inputs change. You don’t have to remember to update the lockfile and rules_js always uses the same version of pnpm from Bazel. You can migrate from an existing npm or yarn lockfile if you haven’t migrated to pnpm yet. Pass your package-lock.json or yarn.lock to npm_translate_lock with the npm_package_lock or yarn_lock attributes. When either is set, update_pnpm_lock defaults to true and rules_js automatically runs pnpm import to produce the pnpm-lock.yaml that Bazel needs. However, note that when you enable update_pnpm_lock, you must list every package.json and any other input files in the data attribute of npm_translate_lock. This tells Bazel which files to watch so it knows when to re-run pnpm. In smaller projects, this list may be short and easy to maintain, but in larger monorepos, it’s easy to forget to add a new file. When that happens, Bazel won’t know to re-run pnpm, which can lead to hard-to-debug staleness issues. See pnpm and rules.js and the npm_translate_lock reference for full details. API reference: npm extensions | npm rules Troubleshooting: rules_js troubleshooting | FAQ

Node.js programs

The js_library, js_binary, and js_run_binary rules let you build, test, and run JavaScript programs under Bazel. Bazel provides a hermetic Node.js toolchain so builds aren’t affected by whatever version of Node is on a developer’s machine. API reference: JavaScript rules

Protocol Buffers & gRPC

rules_js includes experimental support for generating JavaScript and TypeScript code from .proto files which are referenced in proto_library targets.
  1. Bring your own protoc plugin, such as @bufbuild/protoc-gen-es
  2. Configure it with a js_proto_toolchain
  3. Reference proto_library targets anywhere a js_library can appear. Bazel invokes the code generator automatically.
API reference: Protocol Buffer rules

Frameworks & ecosystem

Bazel works with the JavaScript tools you already use. Here are some of the integrations available: For more working examples, see the Bazel examples repository.