# OpenGeometry: a CAD geometry kernel compiled to WebAssembly

> OpenGeometry is a browser-native CAD kernel written in Rust and compiled to WebAssembly, with a TypeScript layer that speaks to Three.js. It is the geometry layer rather than a CAD application, and the interesting part of the design is that the kernel stays deterministic while an AI agent decides what to ask it to do, so a copilot can propose modelling steps without also having to compute the booleans.

**OpenGeometry-io/OpenGeometry** — powerful cad kernel for web

- Repository: https://github.com/OpenGeometry-io/OpenGeometry
- Website: https://opengeometry.io
- Stars: 523 · Forks: 57
- Language: Rust
- License: MPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/opengeometry-io-opengeometry

## What it is, and what it is not

OpenGeometry is an open-source, browser-native CAD kernel. The geometry engine is written in Rust, compiled to WebAssembly, and paired with a Three.js-friendly TypeScript layer, so you can build real CAD tools that run in the browser.

The distinction the README insists on is between a kernel and an application. It is the geometry engine layer, not a full CAD application, and a downstream project called OpenPlans is built on top of it for AEC workflows. In this repository, OpenGeometry is the primary SDK and engine.

That distinction matters because it sets the scope of what you are adopting. A kernel gives you primitives, operations and exports, and leaves the interface, the document model and the undo history to you. A CAD application gives you a working editor and takes the design decisions away from you.

The primary language is Rust, the licence is MPL-2.0, the default branch is main, and the homepage is opengeometry.io. The recent releases show v0.0.7 from 2025-10-08, while the package manifest carries version 2.0.18, so the npm package version and the GitHub release tag are on different numbering schemes. The last push was on 2026-10-12 with the project not archived, and the README opens with a note that it is actively maintained and growing, with APIs, examples and package structure evolving.

That last sentence is the caveat to hold on to. A project whose APIs are explicitly stated to be evolving is fine for exploration and for a prototype, and less fine as the foundation of a product whose users depend on your data model.

The stated use cases are concrete: browser-based parametric modelling with Rust and WebAssembly performance, cutout subtraction and other solid boolean workflows, polygon extrusion into solids for CAD or AEC modelling, IFC, STEP, STL and PDF-style export and projection in web apps, a Three.js-friendly CAD kernel instead of ad hoc mesh maths, and a deterministic geometry engine behind AI-assisted CAD or design workflows.

## The fit list, and the case for a kernel at all

The README has a section titled Good fit, Not the right fit, and the negative half is more informative than the positive half.

The good fit list is browser CAD, mechanical design and geometry-heavy web applications, Three.js-based modeling tools that need a real kernel behind them, and AI first CAD frontends that need deterministic geometry execution in the browser.

The not the default fit list is desktop-native CAD products instead of an embeddable web SDK, non-browser runtimes with no WebAssembly or browser delivery story, and pure visualization-only apps where raw Three.js is enough and kernel-backed modeling is unnecessary.

That third point is the one to sit with. If you are building a viewer that displays a mesh, this library is not for you, and the README says so plainly. Three.js already draws triangles, and a kernel is for the operations that come before the triangles exist: the boolean between two solids, the extrusion of a profile, the offset of a curve.

The distinction also has a performance dimension that the positive half only hints at. A boolean operation between two solid meshes is a genuinely hard computational problem, and doing it well requires a real kernel rather than a library of mesh manipulation functions. A cutout subtraction, which the README lists as a use case, is exactly that kind of operation: you take a solid and remove a shaped volume from it, and the result has to be a valid solid rather than a soup of overlapping triangles.

So the case for a kernel is that some geometry operations are too hard to do approximately. If your application only needs to place shapes and move them, Three.js is the whole answer. If it needs to cut, extrude, sweep and intersect, you need something that maintains a coherent solid model, and that is what this is.

The project is also honest about the shape of its own ambition, with a note that the package is on npm and the demos run entirely client-side via WebAssembly.

## The capabilities, and what is actually in the browser today

The What you can do today table is the most concrete part of the README, and it is a five-row summary of the surface area.

Primitives are lines, arcs, curves, polylines and rectangles. Shapes are polygons, solids, cuboids, cylinders, spheres, wedges, sweeps and openings. Operations are triangulation, extrusion, sweep, offset and boolean operations. Exports are STL, STEP, IFC and PDF projection, with the note that PDF is currently native and Node-only, and browser PDF is on the roadmap. Integration covers Three.js scene management and WebAssembly-powered performance.

Two details in that table carry weight. The openings entry in the shapes row is unusual: it means the library models a hole or a cutout as a first-class shape rather than only as a boolean result, which is the kind of thing you want in a configurator where the user is placing a window in a wall. And the PDF limitation is stated rather than glossed over, and it is a genuine constraint for a browser-first product, since PDF projection is a common requirement in architecture workflows.

The exports are the other thing worth reading closely. STL is a mesh format and is the easy one. STEP and IFC are the interchange formats that mechanical and building design actually use, and producing them from a browser kernel is a real differentiator rather than a checkbox. IFC in particular is a building information model format with a substantial schema, and a library that writes it from a browser is doing something more than drawing shapes.

The demos are hosted at demos.opengeometry.io and the README lists what they cover: primitives rendering, shape generation, sweep operations, boolean operations, file exports and more, all running client-side via WebAssembly. That is the right way to evaluate a geometry library, because the operations either work or they do not and you can see for yourself.

The project also maintains a documentation site at docs.opengeometry.io, a blog, and a Discord, and the README's links section points at all of them alongside the npm package.

## Why it is designed for AI-assisted CAD

There is a whole section on why it works well for AI-powered CAD apps, and the reasoning is the part of the project that is unusual rather than the geometry itself.

The argument is that the kernel layer stays explicit and deterministic. An AI copilot or agent can suggest modeling steps, generate profiles or orchestrate edits, while OpenGeometry executes the actual geometry operations, booleans, projections and exports in a predictable browser runtime.

That is a clean separation of concerns, and it is the same argument that makes a database useful to an agent: the model decides what operation to perform, and the database performs it correctly. A geometry operation is not something a language model can reliably do in its head. A boolean between two solids with fillets on one of them is a spatial computation with a right answer, and an agent that gets it wrong produces a broken model that only shows up later as a rendering artefact.

So the agent writes the intent and the kernel writes the geometry. The three examples given are AI copilots that translate user intent into concrete modeling operations, prompt-to-geometry and agent-driven editing flows inside browser CAD tools, and AI first design interfaces that still need reliable extrusion, boolean, projection and export workflows.

The word deterministic is doing the work in that paragraph. A generative model is not reproducible, and a CAD kernel can be, so the parts of the process that have a right answer are handed to something that has one.

There is a second, more practical reason to keep the geometry out of the model, which is size. A geometry kernel that runs in WebAssembly is a compiled artefact that does the work locally, and the model only ever sees text. That is a much better arrangement than a model emitting coordinates and hoping, and it also means the expensive part of the pipeline, the actual solid modelling, happens on the user's machine rather than on a server.

The README has a dedicated section on AI and coding agent entrypoints, naming ChatGPT, Claude, Gemini, Copilot and others, and pointing at an AGENTS.md file described as a single source of truth for all coding agents covering architecture, commands, gotchas and behavioural rules. That is an unusual thing to ship, and a sensible one, since it lets an agent work on the repository without the agent having to reverse-engineer the build.

The links given are the quickstart, the installation page, a page on boolean operations and a page on the extrude operation, so an agent that has read the README has a short path to the four things most often to be needed.

## The quick start, and how the WebAssembly is loaded

Installation from npm is one command:

```bash
npm install opengeometry
```

And then the README spells out a practical browser deployment, which is worth reading in full because the WebAssembly loading step is the part that trips people up.

You install opengeometry from npm, serve opengeometry_bg.wasm from your app, then initialize the runtime once with OpenGeometry.create({ wasmURL }) before creating Vector3 values or kernel-backed wrappers.

The example shows the shape:

```ts
import { Cuboid, OpenGeometry, Vector3 } from "opengeometry";

await OpenGeometry.create({
  wasmURL: new URL(
    "node_modules/opengeometry/opengeometry_bg.wasm",
    import.meta.url
  ).href,
});

// Initialize once before constructing Vector3 or any wrapper.
const cuboid = new Cuboid({
  center: new Vector3(0, 0, 0),
  width: 2,
  height: 1,
  depth: 1,
  color: 0x33aa66,
});

// Placement is strict: scale must be positive + uniform.
cuboid.setPlacement({
  translation: new Vector3(1, 0, 0),
  rotation: new Vector3(0, 0.25, 0),
  scale: new Vector3(1.25, 1.25, 1.25),
});
```

Three things are worth pulling out of that.

The WASM file is served separately, and the example resolves it through a new URL with import.meta.url pointing into node_modules. That is a bundler-friendly way of locating the binary, and it means the wasm artefact is a separate file your application has to host, not something bundled into the JavaScript. The consequence for deployment is that the wasm file has to be served with the right content type and be fetchable, and a misconfigured static host is the usual reason the runtime fails to initialise.

The initialization is explicitly once, and the comment on the code says to initialize once before constructing Vector3 or any wrapper. So there is an ordering requirement: the runtime must be ready before you touch the typed wrappers. The example awaits OpenGeometry.create with the wasmURL, and the Cuboid construction follows it.

And the placement rules are strict, as the comment on that call says: scale must be positive and uniform. A scale of negative one would mirror the geometry, and a non-uniform one would change its shape, and a CAD kernel refuses both rather than letting a mirrored solid into the scene graph where it would render as inside-out.

The example also sets a color on the cuboid at construction time, which tells you the wrappers carry rendering attributes as well as geometry, and the placement call takes a translation, a rotation and a scale as Vector3 values, which is a conventional transform decomposition rather than a matrix.

## The repository and the build pipeline

The top-level listing shows a Rust core, a TypeScript wrapper and a set of build tooling, and the package manifest tells you the pipeline.

The scripts are the clearest description of how the project is assembled:

```json
    "dev": "vite",
    "test": "cargo test --manifest-path main/opengeometry/Cargo.toml && cargo test --examples --manifest-path main/opengeometry/Cargo.toml",
    "test:wrapper": "node --test main/opengeometry-three/tests/*.test.mjs",
    "lint": "eslint main/opengeometry-three/src/**/*.ts --fix",
    "lint:check": "eslint main/opengeometry-three/src/**/*.ts",
    "clean-dist": "node ./scripts/clean-dist.mjs",
    "build-three": "npm run clean-dist && rollup -c rollup.config.js",
    "build-example-three": "npm --prefix main/opengeometry-three run build-example-three",
    "build-core": "cd main/opengeometry && wasm-pack build --target web && cargo build --release",
    "prepare-dist": "node ./scripts/prepare-dist.mjs",
    "copy-wasm": "npm run prepare-dist",
    "build": "npm run build-core && npm run build-three && npm run prepare-dist"
```

So the test script runs two cargo test invocations against the Rust manifest in main/opengeometry, one for the unit tests and one for the examples, and there is a separate test:wrapper script running the Node test runner over the TypeScript wrapper tests. The lint script covers the TypeScript source under main/opengeometry-three/src, with a lint:check variant that does not fix, so the two can serve as a local check and a CI check.

The build splits into three parts. build-core runs wasm-pack build with the web target and then a release cargo build, which produces the WebAssembly artefact and the native build. build-three cleans the dist directory and runs Rollup with the rollup.config.js at the root, which bundles the TypeScript layer. And prepare-dist runs a Node script that assembles the distribution, with copy-wasm as an alias for it. The build script chains all three in order.

So the toolchain is wasm-pack for the Rust to WebAssembly step, Rollup for the TypeScript bundle, Cargo for the tests and the native build, and Node's own test runner for the wrapper. The presence of wasm-pack with the web target is what produces the separate .wasm file the quick start tells you to serve.

The top-level listing also shows main/, docs/, scripts/, a .claude/ directory, a .vscode/ directory, an eslint.config.js, a vite.config.js, a tsconfig.json and a rollup.config.js, plus developer.md and release.md at the root. The developer document is the one to read if you want to contribute, and the release document is the one to read if you want to understand how a version is cut, since the GitHub release tag and the npm version are numbered differently.

Two dependency details in the manifest are worth noting. The peer dependency is three at 0.168.0 or newer, which confirms the Three.js coupling is a peer relationship rather than a bundled one, so your application controls the Three.js version. The one runtime dependency is uuid at 10.0.0 or newer, which appears to be for identifying entities in a scene, and the fact that a geometry kernel needs a UUID library at all is a hint that the wrapper carries some identity concept rather than being purely about shapes.

## How to evaluate it, and what to check first

There are five things to consider, and the first is that this is an early-stage project with an explicit warning about it.

The README says the APIs, examples and package structure are evolving, and the GitHub release history has one tagged release while the npm version is 2.0.18, which tells you the two numbering schemes have not converged. For an evaluation, that means you should plan on reading the documentation rather than an API reference with stability guarantees, and you should expect to touch the integration when the package moves.

Second, whether the WebAssembly delivery story works in your deployment. The kernel is a separate .wasm file that you host and fetch, the runtime must be initialised before any wrapper is constructed, and the PDF export is Node-only for now. If your application is a browser app with a static host, that is workable, but it is a real integration with the build, and the failure mode of a misconfigured content type is a runtime that refuses to start rather than a clear error.

Third, the actual geometry quality. Booleans, sweeps, offsets and exports are the operations where kernels differ, and the demos are the way to check them. Run the boolean and sweep demos, export something, and look at the result, because the difference between a kernel that handles a filleted cutout and one that produces broken triangles is invisible in the feature list.

Fourth, the AI angle, which is the project's stated reason for existing and is worth taking seriously. The argument that the agent should propose operations and the kernel should execute them is sound, and it means you would be building an interface where a language model emits structured modelling operations rather than coordinates. If that is the shape of your product, this library is aimed at you. If you are building a plain editor with no model in it, the AI framing is irrelevant and you should judge it purely on geometry.

Fifth, what you are not getting. This is a kernel, not an application, so there is no document model, no parametric feature tree, no constraint solver and no UI. The layer above is your problem, and OpenPlans is one team's answer to it rather than a component you can drop in.

What you get is a Rust geometry engine in the browser with a real Three.js-facing wrapper, an export path that includes STEP and IFC, and a documented division of labour that makes an agent-driven CAD front end a plausible build rather than a research project. The costs are the maturity of the package surface, the wasm hosting requirement, and the fact that you build the application on top of the kernel yourself.

## Conclusion

Adopt OpenGeometry if you are building a browser-based CAD tool that needs real solid modelling rather than mesh placement, and you want the kernel in Rust compiled to WebAssembly with a TypeScript layer that speaks to Three.js. Do not adopt it for a viewer that only draws existing geometry, since the README says plainly that raw Three.js is enough in that case, and do not treat the API surface as settled, because the package is explicitly described as evolving and its GitHub release tags and npm versions are numbered differently. Before you commit, run the boolean and sweep demos and export a file yourself, since that is where kernels differ and the feature list will not tell you, plan your hosting for the separate opengeometry_bg.wasm file and remember that PDF export is Node-only for now, and read the developer document before contributing, since the build runs wasm-pack, Rollup and Cargo in sequence.

## FAQ

### What is OpenGeometry?

It is an open-source, browser-native CAD kernel. The geometry engine is written in Rust, compiled to WebAssembly, and paired with a Three.js-friendly TypeScript layer so CAD tools can be built that run in the browser. It is the geometry engine layer rather than a full CAD application, and it is MPL-2.0 licensed with the homepage at opengeometry.io.

### What can OpenGeometry actually do?

Primitives covering lines, arcs, curves, polylines and rectangles; shapes covering polygons, solids, cuboids, cylinders, spheres, wedges, sweeps and openings; operations covering triangulation, extrusion, sweep, offset and boolean operations; and exports to STL, STEP, IFC and PDF projection, where PDF is currently native and Node-only with browser PDF on the roadmap.

### How do I install and initialise OpenGeometry?

Run npm install opengeometry, then serve opengeometry_bg.wasm from your application and initialise the runtime once with OpenGeometry.create({ wasmURL }) before constructing Vector3 values or kernel-backed wrappers. The package declares three at 0.168.0 or newer as a peer dependency and uuid as its runtime dependency.

### Why is OpenGeometry suited to AI-assisted CAD?

Because the kernel layer stays explicit and deterministic while the model decides what to do. An agent can suggest modelling steps, generate profiles or orchestrate edits, while OpenGeometry executes the actual geometry operations, booleans, projections and exports in a predictable browser runtime. The repository also ships an AGENTS.md described as a single source of truth for coding agents.

### When is OpenGeometry not the right choice?

For desktop-native CAD products instead of an embeddable web SDK, for non-browser runtimes with no WebAssembly delivery story, and for pure visualisation-only apps where raw Three.js is enough and kernel-backed modeling is unnecessary. It is also an early project whose APIs and package structure are explicitly stated to be evolving.

## Sources

- [License: MPL-2.0](https://github.com/OpenGeometry-io/OpenGeometry/blob/main/LICENSE)
- [OpenGeometry-io/OpenGeometry on GitHub](https://github.com/OpenGeometry-io/OpenGeometry)
- [Project website](https://opengeometry.io)
- [README](https://github.com/OpenGeometry-io/OpenGeometry/blob/main/README.md)
- [Releases](https://github.com/OpenGeometry-io/OpenGeometry/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/opengeometry-io-opengeometry
