For browser apps (React, bundling, dev servers), see Web Apps.
Component testing with
vitest_test is covered at the end of this page.
Set up the toolchain
Declare the Node.js toolchain once in your workspace’sWORKSPACE.rbs:
22.15.1 (default), 22.11.0, 20.19.6, 20.11.0, and
18.19.0.
Declare npm dependencies
rbs resolves npm packages itself, directly from the npm registry — there is nopackage.json, no npm install, and no npm/yarn CLI involved. Each package your
workspace uses is declared in WORKSPACE.rbs:
version is usually an exact pin, but semver ranges ("^4.18.0") and "latest"
also work — exact pins are recommended for reproducibility.
To declare several packages at once:
The lockfile
The first resolution writesrbs.lock at the workspace root, pinning every resolved
package (including transitives). Later builds resolve instantly from the lockfile instead
of hitting the registry.
Referencing dependencies from targets
In aBUILD.rbs file, a target’s deps can reference npm packages two ways:
@external://package:version form is
explicit about the version at the point of use; the :name_repo form points back at the
nodejs_repository declaration.
When a target runs, your code sees an ordinary
node_modules directory and imports resolve
exactly as in any Node.js project — rbs stages and shares the packages behind the scenes.nodejs_binary
Builds a runnable Node.js program with a hermetic launcher: the target carries its own Node.js toolchain and dependencies, sorbs run works on any machine with no setup.
Attributes
nodejs_library
Groups sources into a reusable unit. Libraries record their own npm dependencies, and any binary or test that depends on the library gets those packages automatically.Attributes
TypeScript
TypeScript works out of the box in all three rules: whensrcs contain .ts or .tsx
files, rbs compiles them with tsc before staging. The only requirement is that the
workspace declares the typescript package as a host dependency:
ES2020 with CommonJS modules, strict mode, and
esModuleInterop enabled. Override individual options per target:
tsconfig = "tsconfig.json".
rbs also generates a TypeScript configuration for your editor (under
.rbs/lsp/) so
imports of npm packages and workspace libraries resolve in the IDE without any manual
setup. This file is regenerated by builds — treat it as read-only. If you need different
compiler behavior, set ts_compiler_options or tsconfig on the target rather than
editing generated files.Testing with nodejs_test
nodejs_test runs your tests with one of two runners:
jest(default) — real Jest:describe/it/expectsuites, with Jest-collected coverage.node— plain Node.js: the test file is a self-executing script (e.g. usingassert) that exits non-zero on failure; coverage is collected with NYC (Istanbul).
WORKSPACE.rbs:
Coverage gates
Set minimum coverage thresholds on the target and enforce them withrbs coverage — the
run fails if any metric drops below its threshold:
Attributes
Component testing with vitest_test
For React/DOM component tests, usevitest_test from the web-vite ruleset. It runs real
Vitest with a jsdom environment by default, transforms TS/TSX with Vitest’s own pipeline
(no separate compile step), and collects V8 lcov coverage.
Install its dependencies once in WORKSPACE.rbs:
srcs must list both the test files (named *.test.* or
*.spec.*) and the sources they exercise:
@testing-library/react v16 requires @testing-library/dom as a peer dependency — list
it explicitly in deps, as above.Attributes
To test components that import a shared workspace library, declare the library under the
same import scope the app rules use:
import { Button } from '@acme/ui' just like the application code
does. See Web Apps for how libraries and apps are wired together.