ncad is an experimental CAD server and TypeScript playground for building geometry through a small, scriptable API.
The project is centered around analytic sketch geometry: points, planes, curves, composite curves, offsets, joins, sections, and high-level solid operations. The server owns geometry and OpenCascade execution; the TypeScript SDK gives scripts a document/object handle API instead of raw HTTP calls.
server/ FastAPI CAD server backed by OpenCascade
playground/ Browser playground with Monaco editor and 3D viewer
The reusable TypeScript SDK lives in the separate
cad-kitchen/ncad-ts-sdk
repository. This repository expects the SDK checkout next to it when
regenerating OpenAPI bindings:
cadki/
├── ncad/
└── ncad-ts-sdk/
- Conda or micromamba for the Python/OpenCascade server environment.
- Bun for the TypeScript playground.
- Docker is optional; the server also has Docker targets.
First-time setup:
make installRun the server and playground together:
make devThe server listens on http://localhost:8080. Swagger UI is available at http://localhost:8080/docs. The playground runs at the Vite URL, usually http://localhost:5173.
You can also run them in separate terminals:
make server-dev
make client-devThe playground loads local TypeScript examples from
playground/public/scripts/. Scripts run against a live document and the
viewer renders the resulting scene.glb.
The VS Code remote viewer lives in the sibling ../ncad-vscode-viewer
repository and connects to this server by host:port.
Run tests and type checks:
make testRegenerate the TypeScript OpenAPI bindings after server schema changes:
make gen-apiCheck and build the client:
make buildTypical playground scripts use the SDK document handle:
const circle = await document.circle([0, 0, 0], [0, 0, 1], 50);
const point = await circle.pointAt(Math.PI / 2);
const tangent = await circle.tangentAt(Math.PI / 2);
const offset = await circle.offset(10);
await offset.setVisual({ color: [0, 0, 0] });For paths, scripts can build declarative composite curves:
const axis = await document.path()
.startAt([0, 0, 0])
.lineTo([100, 0, 0])
.arcTo([100, 40, 0], { via: [120, 20, 0] })
.build();
const solid = await axis.pipe(10, { keepAxis: true });For solid normalization, scripts can fuse caller-selected solids through OCC and optionally split disconnected results into components:
const fused = await document.fuseMany(importedSolids, { tolerance: 0.01 });
const components = await document.fuseMany(importedSolids, {
tolerance: 0.01,
splitComponents: true,
});
const exploded = await document.explodeComponents(fused);The lower-level generated client remains available in the SDK, but scripts should prefer the document/object handle API.
- Server setup and runtime notes are documented in
server/README.md. - Playground-specific setup is documented in
playground/README.md.
The original ncad source code is licensed under the MIT License. See
LICENSE.
Third-party code and runtime dependencies keep their own licenses. In particular, Open CASCADE Technology and pythonocc-core are not relicensed by this repository.