Skip to content

Compatibility Matrix

What's tested, what works, what to avoid. brepjs targets modern browsers, Node 24+, and any reasonable WASM-capable runtime. Server-side rendering is unsupported — brepjs requires WASM to execute.

Node.js

VersionStatus
24.x✓ Supported, CI tested
22.x✓ Likely works (no test gate)
20.x✓ Likely works (no test gate); uses fewer features
18.x✗ End of life — not tested
< 18✗ Unsupported

CI runs on Node 24. Anything with first-class WASM and ESM support should work; the version floor is dictated by Vitest's requirements rather than brepjs's.

Browsers

BrowserMinimum version
Chrome113
Firefox113
Safari16.4
Edge113

The version floors are set by Resource Detector / WebAssembly.Memory features and ECMAScript 2022 syntax in the bundles. Older browsers may work for some operations but are not tested.

For mobile:

Mobile browserStatus
iOS Safari 16.4+
Chrome Android (latest)
Samsung Internet

WASM performance on mobile is slower than desktop; CAD-quality rendering at 60 fps is challenging on lower-end devices.

TypeScript

VersionWhat changes
5.9+Recommended. using works, branded types fully strict.
5.2+using works. Some narrowing in newer brepjs versions may need a workaround.
5.0+No using. Use DisposalScope instead.
< 5.0✗ Branded type defaults assume features that landed in 5.0.

Strict mode ("strict": true in tsconfig.json) is required. Specifically:

  • strictNullChecks — enabled
  • noUncheckedIndexedAccess — recommended; brepjs uses it internally
  • exactOptionalPropertyTypes — recommended

Frameworks (tested)

FrameworkStatus
Vite✓ First-class — the brepjs playground uses Vite
React + R3F✓ Documented integration
Next.js (app router)✓ With 'use client' and dynamic import
Next.js (pages router)✓ With dynamic({ ssr: false })
Astro✓ With client:only
Nuxt 3✓ With <ClientOnly>
SvelteKit✓ With onMount and if (browser)
Remix✓ With useEffect deferred import
webpack 5✓ With experiments.asyncWebAssembly
webpack 4✗ Unsupported — no async WASM

See Vite, Next.js, Astro for per-framework recipes.

Server runtimes

RuntimeStatus
Cloudflare Workers✓ For batch operations; respect memory limits
Vercel Edge Functions✓ For batch operations
Deno⚠ Likely works but untested
Bun⚠ Likely works but untested
Cloudflare Durable Objects⚠ WASM should work but untested

For server-side STEP generation, edge compute is fine for one-off conversions but not for sustained workloads (memory pressure on every cold start).

Server-side rendering: NOT SUPPORTED

brepjs requires WASM to execute. SSR frameworks render on the server, where instantiating the WASM module is possible but operating on shapes is not — the kernel mutates state, including state that's tied to a particular browser-like execution context.

The supported pattern is client-only rendering — wrap brepjs-using components in dynamic({ ssr: false }) (Next.js), <ClientOnly> (Nuxt), client:only (Astro), or equivalent.

Bundle size

ResourceCompressed
brepjs (JS, gzipped)~80 KB
brepjs-opencascade WASM~3.2 MB
brepkit-wasm WASM~2.4 MB

The WASM is the dominant cost. brepjs is treeshakeable per sub-path — importing only brepjs/measurement skips the topology bundle.

What's not supported

These are intentional non-goals:

  • Headless rendering on a server for image generation. Pre-render via puppeteer at build time instead.
  • WebGPU compute for kernel operations. The kernel is C++ / Rust to WASM; WebGPU isn't on the roadmap.
  • Multiple concurrent kernels in the same context. Use withKernel to switch the active kernel; do not run two kernels in parallel inside one tab.
  • Pre-Emscripten WASM runtimes. brepjs-opencascade is built with Emscripten; runtimes that don't support Emscripten's Module interface (rare) won't work.

Specific known issues

iOS Safari 16.4 first-paint

iOS Safari sometimes delays paint while the WASM module compiles in the background. Visible as a "blank canvas for 2 seconds" on first load. Mitigations:

  • Show an explicit loading indicator (use the manual init path).
  • Compress the WASM via brotli at the CDN.

Cloudflare Workers memory

The default 128 MB cap is fine for simple CAD operations but tight for STEP imports. Bump to 256 MB+ via paid Workers if you import third-party STEP routinely.

Threaded WASM

The threaded build (brepjs-opencascade-threaded, optional) requires Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. The default brepjs-opencascade is single-threaded and doesn't need these headers.

Reporting compatibility issues

If brepjs fails on a tested platform, file a bug at github.com/andymai/brepjs/issues with:

  • Platform / version
  • A minimal repro (ideally a playground link)
  • The error message and stack trace

If it fails on an untested platform, please first confirm the runtime supports WASM 1.0+ and ESM modules — those are the only platform requirements.

Next steps

Released under the Apache 2.0 License.