A port of the OpenCascade CAD library to JavaScript and WebAssembly via Emscripten.
Explore the docs »
Issues
·
Get help
| I want to… | Go to |
|---|---|
Use OCCT from JS or TS (npm install, ESM init) |
Quickstart (npm) |
| Build a custom WASM (trim symbols, add C++, CI) | Quickstart (custom build) |
| See what changed in v3 (OCCT V8, ESM-only, exceptions) | What's New in v3 · BREAKING_CHANGES.md |
Configure the build (defineBuild, settings, variants) |
Config reference |
| Build OCCT WASM from source (maintainers/contributors) | MAINTAINER.md |
| Contribute or report an issue | Contributing · Issues |
libcascade brings the OpenCASCADE Technology kernel to JavaScript and
WebAssembly. Its source is maintained in
taucad/opencascade.js; it is not
an official Open CASCADE Technology distribution.
pnpm add libcascade
# or: npm install libcascadeThe package is ESM-only. The root export is an initialised instance (every
bound symbol is also a named value export); libcascade/init exposes the
shared selector, while libcascade/single/init and libcascade/multi/init
expose fixed-variant initializers. The WASM resolves automatically — use
locateFile only when a bundler or deployment relocates the binary, through
the matching libcascade/<variant>/wasm subpath and no dist/... deep imports.
Build-time tools can consume the deterministic API-reference feed through
libcascade/api-reference.json. It includes the parsed class/member hierarchy, the
full source commit, build provenance, and exact input hashes; site-specific
routes and search indexes remain consumer-derived.
import oc from 'libcascade';
using box = new oc.BRepPrimAPI_MakeBox(10, 10, 10);
const shape = box.Shape();The root entry selects the variant this host supports and initialises it at import time. Use a fixed initializer when you need options for a known variant:
// Vite / browser, with a relocated wasm asset
import { createInstance } from 'libcascade/single/init';
import wasmUrl from 'libcascade/single/wasm?url';
const oc = await createInstance({ locateFile: () => wasmUrl });The published tarball ships dist/opencascade_single.{wasm,js} and dist/opencascade_multi.{wasm,js}, each with a provenance.json sidecar describing the exact toolchain and source commits used. Both variants share the assembled types.d.ts/variant.d.ts surface; their raw per-variant glue declarations remain build inputs and are not published, while the exact init.single.d.ts and init.multi.d.ts contracts do ship. The eager root selects the most capable variant the host supports; import libcascade/single/init or libcascade/multi/init when the variant is fixed. npm releases are produced by GitHub OIDC Trusted Publishing and include Sigstore provenance; see the maintainer release flow.
For batch meshing, boolean grids, and STEP→glTF pipelines that benefit from OCCT's internal thread pool, request the pthread-enabled variant explicitly:
import { createInstance } from 'libcascade/multi/init';
const oc = await createInstance();
// Run once after init — flip OCCT global parallel defaults.
oc.BOPAlgo_Options.SetParallelMode(true); // booleans fan out by default
oc.BRepMesh_IncrementalMesh.SetParallelDefault(true); // meshing fan out by defaultcreateInstance owns the pthread plumbing (worker script self-reference, Node
path conversion, OCCT thread-pool sizing). Under Vite, set
worker: { format: 'es' } — Emscripten's workers are ES modules.
Browsers require Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp on every page that loads the threaded wasm. See the multi-threaded build guide for activation, benchmarks, and when not to ship threaded; toolchain custom-build covers the config recipe for trimmed MT variants.
Need a trimmed binary, your own C++ wrappers, or different Emscripten settings?
@libcascade/toolchain is the dev-time package for that. It drives the
published Docker images for you — digest-pinned, with the platform edges
handled — so there is no docker run string to maintain. Docker (or another
supported container engine) must be installed and running before build.
npm install --save-dev @libcascade/toolchain// libcascade.config.ts
import { defineBuild } from '@libcascade/toolchain';
export default defineBuild({
name: 'myapp',
bindings: ['BRepPrimAPI_MakeBox', 'TopoDS_Shape', 'gp_Pnt'],
settings: { MODULARIZE: true, EXPORT_ES6: true, ALLOW_MEMORY_GROWTH: true },
compilerFlags: { optimize: 'O3', simd: true, exceptions: 'wasm', noEntry: true },
variants: [{ name: 'single' }],
});npx libcascade build # link each variant through the pinned image → dist/
npx libcascade assemble # shared types.d.ts + ./init entry + exports map
npx libcascade check src # CI drift guard: referenced symbols ⊆ bound symbolsSymbol names and -s settings are compile-checked against unions generated
from the pinned image, so a typo is a TypeScript error rather than a runtime
BindingError. See the toolchain quickstart,
the config reference,
and the migration guide
if you have an existing yml build.
Images are published to ghcr.io/taucad/opencascade.js
as multi-arch manifest lists (linux/amd64 + linux/arm64); Apple Silicon
runs natively. Building the image itself, or driving it directly, is covered in
MAINTAINER.md.
| Tag | What it points at |
|---|---|
:single-threaded |
Latest release, single-threaded warm cache (default for browser CAD UIs) |
:multi-threaded |
Latest release, multi-threaded warm cache (requires COOP/COEP) |
:bindgen-base |
Latest release, post-PCH/generate but pre-compile (custom-bindings starting point) |
:<version>-<stage> |
Pinned release for single-threaded, multi-threaded, or bindgen-base |
:3.0.0-canary.<sha8>-<stage> |
Immutable maintainer-dispatched canary, retained for seven days |
:branch-main[-<full-sha>] |
Current or immutable main, single-threaded |
:multi-threaded-branch-main[-<full-sha>] |
Current or immutable main, multi-threaded |
:bindgen-base-branch-main[-<full-sha>] |
Current or immutable main, bindgen-base |
Docker resolves the right architecture from every published manifest list automatically — no --platform flag is needed on either linux/amd64 or linux/arm64 hosts.
- OCCT 8.0.1 — 1,085+ commits of improvements; 22-31% faster boolean operations
- Emscripten 6.0.5 — LLVM 24, modern WASM features
- Native WASM Exceptions —
-fwasm-exceptionsreplaces JS invoke trampolines; decodable end-to-end viaoc.getExceptionMessage - ESM-only distribution —
"type": "module"; the eager root selects a supported variant,libcascade/initis the shared lazy selector, and fixed lazy entries live atlibcascade/single/initandlibcascade/multi/init; raw glue remains available underlibcascade/singleandlibcascade/multi - Full TypeScript bindings — Doxygen-derived JSDoc rendered correctly in Monaco IntelliSense
- Suffix-free overloads — single symbol per class with val-based dispatcher, no more
_2/_3subclasses (measured at ~264 ns/call, <0.011% of wall time on typical CAD models — see BENCHMARKS.md) - Reproducible builds —
DEPS.jsonpins every dependency to an exact commit; per-buildprovenance.jsonsidecar - Cached, incremental builds — content-addressed compilation cache turns 10-30 minute clean builds into seconds on hit
See CHANGELOG.md for the full v3.0.0 entry. For empirical evidence of every measurable project change (wall-clock CAD perf vs native C++, multi-threading speedup, embind dispatch cost, RBV overhead), see BENCHMARKS.md.
- BREAKING_CHANGES.md — v3 consumer migration guide
- CHANGELOG.md — release notes
- BENCHMARKS.md — empirical evidence hub: wall-clock CAD perf vs native C++, multi-threading speedup, embind dispatch cost, RBV overhead
- MAINTAINER.md — native build, env vars, customization for maintainers and contributors
- Config reference — every
defineBuildfield and the generated type unions - CLI reference —
build,assemble,detect,check - BUILD_SYSTEM.md —
OCJS_*env-var matrix and configuration authoring - Emscripten settings and flags — tuning size, speed, and build time
- Trim symbols — cut the binding set to a consumer-sized build
- Extend with C++ —
customBindingsscopes - Reproducible CI — digest pinning, provenance, SBOM, lockfile discipline
- ArchiYou — Library, Code-CAD Design Tool, Community Hub
- BitByBit — Code- & node-based CAD Design Tool
- CascadeStudio — Library and Code-CAD Design Tool
- RepliCAD — Library and Code-CAD Design Tool
- Tau — AI-native CAD platform for the web
Contributions are welcome. Start with CONTRIBUTING.md, see TODO.md for the current backlog, and use MAINTAINER.md for build-from-source instructions.
See LICENSE.