{"id":28146455,"url":"https://github.com/aspect-build/rules_js","last_synced_at":"2026-01-31T01:23:42.383Z","repository":{"id":37020565,"uuid":"422379561","full_name":"aspect-build/rules_js","owner":"aspect-build","description":"High-performance Bazel rules for running Node.js tools and building JavaScript projects","archived":false,"fork":false,"pushed_at":"2026-01-20T07:33:00.000Z","size":27886,"stargazers_count":359,"open_issues_count":200,"forks_count":158,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-01-20T09:11:10.851Z","etag":null,"topics":["bazel","bazel-rules"],"latest_commit_sha":null,"homepage":"","language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aspect-build.png","metadata":{"funding":{"github":null,"patreon":null,"open_collective":"aspect-build","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null},"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-28T23:05:47.000Z","updated_at":"2026-01-20T07:16:54.000Z","dependencies_parsed_at":"2023-09-28T10:10:28.860Z","dependency_job_id":"81bbc18c-bca3-4396-80ae-22f14529ef2d","html_url":"https://github.com/aspect-build/rules_js","commit_stats":{"total_commits":1350,"total_committers":63,"mean_commits":"21.428571428571427","dds":0.585925925925926,"last_synced_commit":"63b25346d669fdee13e75fe1f09ea83263b64556"},"previous_names":[],"tags_count":192,"template":false,"template_full_name":null,"purl":"pkg:github/aspect-build/rules_js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Frules_js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Frules_js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Frules_js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Frules_js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aspect-build","download_url":"https://codeload.github.com/aspect-build/rules_js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Frules_js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28642697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","bazel-rules"],"created_at":"2025-05-14T23:12:36.333Z","updated_at":"2026-01-31T01:23:42.370Z","avatar_url":"https://github.com/aspect-build.png","language":"Starlark","funding_links":["https://opencollective.com/aspect-build"],"categories":["Starlark"],"sub_categories":[],"readme":"# Bazel rules for JavaScript\n\nThis ruleset is a high-performance Bazel integration for JavaScript, based on the [pnpm package manager](https://pnpm.io).\n\n-   Lazy: only fetches/installs npm packages needed for the requested build/test targets.\n-   Correct: works seamlessly with node.js module resolution. For example there are no pathMapping issues with TypeScript `rootDirs`.\n-   Fast: Bazel's sandbox only sees npm packages as directories, not individual files.\n    \u003chttps://blog.aspect.build/rulesjs-npm-benchmarks\u003e shows benchmarks for fetching, installing, and linking packages under rules_js as well as typical alternatives like npm and yarn.\n-   Supports npm \"workspaces\": nested npm packages in a monorepo.\n\nMany companies are successfully building with rules_js. If you're getting value from the project, please let us know! Just comment on our [Adoption Discussion](https://github.com/aspect-build/rules_js/discussions/1000).\n\n## Getting started\n\nThe fastest way to try this in an empty project is to click the green \"Use this template\" button on https://github.com/bazel-starters/js.\n\n## More from Aspect\n\nrules_js is just a part Aspect's monorepo developer platform:\n\n-   [Aspect Workflows](https://docs.aspect.build/workflows) delivers on Bazel's promises of speed and cost-savings.\n    It provides Continuous Integration and Delivery, including Remote Cache and Remote Build Execution (RBE).\n    Best of all, it includes all the expertise that you expect from the team at Aspect!\n-   _Need help?_\n    -   Best-effort community support is available on the #javascript channel on [Bazel Slack](https://slack.bazel.build/)\n    -   Commercial support as a Slack Connect channel is offered by https://aspect.build/services.\n-   See [Aspect's Bazel rules](https://docs.aspect.build/rules), especially those built for rules_js:\n    -   [rules_ts](https://github.com/aspect-build/rules_ts) - Bazel rules for [TypeScript](http://typescriptlang.org)\n    -   [rules_swc](https://github.com/aspect-build/rules_swc) - Bazel rules for [swc](https://swc.rs)\n    -   [rules_jest](https://github.com/aspect-build/rules_jest) - Bazel rules to run tests using [Jest](https://jestjs.io)\n    -   [rules_esbuild](https://github.com/aspect-build/rules_esbuild) - Bazel rules for [esbuild](https://esbuild.github.io) JS bundler\n    -   [rules_webpack](https://github.com/aspect-build/rules_webpack) - Bazel rules for [Webpack](https://webpack.js.org)\n    -   [rules_rollup](https://github.com/aspect-build/rules_rollup) - Bazel rules for [Rollup](https://rollupjs.org) - a JavaScript bundler\n    -   [rules_jasmine](https://github.com/aspect-build/rules_jasmine) - Bazel rules to run tests using [Jasmine](https://jasmine.github.io/)\n    -   [rules_terser](https://github.com/aspect-build/rules_terser) - Bazel rules for [Terser](https://terser.org) - a JavaScript minifier\n    -   [rules_cypress](https://github.com/aspect-build/rules_cypress) - Bazel rules to run tests using [Cypress](https://cypress.io)\n    -   [rules_lint](https://github.com/aspect-build/rules_lint) includes [eslint support](https://registry.bazel.build/docs/aspect_rules_lint#lint-eslint-bzl).\n\n## Known issues\n\n-   ESM imports escape the runfiles tree and the sandbox due to https://github.com/aspect-build/rules_js/issues/362\n\n## Installation\n\nFollow instructions from the release you wish to use:\n\u003chttps://github.com/aspect-build/rules_js/releases\u003e.\n\n## Usage\n\nSee the documentation in the [docs](docs/) folder and generated API docs at https://registry.bazel.build/docs/aspect_rules_js.\n\n## Examples\n\nBasic usage examples can be found under the [examples](https://github.com/aspect-build/rules_js/tree/main/examples) folder.\n\n\u003e Note that the examples also rely on code in the `/MODULE` file in the root of this repo.\n\nThe [e2e](https://github.com/aspect-build/rules_js/tree/main/e2e) folder also has a few useful examples such as [js_image_layer](https://github.com/aspect-build/rules_js/tree/main/e2e/js_image_oci) for containerizing a js_binary and [js_run_devserver](https://github.com/aspect-build/rules_js/tree/main/e2e/js_run_devserver), a generic rule for running a devserver in watch mode with [ibazel](https://github.com/bazelbuild/bazel-watcher).\n\nLarger examples can be found in our [bazel-examples](https://github.com/aspect-build/bazel-examples) repository including:\n\n-   [Next.js](https://github.com/aspect-build/bazel-examples/tree/main/next.js) / [rules_ts](https://github.com/aspect-build/rules_ts)\n-   [Angular (cli/architect)](https://github.com/aspect-build/bazel-examples/tree/main/angular)\n-   [Angular (ngc)](https://github.com/aspect-build/bazel-examples/tree/main/angular-ngc) / [rules_ts](https://github.com/aspect-build/rules_ts)\n-   [React (create-react-app)](https://github.com/aspect-build/bazel-examples/tree/main/react-cra)\n-   [Vue](https://github.com/aspect-build/bazel-examples/tree/main/vue)\n-   [Jest](https://github.com/aspect-build/bazel-examples/tree/main/jest) / [rules_jest](https://github.com/aspect-build/rules_jest)\n-   [NestJS](https://github.com/aspect-build/bazel-examples/tree/main/nestjs) / [rules_ts](https://github.com/aspect-build/rules_ts), [rules_swc](https://github.com/aspect-build/rules_swc)\n\n## Relationship to rules_nodejs\n\nrules_js is an alternative to the `build_bazel_rules_nodejs` Bazel module and\naccompanying npm packages hosted in https://github.com/bazelbuild/rules_nodejs,\nwhich is now unmaintained. All users are recommended to use rules_js instead.\n\nrules_js replaces some parts of [bazelbuild/rules_nodejs](http://github.com/bazelbuild/rules_nodejs) and re-uses other parts:\n\n| Layer                           | Legacy                        | Modern                  |\n| ------------------------------- | ----------------------------- | ----------------------- |\n| Custom rules                    | `npm:@bazel/typescript`, etc. | `aspect_rules_ts`, etc. |\n| Package manager and Basic rules | `build_bazel_rules_nodejs`    | `aspect_rules_js`       |\n| Toolchain and core providers    | `rules_nodejs`                | `rules_nodejs`          |\n\nThe common layer here is the `rules_nodejs` Bazel module, documented as the \"core\" in\nhttps://bazel-contrib.github.io/rules_nodejs/:\n\n\u003e It is currently useful for Bazel Rules developers who want to make their own JavaScript support.\n\nThat's what `rules_js` does! It's a completely different approach to making JS tooling work under Bazel.\n\nFirst, there's dependency management.\n\n-   `build_bazel_rules_nodejs` uses existing package managers by calling `npm install` or `yarn install` on a whole `package.json`.\n-   `rules_js` uses Bazel's downloader to fetch only the packages needed for the requested targets, then mimics [`pnpm`](https://pnpm.io/) to lay out a `node_modules` tree.\n\nThen, there's how a Node.js tool can be executed:\n\n-   `build_bazel_rules_nodejs` follows the Bazel idiom: sources in one folder, outputs in another.\n-   `rules_js` follows the npm idiom: sources and outputs together in a common folder.\n\nThere are trade-offs involved here, but we think the `rules_js` approach is superior for all users,\nespecially those at large scale. Read below for more in-depth discussion of the design differences\nand trade-offs you should be aware of.\nAlso see the [slides for our Bazel eXchange talk](https://hackmd.io/@aspect/rules_js)\n\n## Design\n\nThe authors of `rules_js` spent four years writing and re-writing `build_bazel_rules_nodejs`.\nWe learned a lot from that project, as well as from discussions with [Rush](https://rushjs.io/) maintainer [@octogonz](https://github.com/octogonz).\n\nThere are two core problems:\n\n-   How do you install third-party dependencies?\n-   How does a running Node.js program resolve those dependencies?\n\nAnd there's a fundamental trade-off: make it fast and deterministic, or support 100% of existing use cases.\n\nOver the years we tried a number of solutions and each end of the trade-off spectrum.\n\n### Installing third-party libraries\n\nDownloading packages should be Bazel's job. It has a full featured remote downloader, with a content-address-cached (confusingly called the \"repository cache\"). We now mirror pnpm's lock file\ninto starlark code, then use only Bazel repository rules to perform fetches and translate the\ndependency graph into Bazel's representation.\n\nFor historical context, we started thinking about this in February 2021 in a (now outdated) [design doc](https://hackmd.io/gu2Nj0TKS068LKAf8KanuA)\nand have been working through the details since then.\n\n### Running Node.js programs\n\nFundamentally, Bazel operates out of a different filesystem layout than Node.\nBazel keeps outputs in a distinct tree outside of the sources.\n\nOur first attempt was based on what Yarn PnP and Google-internal Node.js rules do:\nmonkey-patch the implementation of `require` in NodeJS itself,\nso that every resolution can be aware of the source/output tree difference.\nThe main downside to this is compatibility: many packages on npm make their own assumptions about\nhow to resolve dependencies without asking the `require` implementation, and you can't patch them all.\nUnlike Google, most of us don't want to re-write all the npm packages we use to be compatible.\n\nOur second attempt was essentially to run `npm link` before running a program, using a runtime linker.\nThis was largely successful at papering over the filesystem layout differences without disrupting\nexecution of programs. However, it required a lot of workarounds anytime a JS tool wanted to be\naware of the input and output locations on disk. For example, many tools like react-scripts (the\nbuild system used by Create React App aka. CRA) insist on writing their outputs relative to the\nworking directory. Such programs were forced to be run with Bazel's output folder as the working\ndirectory, and their sources copied to that location.\n\n`rules_js` takes a better approach, where we follow that react-scripts-prompted workaround to the\nextreme. We _always_ run JS tools with the working directory in Bazel's output tree.\nWe can use a `pnpm`-style layout tool to create a `node_modules` under `bazel-out`, and all resolutions\nnaturally work.\n\nThis third approach has trade-offs.\n\n-   The benefit is that very intractable problems like TypeScript's `rootDirs` just go away.\n    In that example, we filed https://github.com/microsoft/TypeScript/issues/37378 but it probably\n    won't be solved, so many users trip over issues.\n    Now this just works, plus results like sourcemaps look like users expect: just like they would if the tool had written outputs in the source tree.\n-   The downside is that Bazel rules/macro authors (even `genrule` authors) must re-path\n    inputs and outputs to account for the working directory under `bazel-out`,\n    and must ensure that sources are copied there first.\n    This forces users to pass a `BAZEL_BINDIR` in the environment of every node action.\n    https://github.com/bazelbuild/bazel/issues/15470 suggests a way to improve that, avoiding that imposition on users.\n\n# Telemetry \u0026 privacy policy\n\nThis ruleset collects limited usage data via [`tools_telemetry`](https://github.com/aspect-build/tools_telemetry), which is reported to Aspect Build Inc and governed by our [privacy policy](https://www.aspect.build/privacy-policy).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspect-build%2Frules_js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faspect-build%2Frules_js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspect-build%2Frules_js/lists"}