Installation
Shapemetry is three kernel packages with distinct roles, plus shared types:
@huukhanhnguyen/geometry— COMPUTE. The Rust/WASM geometry kernel: namespace functions (Brep.*,Mesh.*,NurbsCurve.*,Path2d.*, …) in, numbers and JSON documents out. No classes, no scene graph.@huukhanhnguyen/io— FORMATS. File readers/writers for STEP, IGES, STL, OBJ, PLY, glTF, USD, DXF, SVG, PDF. Lazy-loaded Rust/wasm.@huukhanhnguyen/model— RUNTIME. The parametric engine: aModelJSONdocument of lanes and operations, evaluated against a node registry into scene entities.
Supporting: @huukhanhnguyen/types (shared type contracts — declarations only, no runtime). See Concepts: B-Rep documents for how the pieces pass data around.
Install
Packages are published to GitHub Packages under @huukhanhnguyen/*.
pnpm add @huukhanhnguyen/geometry
# add the tiers you need:
pnpm add @huukhanhnguyen/io @huukhanhnguyen/modelEverything a first project needs is the geometry kernel:
import { Brep } from '@huukhanhnguyen/geometry'
const box = Brep.box(100, 100, 100)
console.log(Brep.volume(box, Brep.measurementDefaultEps())) // 1_000_000Entity guards live on the model package. File readers/writers live on @huukhanhnguyen/io and load their wasm on first door call:
import { entityTypeOf, isShell } from '@huukhanhnguyen/model'
import { readStep, writeStl } from '@huukhanhnguyen/io'Node: the wasm flag
In Node, loading the geometry kernel requires the ESM wasm integration flag — the same flag the package's own pnpm smoke script uses:
node --experimental-wasm-modules your-script.mjs
# tsx / vitest users:
NODE_OPTIONS=--experimental-wasm-modules tsx your-script.tsBundlers (Vite / webpack)
The browser build is a wasm-pack bundler target: it imports the .wasm module directly with a top-level-await init. Stock Vite rejects that ("ESM integration proposal for Wasm is not supported"), so add two plugins and an esnext target — this is the exact setup the examples app uses (apps/examples/vite.config.ts):
// vite.config.ts
import { defineConfig } from 'vite'
import wasm from 'vite-plugin-wasm'
import topLevelAwait from 'vite-plugin-top-level-await'
export default defineConfig({
plugins: [wasm(), topLevelAwait()],
build: { target: 'esnext' },
optimizeDeps: {
exclude: ['@huukhanhnguyen/geometry', '@huukhanhnguyen/geometry-wasm'],
},
})For webpack, enable async wasm experiments (experiments: { asyncWebAssembly: true, topLevelAwait: true }) and target an ES2022+ environment.
Where next
- Quickstart: your first solid — box → measure → tessellate → render in three.js.
- Quickstart: your first parametric model —
ModelJSON→ evaluate → entities. - Concepts: units and tolerances — Z-up, unit-agnostic numbers, eps conventions.
- Reference: geometry package — the generated API surface of the kernel namespaces.