Skip to content

taucad/opencascade.js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,197 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Logo

opencascade.js

A port of the OpenCascade CAD library to JavaScript and WebAssembly via Emscripten.
Explore the docs »

Issues · Discuss

docker ghcr

Choose Your Path

I want to… Go to
Use OCCT from JS or TS (npm install, ESM init) Quickstart (npm)
Run a reproducible build (CI, Docker, custom YAML) Quickstart (Docker)
See what changed in v3 (OCCT V8, ESM-only, exceptions) What's New in v3 · BREAKING_CHANGES.md
Customize the binding set (trim YAML, add wrappers) docs/reference/yaml-schema.md
Build OCCT WASM from source (fork maintainers) MAINTAINER.md
Contribute or report an issue Contributing · Issues

Table of Contents

Quickstart (npm)

Upgrading from v2? See BREAKING_CHANGES.md for the v3 migration guide (package rename, ESM-only loading, exception decode pattern, OCCT V8 API).

pnpm add @taucad/opencascade.js@beta
# or: npm install @taucad/opencascade.js@beta

The package is ESM-only with a default-export init function. Pass locateFile so the Emscripten loader can resolve the wasm binary from your bundler's output (browser) or node_modules layout (Node). Both runtimes reach the binary through the @taucad/opencascade.js/wasm subpath export — no dist/... deep imports required.

// Node
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import init from '@taucad/opencascade.js';

const WASM_DIR = dirname(fileURLToPath(import.meta.resolve('@taucad/opencascade.js/wasm')));

const oc = await init({
  locateFile: (filename: string) => join(WASM_DIR, filename),
});

using box = new oc.BRepPrimAPI_MakeBox(10, 10, 10);
const shape = box.Shape();
// Vite / browser
import init from '@taucad/opencascade.js';
import wasmUrl from '@taucad/opencascade.js/wasm?url';

const oc = await init({ locateFile: () => wasmUrl });

The published tarball ships pre-built WASM at dist/opencascade_full.{wasm,js,d.ts} (single-threaded default) and dist/opencascade_full_multi.{wasm,js,d.ts} (multi-threaded opt-in), each with a provenance.json sidecar describing the exact toolchain and source commits used.

Multi-threaded build

For batch meshing, boolean grids, and STEP→glTF pipelines that benefit from OCCT's internal thread pool, import the pthread-enabled variant instead of the default:

// Node
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import init from '@taucad/opencascade.js/multi';

const WASM_DIR = dirname(fileURLToPath(import.meta.resolve('@taucad/opencascade.js/multi/wasm')));

const oc = await init({
  locateFile: (filename: string) => join(WASM_DIR, filename),
});

// Run once after init — flip OCCT global parallel defaults and size the thread pool.
oc.BOPAlgo_Options.SetParallelMode(true); // booleans fan out by default
oc.BRepMesh_IncrementalMesh.SetParallelDefault(true); // meshing fan out by default
const pool = oc.OSD_ThreadPool.DefaultPool(-1); // lazy-init pool to NbLogicalProcessors
pool.SetNbDefaultThreadsToLaunch(pool.NbThreads()); // let each call use all workers
// Vite / browser (requires COOP/COEP headers — see docs)
import init from '@taucad/opencascade.js/multi';
import wasmUrl from '@taucad/opencascade.js/multi/wasm?url';

const oc = await init({ locateFile: () => wasmUrl });

oc.BOPAlgo_Options.SetParallelMode(true);
oc.BRepMesh_IncrementalMesh.SetParallelDefault(true);
using pool = oc.OSD_ThreadPool.DefaultPool(-1);
pool.SetNbDefaultThreadsToLaunch(pool.NbThreads());

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 YAML recipe for trimmed MT variants.

Quickstart (Docker)

Pre-built images are published to ghcr.io/taucad/opencascade.js:

  • Release tags (v*) publish multi-arch manifest lists (linux/amd64 + linux/arm64).
  • Branch pushes publish linux/amd64-only images for fast smoke iteration.

No local build required.

docker pull ghcr.io/taucad/opencascade.js:single-threaded

# Single-mount Quickstart — outputs land next to your YAML
docker run --rm \
  -v "$(pwd):/src" \
  -u "$(id -u):$(id -g)" \
  ghcr.io/taucad/opencascade.js:single-threaded link /src/my-config.yml

For cached iterative builds (link-only reruns in ≤ 5 min), see the named-volume recipe in MAINTAINER.md. Apple Silicon runs natively from the manifest list — no --platform flag required.

The entrypoint dispatches subcommands (link, compile-bindings, compile-sources, pch, generate, apply-patches) through npx nx run ocjs:<target>. link is the end-to-end command — Nx's dependsOn graph pulls every upstream step with cache reuse, so a fresh container performs a full build and cached re-runs replay only the link. Use docker run … --help for the complete reference, or docker run … nx <args> as an escape hatch into raw Nx.

Tags

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>-single-threaded Pinned release, single-threaded (e.g. :3.0.0-single-threaded)
:<version>-multi-threaded Pinned release, multi-threaded
:<version>-bindgen-base Pinned release, bindgen-base
:branch-<slug> Branch tip, single-threaded (amd64-only, ephemeral — 7-day GHCR retention)
:multi-threaded-branch-<slug> Branch tip, multi-threaded (amd64-only, ephemeral)
:bindgen-base-branch-<slug> Branch tip, bindgen-base (amd64-only, ephemeral)

On release tags, Docker resolves the right architecture from the manifest list automatically — no --platform flag is needed on either linux/amd64 or linux/arm64 hosts.

What's New in v3

  • OCCT 8.0.0 RC5 — 1,085 commits of improvements; 22-31% faster boolean operations
  • Emscripten 5.0.1 — LLVM 17, modern WASM features
  • Native WASM Exceptions-fwasm-exceptions replaces JS invoke trampolines; decodable end-to-end via getExceptionMessage
  • ESM-only distribution"type": "module"; default export is single-threaded opencascade_full.{js,wasm,d.ts}; multi-threaded opencascade_full_multi.{js,wasm,d.ts} ships under @taucad/opencascade.js/multi and /multi/wasm
  • 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/_3 subclasses
  • Reproducible buildsDEPS.json pins every dependency to an exact commit; per-build provenance.json sidecar
  • 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.

Documentation

Projects Using opencascade.js

  • 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

Contributing

Contributions are welcome! See TODO.md for the current backlog and MAINTAINER.md for build-from-source instructions.

License

See LICENSE.

About

Port of the OpenCascade CAD library to JavaScript and WebAssembly via Emscripten.

Resources

License

LGPL-2.1, Unknown licenses found

Licenses found

LGPL-2.1
LICENSE
Unknown
LICENSE.OCCT-Exception

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 56.6%
  • TypeScript 23.1%
  • JavaScript 8.3%
  • Shell 5.9%
  • CSS 2.4%
  • HTML 1.9%
  • Other 1.8%