Imported from gdsfactory/kwasm (
.agents/skills/kwasm-build-test/SKILL.md). Install upstream withnpx skills add gdsfactory/kwasm --skill kwasm-build-test. Copyright stays with the author.
Build and verify kwasm
Run commands from the repository root. Read the toolchain and testing sections of DEVELOPING.md; use justfile, package.json and .github/workflows/ci.yml for the current commands. Match verification to the changed behavior.
Choose the build
- Rust, C++, native JS libraries under
crates/kwasm/js/, or native build flags:just build. This compiles the release WASM and then packages the browser artifact. - Browser JS/HTML/CSS:
npm run buildif the release runtime matches the native source in this checkout; otherwise runjust buildfirst. Packaging cannot establish that an old WASM binary includes current Rust changes. - Python host-generation edits: run Python checks; use
just devif the packaged JS needs refreshing. It copies bytes fromdist/, without building them. - Instructions/specs only: verify links, referenced commands and formatting.
Before a native build, inspect emcc --version, node --version,
rust-toolchain.toml and git submodule status. Emscripten 6.0.4 is the tested pin.
If unavailable, locate or install/activate that version in a task-appropriate emsdk;
do not silently substitute a system compiler or change CI's pin. Temporary paths
from past sessions are not setup instructions. Report a missing prerequisite
separately from a compilation failure if it cannot be resolved in scope.
The first C++ build can take minutes and emits many vendored warnings. Preserve
the exit status and inspect the actual error, not merely the last warning.
just check can trigger a separate debug C++ build; it does not link a runtime.
Avoid clearing caches or running cargo clean as a first troubleshooting step.
Select evidence
| Change | Relevant checks |
|---|---|
| Pure Rust policy/parsing/math | just test-rust; focus on the owning crate during iteration. Layout/geometry pure tests use --no-default-features. |
| Browser modules/actions | npm run lint, npm test, npm run format:check; unit factories use the real module imports. |
| Python | uv run ruff check --no-fix, uv run ty check, just test-python. |
| UI, FFI, lifecycle, transport or shared state | Rebuild, then just test-js-browser. |
| Private ABI or worker ordering/callbacks | Also npm run test:worker. |
| Retained resources, teardown, batching or large-layout behavior | Also just test-stress and the relevant large/dense fixture cases. |
| Native changes | just lint-rust after compilation, in addition to applicable behavior tests. |
Use npm test -- tests/browser/unit/<file>.test.ts for unit iteration. Browser
cases use Node's runner, for example:
node --test --test-name-pattern='shipped standalone artifact' tests/browser/viewer.test.mjs
node --test tests/browser/upstream.test.mjs
Some nested viewer tests share setup/state: select their parent test when needed.
The full npm run test:browser includes both viewer and upstream-feature files.
Focused successes do not imply the full suite ran. After relevant checks pass,
repeat only for new changes, failures or unresolved concerns.
Browser and artifact pitfalls
- Tests read
dist/kwasm-VERSION.js; they do not rebuild. Inspect the version read by the test harness rather than assuming a filename from an old report. - Use tests/browser/client.mjs for actual
postMessage requests and fixtures.mjs for
small generated layouts. Static inputs live in
tests/fixtures/. tests/browser/reference/contains original Chromium pixels. Do not overwrite them with current output or loosen tolerances to make a failure disappear.capturePreservedUIhas explicit exclusions for the accepted upstream controls; inspect its unmodified*-with-upstream.pngcaptures too. New visual changes need behavior checks and an inspection of the actual UI.- Match viewport, theme and fixture before diagnosing pixel differences. Put
synthetic canvas clicks in explicit aspect-matched viewport bounds. A successful
readymeans initialization/initial inputs finished, not that a frame was painted. - Cross-engine commands and headed Firefox/Mesa setup are in
DEVELOPING.mdand CI. Browser launch/dependency failures precede product tests. On unsupported Linux, use an isolated launcher viaKWASM_BROWSER_EXECUTABLEif necessary; preserve system libraries and keep machine-specific paths out of the repo. - When Python distribution is affected,
just devand compare the matching files indist/andpython/kwasm/; a wheel must contain the same JS. Building a wheel is separate from publishing.just docsadditionally replaces the local preview.
Report the behavior tested, the artifact/source revision, relevant successes,
and any unrun checks. Read CI for the current commit if reporting remote results;
a prior green run is not verification of later changes. Use prek for hooks.