# How to Parameterize STEP Models with .step.js Sidecar Modules

> Learn to parameterize STEP models using .step.js sidecar modules in earthtojake/text-to-cad. Control UI elements bound to STEP file features for interactive manipulation without regeneration.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-07-29

---

**In the earthtojake/text-to-cad repository, you parameterize STEP geometry by creating a JavaScript sidecar module named `.<stem>.step.js` that exports a manifest defining UI controls bound to specific feature IDs in the STEP file, enabling interactive manipulation without regenerating the underlying CAD artifact.**

The text-to-cad project introduces a robust pattern for converting static STEP files into dynamic, interactive components. By pairing each `*.step` or `*.stp` geometry file with a [`.step.js`](https://github.com/earthtojake/text-to-cad/blob/main/.step.js) sidecar module, you maintain a clean separation between immutable geometry artifacts and live presentation logic. This architecture allows the CAD Viewer to load geometry once while providing real-time controls for parameters like gear ratios or joint angles, all validated through a standardized manifest schema.

## Understanding the Sidecar Architecture

The sidecar pattern relies on specific file naming conventions and a strict manifest contract to bridge static CAD data with interactive JavaScript controls.

### Sidecar Naming Convention

A sidecar module must follow the pattern `.<stem>.step.js`, where `<stem>` matches the STEP file name exactly. For example, `gearbox.step` pairs with [`.gearbox.step.js`](https://github.com/earthtojake/text-to-cad/blob/main/.gearbox.step.js). The helper function `isInlineStepParameterPath` in `packages/cadjs/src/common/stepSidecars.mjs` validates this naming convention, ensuring the viewer can automatically associate sidecars with their geometry sources.

### Path Resolution Utilities

The `stepSidecars.mjs` file provides `stepParameterPathForStepSource(sourcePath)` to compute the sidecar path from any STEP source path. This utility guarantees consistent path resolution across the workspace, handling the dot-prefix naming automatically.

### Manifest Contract Requirements

Every sidecar must export a default object containing a `manifest` key. The manifest must specify `schemaVersion: 1` (currently the only supported version) and include a `step` block pointing to the STEP file path **relative to the workspace root**. According to [`skills/cad/references/parameters.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/references/parameters.md), the `manifest.step.path` value should contain no leading slashes or parent directory references.

### Parameter Definitions and Feature Binding

Inside the manifest, you define UI controls using the `parameters` array. Each parameter requires `id`, `type` (such as `"number"` or `"select"`), `label`, and binding to a geometry feature via `featureId`. Feature IDs use stable references like `#gear_pair` that must exist in the STEP file metadata. The repository enforces **snake_case** naming conventions for parameter IDs to maintain consistency across the codebase.

### Viewer Integration

The CAD Viewer scans model directories using `cadDirectoryScanner.mjs` located in `viewer/src/server/catalog/`. The scanner calls `isInlineStepParameterPath` to identify sidecars and serves them under URLs like `/models/<folder>/.<stem>.step.js?v=<hash>`. The viewer dynamically imports these modules and instantiates controls based on the exported manifest.

### Animation Support

Sidecars may expose a `durationSeconds` field at the manifest root level. When present, the viewer renders an animation timeline with playback controls. Animation-specific parameters, such as normalized travel values, can reference geometry features just like static parameters, allowing smooth interpolation without STEP regeneration.

## Creating Your First .step.js Sidecar Module

Place your sidecar file in the same directory as its corresponding STEP file, using the dot-prefix naming convention.

### Minimal Parameterized Sidecar

The following example creates a single slider controlling gear ratio:

```javascript
// models/mechanisms/.gearbox.step.js
export default {
  manifest: {
    schemaVersion: 1,
    step: {
      // Workspace-relative path to the STEP geometry
      path: "models/mechanisms/gearbox.step"
    },
    // UI controls – one slider controlling the gear ratio
    parameters: [
      {
        id: "gear_ratio",
        type: "number",
        label: "Gear Ratio",
        unit: "",
        default: 2,
        min: 1,
        max: 10,
        step: 0.1,
        // Reference to the feature that will be transformed
        featureId: "#gear_pair"
      }
    ]
  }
};

```

**Key implementation details:**
- The filename **[`.gearbox.step.js`](https://github.com/earthtojake/text-to-cad/blob/main/.gearbox.step.js)** matches the `gearbox.step` source exactly.
- `manifest.step.path` uses a workspace-relative path without leading `/` or `..` segments.
- The `featureId` `#gear_pair` must correspond to a feature identifier embedded in the STEP file metadata.

### Animation-Enabled Sidecar

Add `durationSeconds` to enable timeline controls:

```javascript
// models/robots/.arm.step.js
export default {
  manifest: {
    schemaVersion: 1,
    step: { path: "models/robots/arm.step" },
    durationSeconds: 4,               // 4-second animation loop
    parameters: [
      {
        id: "joint_travel",
        type: "number",
        label: "Elbow Travel",
        unit: "deg",
        default: 0,
        min: -90,
        max: 90,
        step: 1,
        featureId: "#elbow_joint"
      }
    ]
  }
};

```

The viewer automatically generates play/pause and scrubber controls when `durationSeconds` is present, interpolating the `joint_travel` parameter over the specified interval.

## Accessing Sidecars Programmatically

You can inspect sidecar manifests from Python skills by evaluating the JavaScript module and extracting the JSON structure:

```python
from pathlib import Path
import json
import subprocess

def load_step_manifest(step_path: Path):
    sidecar_path = step_path.with_name(f".{step_path.stem}.step.js")
    if not sidecar_path.is_file():
        raise FileNotFoundError(f"No sidecar for {step_path}")
    
    # Evaluate the module and extract the manifest

    result = subprocess.check_output([
        "node", "-e",
        f"import('{sidecar_path}').then(m=>console.log(JSON.stringify(m.default.manifest)))"
    ])
    return json.loads(result)

manifest = load_step_manifest(Path("models/mechanisms/gearbox.step"))
print(manifest["parameters"][0]["id"])   # → gear_ratio

```

This approach leverages Node.js to parse the ECMAScript module syntax, making the manifest data available to Python-based automation scripts or build pipelines.

## Summary

- **Create sidecars** using the naming pattern `.<stem>.step.js` adjacent to your `*.step` files.
- **Export a manifest** with `schemaVersion: 1`, a workspace-relative `step.path`, and a `parameters` array defining UI controls.
- **Bind parameters** to geometry using `featureId` references that match IDs embedded in the STEP file metadata.
- **Enable animations** by adding `durationSeconds` to the manifest root, which triggers the viewer's timeline interface.
- **Discover sidecars** automatically through the `isInlineStepParameterPath` predicate used by the viewer's directory scanner.

## Frequently Asked Questions

### What is the exact file naming convention for sidecar modules?

Sidecar files must use the pattern `.<stem>.step.js` where `<stem>` is identical to the STEP filename without extension. For `housing.step`, the sidecar must be [`.housing.step.js`](https://github.com/earthtojake/text-to-cad/blob/main/.housing.step.js). The leading dot hides the file in standard directory listings while the viewer's `stepParameterPathForStepSource` function in `packages/cadjs/src/common/stepSidecars.mjs` computes these paths automatically.

### How do I reference specific geometry features in the STEP file?

Use the `featureId` field in your parameter definition with a hash-prefixed identifier like `#mounting_hole` or `#drive_shaft`. These IDs must be embedded in the STEP file's metadata during export from your CAD generator (such as build123d). The viewer uses these stable references to apply transformations without modifying the underlying STEP geometry.

### Can I animate a model without regenerating the STEP file?

Yes. Include `durationSeconds` in your manifest root to enable the animation timeline. Define parameters with ranges that represent your animation states (e.g., 0 to 1 for normalized travel). The viewer interpolates between these values client-side, moving or deforming the loaded geometry without calling back to the STEP generator.

### How does the CAD Viewer discover sidecar modules automatically?

The viewer uses `cadDirectoryScanner.mjs` to scan model directories, calling `isInlineStepParameterPath` from `stepSidecars.mjs` to identify files matching the sidecar naming pattern. Valid sidecars are served with versioned URLs (`?v=<hash>`) and dynamically imported in the browser, where the manifest schema is validated before rendering controls.