Skip to main content

Quickstart with WebAssembly

In this guide you build a React app that runs the ClassCAD engine in the browser, as WebAssembly, and shows a part. You need Node.js and a ClassCAD account.

The part this guide builds: a box, hollowed out, with a hole through it

1. Make an access token​

  1. Sign up on classcad.ch/account.
  2. Under Access tokens on your account, make a public access token. It starts with ccpk_.

The token is public and belongs in your page's code. It works on localhost and on the domains you register under Domains on your account.

The quickest way

Copy one of the starters, a small app that is ready to run, and put your token in its src/main.jsx:

npx degit awv-informatik/buerli-starter/packages/with-part-run#next my-buerli-app
cd my-buerli-app
npm install
npm run dev

The rest of this guide builds such an app from scratch.

2. Create the app​

Make a React app with Vite's template and add buerli to it:

npm create vite@latest my-buerli-app -- --template react
cd my-buerli-app
npm install
npm install @buerli.io/classcad@beta @buerli.io/react@beta three @react-three/fiber @react-three/drei

buerli 2.0 is in beta: the beta tag has the version this guide is written for.

3. Connect to the engine​

In src/main.jsx, add the two lines that connect buerli. init tells buerli how a drawing reaches the engine: call it once, before anything renders, with your token.

src/main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { init, WASMClient } from '@buerli.io/classcad'
import App from './App.jsx'

// A public access token from your ClassCAD account
init((drawingId) => new WASMClient(drawingId, { token: 'ccpk_…' }))

createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
)

4. Build a part​

Replace src/App.jsx. useBuerliCadFacade opens a drawing and builds the part with the function you give it, and Geometry shows the drawing in the scene.

src/App.jsx
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import { useBuerliCadFacade } from '@buerli.io/react'

export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Canvas camera={{ position: [120, 100, 200], fov: 35, near: 1, far: 2000 }}>
<color attach="background" args={['#f0f0f0']} />
<ambientLight intensity={1.5} />
<directionalLight position={[100, 150, 150]} intensity={2} />
<Cutout hole={55} />
<OrbitControls />
</Canvas>
</div>
)
}

// A box of 90 mm, hollowed out, with a hole through it
function Cutout({ hole }) {
const { Geometry } = useBuerliCadFacade(
'cutout',
async (api) => {
await api.v1.common.clear()
const part = await api.v1.part.create({ name: 'Cutout' })
const ei = await api.v1.part.entityInjection({ id: part })
const box = await api.v1.solid.box({ id: ei, length: 90, width: 90, height: 90 })
const inner = await api.v1.solid.box({ id: ei, length: 70, width: 70, height: 70 })
await api.v1.solid.subtraction({ id: ei, target: box, tools: [inner] })
const cylinder = await api.v1.solid.cylinder({ id: ei, diameter: hole, height: 180 })
await api.v1.solid.subtraction({ id: ei, target: box, tools: [cylinder] })
},
[hole]
)
return <Geometry />
}

5. Run it​

npm run dev

Open http://localhost:5173. The first start loads the engine from ClassCAD's CDN, which takes a moment. Then you see the part from the picture at the top, and you can turn it with the mouse.

How it works​

  • init takes a factory: buerli calls it for every drawing it opens, with the drawing's id. Here every drawing gets a WASMClient, so the engine runs in a Web Worker in the page.
  • useBuerliCadFacade('cutout', build, [hole]) opens the drawing named cutout and suspends until it is connected. Then it runs build, and runs it again whenever hole changes, as an effect would: a build that a newer one replaces stops where it is, so the drawing always holds one part. Components that pass the same name share the drawing. When the last of them unmounts, the drawing is closed.
  • api is the ClassCAD API. Every call returns its result and throws when the engine reports an error. The solids of an entity injection (part.entityInjection) are centered at the origin; sizes are in millimeters.
  • Geometry renders the drawing, and draws it again whenever the model changes.
  • StrictMode mounts each component twice in development. buerli keeps the drawing and builds the part once.

Options​

Your own copy of the engine. By default WASMClient loads the engine from ClassCAD's CDN. With the Business plan you can host its files yourself and pass their address:

init((drawingId) => new WASMClient(drawingId, { token: 'ccpk_…', url: 'https://example.com/classcad/' }))

Your own sign-in. An app that signs its users in can pass getKey instead of token: a function that returns a key, which your server gets with a secret access token. See WebAssembly on classcad.ch.

Next​