Your First Kernel
Build a parametric model with the Replicad kernel, override its parameters, and export glTF and STEP.
Build a parametric box with rounded corners, render it with overridden parameters, and export it to glTF and STEP.
Prerequisites
- Install @taucad/runtime
- Complete the Quick Start
Step 1: Set Up the Client
Create a runtime client with the Replicad kernel and the esbuild bundler:
import { createRuntimeClient } from '@taucad/runtime';
import { defineRuntime } from '@taucad/runtime/worker';
import { replicad } from '@taucad/replicad';
import { esbuild } from '@taucad/esbuild';
import { fromMemoryFs } from '@taucad/runtime/filesystem';
import { inProcessTransport } from '@taucad/runtime/transport/in-process';
const runtime = defineRuntime({
plugins: [replicad(), esbuild()],
});
const client = createRuntimeClient({
transport: inProcessTransport({ runtime, fileSystem: fromMemoryFs() }),
});This is the explicit form of what createNodeClient did in the Quick Start: you supply the transport and filesystem yourself. Inline source.files input is staged into the filesystem you pass here.
Verify: No output yet. The client initializes lazily — the worker spawns on the first command call.
Step 2: Write a Parametric Model
Define a model whose dimensions are parameters, so callers can adjust them without editing code:
const modelCode = `
import { drawRoundedRectangle } from 'replicad';
const defaultParams = {
width: 30,
height: 20,
depth: 10,
fillet: 3,
};
export default function main(params = defaultParams) {
const { width, height, depth, fillet } = params;
return drawRoundedRectangle(width, height, fillet)
.sketchOnPlane('XY')
.extrude(depth);
}
`;The default-exported main function is the entry point the kernel calls. The kernel infers the parameter shape from defaultParams and derives a JSON Schema from it for UI generation.
Verify: This step assigns a string — nothing executes yet.
Step 3: Render with Parameter Overrides
Open the model with parameter overrides, then export the document's committed evaluation:
import { createRuntimeClient } from '@taucad/runtime';
import { defineRuntime } from '@taucad/runtime/worker';
import { replicad } from '@taucad/replicad';
import { esbuild } from '@taucad/esbuild';
import { fromMemoryFs } from '@taucad/runtime/filesystem';
import { inProcessTransport } from '@taucad/runtime/transport/in-process';
const modelCode = `
import { drawRoundedRectangle } from 'replicad';
export default function main(params = { width: 30, height: 20, depth: 10, fillet: 3 }) {
const { width, height, depth, fillet } = params;
return drawRoundedRectangle(width, height, fillet).sketchOnPlane('XY').extrude(depth);
}
`;
const runtime = defineRuntime({ plugins: [replicad(), esbuild()] });
const client = createRuntimeClient({
transport: inProcessTransport({ runtime, fileSystem: fromMemoryFs() }),
});
const document = client.open({
source: { files: { 'main.ts': modelCode } },
parameters: { width: 50, depth: 15 },
});
const result = await document.export('glb');
if (result.success) {
for (const file of result.files) {
console.log(`Rendered ${file.name}: ${file.bytes.byteLength} bytes (${file.mimeType})`);
}
} else {
for (const issue of result.issues) {
console.error(`[${issue.severity}] ${issue.message}`);
}
}
document.close();
await client.shutdown();The parameters object overrides the model's defaults for this render — here the box widens to 50 and deepens to 15 while height and fillet keep their defaults. The result is a discriminated union: result.success narrows to files (an ordered, non-empty file array) on success, or to issues (structured errors with messages, locations, and severities) on failure.
Verify: You should see output like Rendered model.glb: 5824 bytes (model/gltf-binary). On errors, check that the model imports from replicad and default-exports main.
Step 4: Export to STEP and Clean Up
Swap the format argument to export STEP from the same source, then terminate the client to shut down the worker:
import { createRuntimeClient } from '@taucad/runtime';
import { defineRuntime } from '@taucad/runtime/worker';
import { replicad } from '@taucad/replicad';
import { esbuild } from '@taucad/esbuild';
import { fromMemoryFs } from '@taucad/runtime/filesystem';
import { inProcessTransport } from '@taucad/runtime/transport/in-process';
const modelCode = `
import { drawRoundedRectangle } from 'replicad';
export default function main(params = { width: 30, height: 20, depth: 10, fillet: 3 }) {
const { width, height, depth, fillet } = params;
return drawRoundedRectangle(width, height, fillet).sketchOnPlane('XY').extrude(depth);
}
`;
const runtime = defineRuntime({ plugins: [replicad(), esbuild()] });
const client = createRuntimeClient({
transport: inProcessTransport({ runtime, fileSystem: fromMemoryFs() }),
});
const document = client.open({
source: { files: { 'main.ts': modelCode } },
parameters: { width: 50, depth: 15 },
});
const stepResult = await document.export('step');
if (stepResult.success) {
for (const { name, bytes, mimeType } of stepResult.files) {
console.log(`Exported ${name}: ${bytes.byteLength} bytes (${mimeType})`);
}
} else {
console.error('Export failed:', stepResult.issues);
}
document.close();
await client.shutdown();The runtime picks the export route from the active kernel's capabilities. STEP export is available on the Replicad and OpenCASCADE kernels; other kernels support different formats — see Choose a Kernel.
Verify: You should see a .step file logged, and the process should exit cleanly. If it hangs, shutdown() was not awaited or a listener is keeping the event loop alive.
Recap
- Created a
RuntimeClientwith an explicit transport and filesystem - Wrote a parametric model with a default-exported
mainfunction - Rendered to glTF with parameter overrides via
document.export('glb') - Re-exported to STEP by swapping the format argument, then terminated the client
Next Steps
- Live Rendering — Drive UI viewers that react to parameter changes and file edits
- Use Middleware — Add caching and post-processing to your pipeline
- Set Up the Filesystem — Use Node.js or browser filesystems instead of in-memory
- Architecture — How client, transport, worker, and kernel layers interact