[]previous and next page

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,…

For agentsUpdated

@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.

sh
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:

vite.config.tsts
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.