Text-to-CAD Viewer Architecture: A Full-Stack React and Node.js Breakdown
The text-to-CAD viewer is a full-stack JavaScript application that combines a Vite-based React frontend with a lightweight Node.js backend, separating concerns between server-side asset compilation and client-side WebGL rendering.
The text-to-CAD viewer from the earthtojake/text-to-cad repository provides a modular platform for visualizing CAD models generated from text prompts. Its architecture cleanly divides responsibilities across three distinct layers: a Node.js server for asset management, a React client for interactive rendering, and shared packages for core geometry logic. This design enables flexible deployment across local development environments and cloud platforms like Vercel.
Overview of the Text-to-CAD Viewer Stack
The application follows a clear separation of concerns between server and client, connected through a REST API and shared monorepo packages:
- Server Layer (Node.js): Handles static asset serving, directory scanning, and STEP-to-mesh compilation via Python helpers.
- Client Layer (React): Manages the WebGL rendering pipeline, workbench UI components, and interactive model state.
- Shared Packages: Contains reusable CAD geometry logic (
cadjs), implicit surface generation (implicitjs), and Python-based STEP conversion utilities (cadpy).
Server-Side Architecture
The Node.js backend in viewer/src/server/server.mjs serves as the central orchestration point. It exposes HTTP endpoints for the client while managing two critical backend processes: catalog generation and asset compilation.
Catalog Generation and STEP Compilation
When the server starts, it scans the local models/ directory using src/server/catalog/cadDirectoryScanner.mjs to build a comprehensive manifest of available CAD files. For each STEP artifact discovered, the server invokes src/server/step/stepArtifactCompiler.mjs, which spawns the Python helper in packages/cadpy/ to generate WebGL-compatible GLB/GLTF assets.
The compiled manifest is cached in memory and served via the /api/catalog endpoint, allowing the client to discover available models without filesystem access.
Asset Backend Abstraction
The server abstracts storage implementation behind a common interface, enabling deployment flexibility. Two primary backends exist:
localAssetBackend.mjs: Serves files directly from the local filesystem during development.vercelBlobAssetBackend.mjs: Integrates with Vercel Blob storage for production cloud deployments.
This abstraction ensures the React client remains agnostic to asset storage location, fetching all resources through uniform API routes.
Client-Side Architecture
The React frontend bootstraps from src/client/main.jsx and mounts a comprehensive workbench interface for model inspection and manipulation.
Rendering Pipeline with cadjs and implicitjs
The client relies on cadjs (WebGL-based rendering primitives) and implicitjs (implicit CAD surface generation) from the packages/ directory to display geometry. When a user selects a model, the client fetches the compiled GLB from /api/model and resolves it into a cadjs scene graph for hardware-accelerated rendering.
Workbench UI and State Management
The user interface comprises specialized components located in src/client/components/workbench/, including CadWorkspaceTopBar.js for navigation and DrawingToolbar.js for annotation controls. State management for interactive features lives in src/client/workbench/, with dedicated stores like stepAnimationStore.js handling parameter animations and cadManifestStore.js caching the server-generated catalog locally.
How the Architecture Components Connect
The data flow follows a predictable pipeline from startup to rendering:
- Build and Boot: The Vite configuration (
viewer/vite.config.mjs) bundles the React client and starts the Node server, readingviewerConfig.mjsfor the absolute model root path. - Catalog Discovery: On initial requests, the server walks the
models/tree, compiles STEP files to GLB using Python helpers, and caches the resulting manifest. - Client Hydration: The React app loads the catalog via
/api/catalog, then requests specific model assets through the abstracted backend. - Interactive Rendering: User interactions—such as parameter adjustments in
stepModuleParameterControls.jsor assembly isolation—synchronize through state stores that update thecadjsscene graph in real time.
Development Workflow and Code Examples
Launch the Development Server
Start the viewer locally with Vite’s hot-reload development server:
npm --prefix viewer run dev
This command initializes the Node server and serves the React client at http://localhost:5173/?dir=$PWD/models.
Load a Specific Model in React
Fetch and render a compiled CAD model using the shared configuration helper:
import { useEffect, useState } from 'react';
import { loadModel } from '../shared/viewerConfig.mjs';
function ModelViewer({ modelPath }) {
const [model, setModel] = useState(null);
useEffect(() => {
loadModel(modelPath).then(setModel);
}, [modelPath]);
return model ? <CadScene model={model} /> : <p>Loading…</p>;
}
The loadModel utility retrieves the GLB asset from /api/model and constructs a cadjs-compatible scene graph.
Retrieve the CAD Catalog
Query the server API to discover available models:
fetch('/api/catalog')
.then(r => r.json())
.then(catalog => console.log('Available models:', catalog));
This endpoint returns the JSON manifest generated by cadDirectoryScanner.mjs, containing metadata for all discovered STEP files and their compiled artifacts.
Summary
- The text-to-CAD viewer employs a layered architecture separating Node.js server logic from React client rendering.
- Server responsibilities include scanning
models/viacadDirectoryScanner.mjs, compiling STEP files throughstepArtifactCompiler.mjs, and abstracting storage throughlocalAssetBackend.mjsorvercelBlobAssetBackend.mjs. - Client rendering relies on
cadjsandimplicitjspackages for WebGL visualization, managed by React components insrc/client/components/workbench/. - State management uses dedicated stores like
stepAnimationStore.jsto synchronize UI interactions with the 3D scene. - The monorepo structure in
packages/enables code sharing between Python-based STEP conversion and JavaScript rendering pipelines.
Frequently Asked Questions
What technologies power the text-to-CAD viewer frontend?
The frontend is built with React and bundled using Vite. It leverages custom WebGL libraries including cadjs for rendering and implicitjs for implicit surface generation, both located in the packages/ directory of the monorepo.
How does the server handle different deployment environments?
The server uses an abstraction layer with localAssetBackend.mjs for filesystem serving during development and vercelBlobAssetBackend.mjs for cloud storage in production. Both implement the same interface, allowing seamless switching without client code changes.
What is the role of Python in the text-to-CAD viewer architecture?
Python handles STEP-to-mesh conversion through the packages/cadpy/ module. The Node server invokes these scripts via stepArtifactCompiler.mjs to generate GLB/GLTF assets from raw STEP files before the client requests them.
Where is the CAD model catalog stored and managed?
The catalog is generated dynamically by src/server/catalog/cadDirectoryScanner.mjs scanning the models/ directory, then cached in cadManifestStore.js on the client side. This manifest tracks available models, their parameters, and paths to compiled assets.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →