Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>OpenSCAD.js PreviewNew to Visual Studio Code? Get it now.
OpenSCAD.js Preview

OpenSCAD.js Preview

Ouroboros Productions

|
2 installs
| (0) | Free
SCAD syntax highlighting and interactive 3D previews with STL export, Customizer, animation, and STL, STEP, 3MF and G-code viewers.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

OpenSCAD.js Preview

Local VS Code extension with normal .scad text editing, syntax highlighting and a side-by-side, file-pinned 3D preview. No native OpenSCAD installation is required. The compiler supports a partial OpenSCAD subset, not every model.

Supported extension targets are desktop VS Code and Remote SSH, not browser VS Code. Safari and iOS browsers are unsupported for this release; volunteer compatibility contributions are welcome for future consideration.

The blue square-tunnel cube is the extension's package and preview-tab icon. Its SCAD source and reproducible artwork are created with OpenSCAD.js; the mark does not imply affiliation with OpenSCAD.

Open a .scad file and run OpenSCAD: Open Preview to the Side (or press F5 / select the editor-title preview icon). The preview automatically builds upon opening. Subsequent edits mark the panel Out of Date (or trigger background recompilation if Auto preview is enabled). The last successful geometry and camera remain visible on compile errors. STL export renders the current source and asks for a destination. Compilation errors appear in Problems and the preview, with clickable source locations.

The preview footer displays real-time geometric dimensions ($X \times Y \times Z$ mm), volume ($\text{mm}^3$), and triangle count, and exports .openscad-model.json to the workspace for AI/Copilot inspection. Use the Camera button or command OpenSCAD: Capture Viewport Snapshot to Workspace to save rendered PNG snapshots to ${file}-preview.png and .openscad-preview.png. Both files are saved in the SCAD file's workspace root (or beside the file when it is outside a workspace). The snapshot includes the current camera, visible references, clipping and annotations. It captures the displayed geometry, which may be out of date after an edit; it does not compile the source automatically. Wait for compilation to finish before capturing.

The command uses the focused preview, then the active SCAD editor's preview. When neither identifies a target, it uses the only open preview or asks you to choose among multiple previews. Moving, hiding or revealing a preview does not invalidate its model or cancel compilation. Capture failures appear in the preview and/or a VS Code error notification rather than silently saving a blank image.

For extension/API callers, vscode.commands.executeCommand('openscadJs.captureSnapshot', scadUri) pins the request to that file's already-open preview. The returned promise resolves to the named PNG's vscode.Uri only after both PNG files have been written, and rejects on capture/write errors, panel closure or a 15-second timeout. Omitting the URI uses the interactive selection rules above; cancelling selection returns undefined. This command must be invoked through the VS Code extension host; it is not automatically exposed as an AI tool.

The Axes toggle draws world X, Y, and Z lines through the origin. Marks also enables axes and adds positive-side tick marks and labels; spacing adapts between 10, 100, and 1000 mm intervals as the view zooms out. The corner XYZ indicator follows camera rotation and is independent of these toggles. Axes and marks are viewport overlays and do not affect model metrics or STL exports.

The Audit, Cross Section, Animation, Customizer, References, and Fonts tabs share a single tool panel beneath the preview. Select a tab to show its controls, or the ▼ tab to hide all panels (the default). Switching tabs preserves settings and does not stop animation, disable slicing, or cancel an audit. Use Left/Right arrow keys or Home/End while a tab is focused to switch tabs.

The Cross Section (Slicing Plane) tab allows cutting through solid geometry in real time along the X, Y, or Z axis with an interactive slider and invert toggle. This makes it easy to inspect internal cavities, bolt recesses, and tendon channels without altering your source model.

Select Measure, then click two visible points on the model to see their point-to-point distance and signed X/Y/Z deltas in millimeters. Hits behind the active cross-section plane are ignored. The optional gap target compares the measured distance with a selected 0.20, 0.30, or 0.40 mm reference; this is a reference comparison, not an automatic fit or interference analysis. Use Copy to send the point coordinates, distance, deltas, and comparison to the clipboard as JSON. The line and endpoint markers are preview annotations and are not included in compilation or STL exports.

The Interference Audit samples $t from 0 to 1 and intersects named part solids at each sample. Mark independently moving solids in source, outside their own union/difference operations:

audit_part("palm") cube([20, 30, 8]);
translate([20 - 20 * $t, 0, 0]) audit_part("finger") cube([12, 8, 8]);

Choose 2-20 samples, an overlap-volume threshold in mm³, and a minimum Clearance (mm) (default 0.2; set to 0 to disable gap warnings). Findings identify each part pair and sample times, separated into:

  • INTERFERENCE (red): overlap above the volume threshold, with maximum volume and the worst sample time.
  • CLEARANCE (amber): separated parts closer than the requested clearance, with minimum gap and the worst sample time.
  • CONTACT (muted): touching within 0.001 mm, with overlap at or below the volume threshold. Contacts are not automatically treated as collisions.

Up to 64 explicitly wrapped solids are compared; nested markers and duplicate names are rejected. This is discrete sampling, so collisions between sample times may be missed. Clearance is measured on the tessellated solids, not a mechanical strength or manufacturing-fit guarantee. The original preview remains displayed during the audit. The repository CLI's --audit runs the same check from a terminal (so Copilot can run it) and accepts -D pose lists; see COPILOT_INTEGRATION.md.

After compiling a source, the Customizer tab exposes documented SCAD parameters, including ranges, choices, booleans, strings and vectors. Parameter changes trigger a debounced preview. Presets can be saved per preview panel and imported/exported using OpenSCAD's parameter-set JSON format. The Animation tab seeks or plays $t from 0 to 1; FPS is bounded to 1-60 and steps to 1-1000. Playback waits for each frame compile and stops on edits, errors or manual rendering.

For example, these top-level assignments produce a width slider, a color choice and a centered checkbox:

/* [Dimensions] */
width = 20; // [4:2:40]
color = "red"; // [red:Red, blue:Blue]
centered = true;

color(color) cube([width, width, 8], center = centered);

The extension overrides those variables for preview compilation without rewriting the source file. It discovers literal number, boolean, string and numeric-vector assignments at the file's top level; $ variables, computed defaults and assignments inside modules are not exposed. A /* [Hidden] */ group hides following parameters until the next group heading. Presets save and restore the overrides, not copies of the SCAD source.

Fonts

text(), textmetrics() and fontmetrics() can use installed .ttf/.otf faces such as Arial:style=Bold Italic, without bundling the fonts into the extension. Bundled Liberation faces remain available without system discovery.

Open the preview's Fonts tab to discover parser-readable faces. The list is loaded only when opened and labels Bundled, Font directory, and Host installed faces. Search by family or style; Copy puts the exact SCAD assignment (for example font="DejaVu Sans:style=Bold Oblique") on the clipboard without modifying the source or compiling. Refresh rescans directories and installed fonts, including fonts added since the panel was opened. Discovery errors appear in the Fonts panel and can be retried. Font files are checked for readability/format, not certified for every glyph or shaping feature.

  • openscadJs.fontDirectories: additional directories, searched recursively before installed fonts, matched by embedded family/style names rather than filenames. Paths are absolute or relative to the workspace folder. Symlinks are not scanned. Configure this machine-scoped setting in user settings.
  • openscadJs.systemFonts: defaults to true. Linux uses fontconfig (fc-match for resolution, fc-list for browsing); if unavailable, a warning is shown and standard font directories are scanned. Windows/macOS scan standard system and user font directories.

Fonts are accessed on the extension/workspace host. With SSH, WSL or containers, fonts installed on the PC displaying VS Code may not be available there. Install fonts on the host or configure host font directories; client-PC font forwarding is not implemented. Font files are not uploaded or copied into your SCAD project. Font bytes are limited to 20 MB per compile, with at most 128 faces; directory scans are bounded. Use Refresh in Fonts after adding fonts to a scanned directory. The panel explicitly identifies remote extension hosts so Windows client fonts are not confused with Linux SSH host fonts.

Missing faces and unsupported/malformed fonts are explicit compilation errors; Arial is not silently replaced with Liberation Sans. .ttc collections, variable axes, Unicode text and complex shaping remain unsupported. Use fonts you are licensed to use. The browser studio separately provides a file picker and permission-based local-font access.

Model viewer (STL, STEP, 3MF)

Opening a .stl, .step/.stp or .3mf file shows it in the read-only OpenSCAD.js Model Viewer instead of VS Code's binary-file message. The viewer uses the same camera toolbar, axes, marks and wireframe toggle as the SCAD preview. Its summary reports the triangle count, bounding-box size in mm, and file size. For watertight meshes it also reports the volume in mm³. For other meshes it reports the number of open and non-manifold edges, which helps you catch broken print exports.

  • STL: binary and ASCII.
  • STEP: CAD solids are tessellated with OpenCascade in a background worker in the extension host, converted to millimeters, and welded so that closed solids report as watertight. Large assemblies can take a few seconds. Tessellation times out after two minutes.
  • 3MF: mesh objects, components (including production-extension parts stored in other model files), build-item and component transforms, and model units. Support and "other" objects are skipped. Colors and materials are not shown.

For STEP and 3MF files, Convert to STL saves the displayed mesh as a binary STL, by default next to the source file. To use that STL as a reference while recreating a part in OpenSCAD, add it as a transparent background modifier: %import("part.stl");. This shows it in the preview but leaves it out of renders and exports.

The viewer reloads automatically when the file changes on disk, for example after you re-export it, and keeps the current camera. If a reload fails, the previous model stays visible alongside the error. Files are limited to 100 MB and 2,000,000 triangles. To open a file as text or with another editor, use Reopen Editor With... or the workbench.editorAssociations setting.

STEP support uses occt-import-js and Open CASCADE Technology under the LGPL-2.1. They ship unmodified in media/vendor/occt/ (adding about 8 MB to the extension), and their licenses are in licenses/occt-import-js/.

Reference overlays

To compare a downloaded model with your SCAD design, select Use as Reference in the model viewer and choose the target SCAD file. You can also use the model's Explorer context menu, the command OpenSCAD: Use Model as Reference in SCAD Preview, or References > Add Reference in an existing preview. STL, STEP/STP and 3MF references use the same readers and millimeter units as the model viewer; no intermediate STL conversion is needed.

Each reference appears as a translucent gray overlay with:

  • Visible and Opacity controls.
  • Position in millimeters, Rotation in degrees (X, then Y, then Z about the model's original origin), and independent positive Scale factors. Scaling and rotation are applied before translation.
  • Fit Reference, which frames that reference without changing its placement. The normal camera Fit button continues to frame only the compiled model.
  • Reset Placement, Reload, and Remove controls.

Reference files and settings are saved per SCAD file in VS Code's workspace storage and restored when its preview reopens. The files are linked, not copied; moving a reference file or renaming the SCAD file requires adding it again. The settings are local to this VS Code workspace, not checked into the project. Up to eight references are allowed, each subject to the model viewer's 100 MB and 2,000,000-triangle limits.

References stay visible across recompilation and automatically reload when their files change. A failed reload or deleted file retains the previous geometry with an explicit error. Removing a reference does not delete its file. References are preview only: they do not modify SCAD source, affect model metrics, measurements, cross-section clipping or interference audits, or appear in STL exports. Viewport snapshots include visible references.

G-code viewer

Opening a .gcode or .gco file shows its sliced toolpath in the OpenSCAD.js G-code Viewer, drawn on the printer's build plate when the slicer recorded it. Open as Text (or Reopen Editor With...) switches back to the text editor.

  • Layer sliders pick the first and last visible layer. The label shows the range and the Z height of the top layer, so you can step through a print layer by layer.
  • Travel shows non-extruding moves, which are hidden by default.
  • Tubes draws extrusions as shaded 3D tubes instead of lines. This is slower on large files.
  • The camera toolbar provides fit, zoom, reset, and right/left/back/front/top views. Drag to orbit, right-drag to pan, and scroll to zoom.
  • The summary reports the layer count, the printed part's size in mm, filament length and weight, estimated print time, printer, slicer, and file size. PrusaSlicer, OrcaSlicer, Bambu Studio and Cura metadata are recognized. The slicer's purge and prime lines (;TYPE:Custom) are drawn but are excluded from the reported size and camera fit.

Line colours follow each tool's filament colour, shaded from dark at the bottom layer to light at the top. Very dark and very light filaments are lightened or darkened so the toolpath stays visible. Like the model viewer, the G-code viewer reloads when the file changes and keeps the camera. Files are limited to 100 MB.

Limitations: binary G-code (.bgcode) is not supported, relative positioning (G91) is not interpreted, and moves are not coloured by feature type (perimeter, infill, support). Rendering uses gcode-preview (MIT).

Development

The build currently depends on the parent repository and its installed runtime dependencies and reference font assets. From the parent directory:

npm ci
npm --prefix extension ci
npm --prefix extension run build
npm --prefix extension test
npm --prefix extension run test:occt
npm --prefix extension run test:browser
npm --prefix extension run package

For the complete parent-plus-extension local candidate gate, run npm run release:check from the parent directory. It cleans generated outputs, runs both projects' checks and inspects actual packaged archives; see the gate instructions and limits. The VSIX uses normal README-link rewriting against the planned GitHub repository and its extension/ directory; no missing-repository or relative-link override is needed. It is not Marketplace-ready merely because tests pass.

Open extension/ as the VS Code workspace and press F5 to launch an Extension Development Host. Alternatively install the generated openscad-js-preview-0.1.0.vsix using Extensions: Install from VSIX. For Remote SSH, install it in the remote workspace extension host. Packaged assets are served to the local webview by VS Code; no HTTP server is required.

Set openscadJs.libraryPaths to library directories on the workspace host. Relative paths use the entry's workspace folder, or its parent for standalone files. Reads cannot escape these roots, including through symlinks. Unsaved open-document text takes precedence over disk contents. Workspace Trust is required. Preview panels are not restored after restarting VS Code.

Set openscadJs.experimentalFeatures to an array of supported flags to enable experimental behavior. Available values are roof, object-function, import-function, and vector-swizzle; the default is empty. These options enable partially implemented features and do not imply full native OpenSCAD compatibility.

The author reports successful installed-extension use on Desktop and Remote SSH. A structured smoke check against the exact release VSIX is still needed before release. Use the release checklist for separate local and SSH results, exact package hashes, expected geometry, error recovery and sign-off. The CI extension job builds, tests, packages and inspects a candidate, but does not replace those real extension-host checks. Browser tests cover the actual packaged rendering code with a simulated VS Code message bridge, not VS Code's complete webview resource transport.

The publisher ID is OuroborosProductions. Automatic compilation, Customizer and animation are implemented; native backend selection, language-server features and session restoration remain deferred. See SPECIFICATION.md in the source tree.

Publication identity

  • Public author: Jameson McCowan.
  • Planned repository: https://github.com/jamesonmccowan/openscad.js, branch main.
  • Initial version: 0.1.0; package name: openscad-js-preview.
  • Registered Marketplace publisher ID: OuroborosProductions.
  • Full extension ID: OuroborosProductions.openscad-js-preview.

The publisher in package.json matches the registered publisher ID. See the official publishing instructions for packaging and publication. The public publisher display name and the unique publisher ID are different. Do not put publishing credentials in this repository or send them in chat. No login, account creation, upload or publication is performed by the build/gate.

Changing the publisher changes the extension ID (publisher.name). The former openscad-js-local.openscad-js-preview installation will not automatically become an installation of the new ID; uninstall the local-ID copy when testing the new VSIX to avoid duplicate commands/viewers. Rebuild and rerun the release gate with OuroborosProductions, then smoke-test that exact VSIX.

README content links explicitly target blob/main/extension/, with image links targeting raw/main/extension/, because this extension lives in a monorepo. Parent-document links therefore resolve at the repository root. These URLs are planned publication targets, not evidence that the repository has already been uploaded. Verify them after pushing the fresh public tree.

Notices

Original code is Apache-2.0. Build output includes LICENSE, THIRD_PARTY_NOTICES.md, dependency/font licenses and generated legal notices. Retain these when redistributing. The extension also includes the parent project's reviewed Manifold/roof provenance and embedded notices under licenses/wasm/; see the parent notices. Those inputs are checked by the parent distribution build before extension packaging. This bounded review is not legal certification of all project assets.

The build discovers npm inputs for all five host/webview/worker bundles from esbuild metadata. licenses/bundled-packages.json records their package versions, bundle/sidecar hashes and license-file hashes. Notices are retained under licenses/npm/<name>@<version>/, including both Three.js versions (0.180.0 for the main viewer and 0.159.0 for G-code). Embedded OpenType.js helpers and Lucide's Feather-derived artwork have supplemental notices in licenses/javascript/. Rebuilds clear generated licenses before repopulating them, so removed dependencies do not leave stale attribution trees.

All 12 Liberation TTF faces and six UI WOFF/WOFF2 assets are copied unchanged from the parent artifact, with their SIL OFL texts. System/user fonts are not redistributed. VS Code command icon names request host-supplied icons; no Codicons font is shipped. See the JavaScript, icon and font review for scope and upstream attribution.

STEP importer provenance review

Evidence checked on 2026-10-19 for occt-import-js 0.0.23:

  • The npm release metadata records gitHead as c2148e54b456b571238d35cac037d304053d64b2. The downloaded npm archive was checked against its registry SHA-512 integrity: sha512-RFfYQXYFX5C1mB1Aywm0ShcUKzXOr/VzTnlzhBSDJOR6YCAPt1HYCzeXWg1vwwjn/cUxwqRNhhtf1dlewoZYCQ==.
  • The importer source tree pins its occt submodule to d2abb6d844231cb8f29be6894440874a4700e4a5. Its version header identifies OCCT 7.6.1. The original submodule URL is https://git.dev.opencascade.org/repos/occt.git; the same revision is available in the official GitHub mirror.
  • Installed and packaged occt-import-js.wasm have SHA-256 33391fc9d94ea5c869a6718488bf0a9a464222bac9bdc764dfe1690cef281952, identical to the binary checked into that importer revision. Installed and packaged occt-import-js.js have SHA-256 3fb44ce11d00611f9b3f3c5775d520ebab48930c1f08279b7b1316f05f0d3379. The upstream wrapper differs in CRLF/LF line endings only.
  • The installed CMake file and Windows setup/build/distribution scripts match that revision after CRLF/LF normalization. Our extension copies the npm wrapper and WASM without modification. This is not a claim that every upstream source file was compared or that the publisher's build was attested.

The upstream build recipe is in tools/ and CMakeLists.txt. Check out the exact importer revision and initialize its pinned OCCT submodule. On Windows, tools/setup_emscripten_win.bat selects Emscripten 3.1.69 and MinGW 7.1.0; tools/build_wasm_win_dist.bat runs the Release build, tests it, and copies the outputs and license files into dist/. The Release CMake configuration selects -Oz, WebAssembly exceptions, embind, a modularized occtimportjs factory, a 10 MB stack and memory growth. These are the published recipe's settings, not independently verified facts about the toolchain used to produce the distributed binary.

The build now includes the full pinned importer, OCCT and Emscripten source archives in every VSIX under licenses/occt-import-js/sources/, alongside a checksum/revision manifest, LGPL texts, OCCT exception, and runtime notices. It verifies source archive and npm binary hashes and fails on changes rather than silently reusing a different version. First builds require network access to download approximately 79 MiB of sources; later builds use a hash-verified ignored .occt-cache/. tar must be installed. The cache is not packaged. Source delivery increases the VSIX size deliberately so recipients receive the sources without relying on continued upstream availability.

See OCCT-SOURCES.txt for extraction, clean-build commands, license rights and replacement of the JS/WASM pair in media/vendor/occt/. No runtime integrity check prevents users replacing that pair. The extension host's calling code is also delivered as source. The separate test:occt command checks the built source archives, binaries, instructions and notices; run it after build.

The OCCT worker test and model-viewer browser tests use the packaged library by default, not the npm copy. To check a rebuilt replacement without changing the installed pair, set OPENSCAD_OCCT_SCRIPT to the absolute path of the rebuilt occt-import-js.js (with its matching WASM beside it), then run npm --prefix extension run test:occt and npm --prefix extension run test:browser -- tests/stl.spec.mjs --grep 'STEP'. The source/archive integrity tests still check the reviewed release pair; the worker/browser tests exercise the selected replacement.

Clean Linux rebuilding was verified on 2026-10-19 with Emscripten 3.1.69, Ninja and the unpatched pinned sources. The rebuilt pair passed the Node worker geometry/error checks and all four focused Chromium STEP-viewer tests, including STL conversion. The rebuilt JS matches upstream LF text; the WASM differs from npm's binary. provenance.json records both rebuilt hashes and the bounded checks; this demonstrates buildability/replacement, not bit-identical reproducibility or correctness for every model. Release builds continue to use the reviewed, unchanged npm pair. OCCT's source declares LGPL-2.1 with its special exception; the package preserves that exception and prominent OCCT attribution. Runtime notices include Emscripten (MIT selected), musl, libc++, libc++abi, compiler-rt, libunwind and dlmalloc; complete source-file notices are retained in the supplied archives. This source-delivery and provenance work is not a legal certification or an attestation of the upstream publisher's build.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft