# Understanding the text-to-CAD Architecture: A Three-Layer Modular Design

> Explore the text-to-CAD architecture. Learn about its three modular layers: Skills for commands, Runtime Packages for CAD, and a Viewer for visualization. Convert text to manufacturable designs.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: architecture
- Published: 2026-08-02

---

**The text-to-CAD architecture consists of three decoupled layers—Skills for agent commands, Shared Runtime Packages for CAD processing, and a Viewer for visualization—communicating via file-based APIs to convert natural language into manufacturable artifacts.**

The **earthtojake/text-to-cad** repository implements a modular workbench that transforms plain-language prompts into CAD models, robot descriptions, and fabrication files. Its **text-to-CAD architecture** deliberately separates concerns into three distinct layers: isolated **Skills**, language-agnostic runtime libraries, and a browser-based **Viewer**. This design allows any skill to run from a CLI, web UI, or external agent without cross-layer coupling.

## The Three-Layer Architecture of text-to-CAD

The repository organizes functionality into three horizontal layers:

| Layer | Purpose | Location |
|-------|---------|----------|
| **Skills** | Agent-focused, self-contained commands | `skills/*/SKILL.md` |
| **Shared Runtime Packages** | Core CAD parsing, rendering, and export libraries | `packages/cadjs`, `packages/implicitjs`, `packages/cadpy` |
| **Viewer / UI** | Browser workbench for file inspection and MoveIt2 integration | `viewer/` |

All layers communicate through framework-agnostic APIs and file-based contracts, eliminating global state or mutable imports between components.

## 1. Skills Layer: Agent-Focused Commands

The **Skills** layer contains isolated, self-contained command modules that orchestrate generation workflows. Each skill resides under `skills/<skill>/` and strictly follows the self-contained rule: no skill imports code from sibling skills or the repository root.

### Structure of a Skill

Every skill directory contains:

- **[`SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/SKILL.md)** – Human-readable specification of inputs, outputs, and validation rules
- **Implementation source** – Python or TypeScript scripts executing the generation logic
- **`references/`** – Contracts and ledger rules for artifact validation

### Available Skills

The repository ships with five primary skills:

- **cad** – Parses natural-language briefs into **STEP** (primary), STL, 3MF, or GLB formats
- **urdf** – Generates robot description files defining links, joints, and meshes
- **gcode** – Slices meshes into validated `.gcode` for FDM fabrication
- **implicit-cad** – Produces GLSL-based signed-distance-field models for real-time rendering
- **step-parts** – Looks up off-the-shelf STEP components like screws and bearings

### Execution Flow

Skills are invoked via the Skills CLI and delegate heavy computation to the runtime packages:

```bash
npx skills run cad "a 100 mm × 60 mm × 20 mm block with four 8 mm holes"

```

This command executes the **cad** skill entry point in `skills/cad/`, which invokes **`cadpy`** for STEP generation, then hands resulting files to **`cadjs`** for snapshot rendering.

## 2. Shared Runtime Packages: Language-Agnostic Core

The **Shared Runtime Packages** implement the heavy CAD processing, mesh export, and rendering pipelines. These libraries remain framework-agnostic (no React or UI state) and are exposed as file-system symlinks under the `develop` directory for instant local updates.

### cadjs: JavaScript CAD Runtime

**`packages/cadjs`** provides the core JavaScript library for parsing CAD formats and building scene graphs. Key modules include:

- [`src/lib/fileFormats.js`](https://github.com/earthtojake/text-to-cad/blob/main/src/lib/fileFormats.js) – Parsers for STEP, STL, GLB, and DXF
- `src/lib/viewer/` – Non-React utilities for picking, clipping, and theme handling
- `src/common/` – Browser-safe render pipeline consumed by the viewer and documentation tools

### implicitjs: Implicit CAD Engine

**`packages/implicitjs`** handles browser-native implicit CAD via GLSL shaders. Located in `packages/implicitjs/src/lib/implicitCad/`, it manages model normalization, GPU ray-march rendering, and headless snapshot generation. The `src/common/` directory exposes camera controls and snapshot helpers for Node.js and browser contexts.

### cadpy: Python Artifact Generation

**`packages/cadpy`** produces STEP and STL artifacts using Python libraries like `build123d`. Skills requiring heavy solid modeling invoke `cadpy` via subprocess calls, then pass output files to `cadjs` for downstream visualization.

## 3. Viewer Layer: Browser-Based Workbench

The **Viewer** is a Vite-powered React application in `viewer/` that visualizes generated artifacts without embedding skill logic. It consumes `cadjs` and `implicitjs` runtimes to render files directly.

### Core Capabilities

- **File browsing** via `?dir=` URL parameters and a directory-tree sidebar
- **Asset previews** for STEP, STL, GLB, DXF, G-code, URDF, SRDF, SDF, and [`.implicit.js`](https://github.com/earthtojake/text-to-cad/blob/main/.implicit.js) models
- **MoveIt2 integration** via optional websocket for inverse kinematics and motion planning
- **Backend adapters** (`local-fs` in [`viewer/src/server/localAssetBackend.js`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/src/server/localAssetBackend.js) or `vercel-blob`) serving files and hidden STEP GLB sidecars

The main entry point resides at [`viewer/src/client/App.jsx`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/src/client/App.jsx), which initializes the React router and file catalog.

## Data Flow and Component Interaction

The text-to-CAD architecture follows a strict data flow:

```

[User Prompt] → [Skill CLI] → (Skill Logic)
                    ↓
              [cadpy] (Python STEP generation)
                    ↓
              [cadjs] (JavaScript parsing/scene graph)
                    ↓
              [Viewer] or [implicitjs] (Rendering)

```

Skills produce files; runtimes consume files. No component holds mutable references to another layer's internals. For example, the **cad** skill writes STEP data to disk, then `cadjs` loads that file via `loadStepFile()` without importing the skill's Python modules.

## Extending the text-to-CAD Architecture

The modular boundaries enable several extension points:

- **Add a skill** – Create `skills/<new>/SKILL.md` and implementation scripts, ensuring zero imports from sibling skills
- **Support new formats** – Extend [`packages/cadjs/src/lib/fileFormats.js`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadjs/src/lib/fileFormats.js) with parsers and update the render pipeline
- **Custom implicit shaders** – Add GLSL helpers under the `implicit_*` namespace in `packages/implicitjs/src/lib/implicitCad/`
- **Backend storage** – Implement adapters in `viewer/src/server/` and expose via the `VIEWER_ASSET_BACKEND` environment variable

## Code Examples

### Generating STEP Models via CLI

```bash
npx skills run cad "a rectangular block 120 mm × 80 mm × 30 mm with a 10 mm fillet"

```

The **cad** skill calls `cadpy`, writes `block.step` to the current directory, and returns the file path for further processing.

### Loading STEP Files with cadjs

```javascript
import { loadStepFile, getAssemblyStructure } from "cadjs";

const stepBuffer = await fetch("/models/gear_assembly.step")
  .then(r => r.arrayBuffer());
const stepModel = await loadStepFile(stepBuffer);
const structure = getAssemblyStructure(stepModel);
console.log(structure); // Tree of parts and joints

```

### Rendering Implicit CAD in Node.js

```javascript
import { loadImplicitModuleFromSource, renderImplicitToDataUrl } from "implicitjs";

const source = `export default {
  schema: "implicit.js/0.1.0",
  name: "parametric sphere",
  units: "mm",
  params: { radius: { type: "number", default: 22 } },
  glsl: \`float sdf(vec3 p){return length(p)-radius;}\`
};`;

const model = await loadImplicitModuleFromSource(source);
const dataUrl = await renderImplicitToDataUrl(THREE, model, { 
  width: 800, 
  height: 600 
});

```

## Summary

- The **text-to-CAD architecture** splits functionality into **Skills**, **Shared Runtime Packages** (`cadjs`, `implicitjs`, `cadpy`), and a **Viewer**
- **Skills** are self-contained under `skills/*/SKILL.md` and must not import sibling code
- **Shared runtimes** handle format parsing, implicit CAD shaders, and Python-based solid modeling without UI dependencies
- **Viewer** consumes file outputs via framework-agnostic APIs, supporting MoveIt2 integration and multiple storage backends
- All communication occurs through file paths and JSON objects, enabling CLI, web, and agent-based workflows

## Frequently Asked Questions

### How do the three layers communicate without tight coupling?

Components communicate through well-defined, framework-agnostic APIs using file paths and JSON objects. For instance, the **cad** skill writes STEP files to disk, then passes the path to `cadjs` functions like `loadStepFile()` rather than importing Python modules directly. This file-based contract allows any layer to be replaced or extended independently.

### What makes the Skills layer "self-contained"?

Each skill in `skills/<skill>/` operates as an isolated runtime unit. According to repository rules, skills cannot import code from sibling skills or the repository root. Each skill includes its own [`SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/SKILL.md) specification, implementation scripts, and validation references, ensuring it can execute independently via CLI or agent platforms without external dependencies.

### Which runtime handles implicit CAD models?

The **`implicitjs`** package (`packages/implicitjs`) manages implicit CAD via GLSL-based signed-distance-field shaders. It handles model normalization, GPU ray-march rendering in `src/lib/implicitCad/`, and headless snapshot generation. When the viewer encounters an [`.implicit.js`](https://github.com/earthtojake/text-to-cad/blob/main/.implicit.js) file, it delegates rendering to this runtime rather than the standard mesh pipeline.

### How does the Viewer display files without embedding skill logic?

The Viewer is a React application that only consumes the shared runtimes (`cadjs` and `implicitjs`) to parse and render artifacts. It does not import skill logic; instead, it reads files from disk via backend adapters like [`viewer/src/server/localAssetBackend.js`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/src/server/localAssetBackend.js) and uses `cadjs` functions to build scene graphs for preview, maintaining strict separation between generation and visualization.