One compiler, three implementations
@shadow-js/compiler is one package that holds the same compiler three times and uses the fastest one the machine has: a Rust addon, the same Rust code as WebAssembly,…
@shadow-js/compiler is one package that holds the same compiler three times and uses the fastest one the machine has: a Rust
addon, the same Rust code as WebAssembly, and the TypeScript implementation. Code, source map and errors are identical (the package
replays thousands of recorded cases against the TypeScript implementation in its tests), so nothing in your project depends on which
one runs. The Rust addon is about ten times faster on large apps: 1,000 components compile in 0.16 s instead of 1.7 s, and 200 modules
compile in 70 ms on all cores with compileAsync. It speeds up cold builds and CI; a dev server compiles one file at a time and is
limited by other work, so you will not see a difference there.
npm install --save-dev @shadow-js/compiler
npm installs the prebuilt addon for your platform (macOS, Linux with glibc or musl, and Windows, on x64 and arm64) as an optional
dependency, and the package falls back to its WebAssembly build, then to the TypeScript implementation. getBackend() tells which one
runs and why a faster one did not. A browser or a worker gets the TypeScript implementation alone, through the package conditions (or
@shadow-js/compiler/javascript), with no loader in the bundle.
The Vite plugin uses the package as it is (compiler: "auto", the default). One option asks for a particular behavior:
import shadow from "@shadow-js/vite";
import { defineConfig } from "vite";
export default defineConfig({
// "auto" (default): the fastest implementation available; "native": fail unless the Rust or WebAssembly build loads;
// "javascript": the TypeScript implementation only, for example to compare outputs.
plugins: [shadow({ compiler: "auto" })],
});
A module compiled with compiler plugins is handed to the TypeScript implementation, because plugins are JavaScript; the result is the
same, only the speed differs. The environment variable SHADOW_COMPILER_BACKEND (auto, native, wasm, javascript) asks for one
for the whole process. The numbers, the method and the competitors (Babel with the Solid preset, oxc-transform) are in the package
README.