Skip to content
Shapemetry

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: a ModelJSON document 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/model

Everything 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_000

Entity 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.ts

Bundlers (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

Last updated: 📖 2 min readEdit on GitHub