npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@moicad/gui

v0.1.6

Published

Reusable React components for moicad CAD platform

Readme

@moicad/gui

Reusable React components, hooks, and utilities for building CAD editor interfaces with moicad.

Installation

npm install @moicad/gui @moicad/sdk
# or
bun add @moicad/gui @moicad/sdk

Peer Dependencies

This package requires the following peer dependencies:

  • react >= 18.0.0
  • react-dom >= 18.0.0
  • three >= 0.150.0

Usage

Basic Editor Setup

import { Editor, Viewport } from '@moicad/gui';
import { useState } from 'react';

function App() {
  const [code, setCode] = useState('cube(10);');
  const [geometry, setGeometry] = useState(null);

  return (
    <div style={{ display: 'flex', height: '100vh' }}>
      <Editor 
        value={code} 
        onChange={setCode}
        language="openscad"
      />
      <Viewport geometry={geometry} />
    </div>
  );
}

Full-Featured Editor (CADEditor Component)

The easiest way to get a complete CAD editor interface:

import { CADEditor } from '@moicad/gui/components';

function App() {
  return (
    <CADEditor
      initialLanguage="javascript"
      showFileManager={true}
      showAnimationExport={true}
      showTopMenu={true}
      showPrinterSettings={true}
      apiBaseUrl="http://localhost:42069"  // Optional: API endpoint
    />
  );
}

CADEditor Props:

  • initialCode?: string - Starting code (default: cube(10);)
  • initialLanguage?: 'openscad' | 'javascript' - Code language
  • apiBaseUrl?: string - API endpoint base URL (default: same origin)
  • showFileManager?: boolean - Show file browser (default: true)
  • showAnimationExport?: boolean - Show animation export features (default: true)
  • showTopMenu?: boolean - Show top menu bar (default: true)
  • showPrinterSettings?: boolean - Show printer presets (default: true)
  • onCodeChange?: (code: string) => void - Code change callback
  • onGeometryUpdate?: (geometry: any) => void - Geometry update callback
  • onError?: (error: string) => void - Error callback

Custom Editor Layout

For more control, build your own layout with individual components:

import {
  Editor,
  Viewport,
  TopMenu,
  Sidebar,
  FileManager,
  AnimationControls,
  ErrorDisplay,
  StatsOverlay
} from '@moicad/gui/components';
import { useEditor, useGeometry, useAnimation } from '@moicad/gui/hooks';
import { evaluateCode } from '@moicad/gui/lib';

function CustomCADEditor() {
  const editor = useEditor({ defaultCode: 'cube(10);' });
  const geometry = useGeometry();
  const animation = useAnimation();

  const handleRender = async () => {
    const result = await evaluateCode(editor.code, editor.language);
    if (result.success) {
      geometry.setGeometry(result.geometry);
    }
  };

  return (
    <div className="cad-editor">
      <TopMenu onRender={handleRender} />
      <div className="main-content">
        <FileManager />
        <Editor {...editor} onRender={handleRender} />
        <Viewport {...geometry} />
        <Sidebar geometry={geometry.current} />
      </div>
      {animation.isAnimation && (
        <AnimationControls {...animation} />
      )}
      {geometry.error && <ErrorDisplay error={geometry.error} />}
      <StatsOverlay stats={geometry.current?.stats} />
    </div>
  );
}

Components

Editor Components

  • <Editor> - Monaco-based code editor with OpenSCAD/JavaScript syntax highlighting
  • <FileManager> - File browser with save/load functionality
  • <TopMenu> - Application menu bar (File, Edit, View, etc.)
  • <ErrorDisplay> - Error message display with syntax highlighting

Viewport Components

  • <Viewport> - Three.js 3D viewport with orbit controls
  • <ViewportWrapper> - Viewport with camera controls context
  • <StatsOverlay> - Geometry statistics overlay (vertex count, faces, volume)

Control Components

  • <AnimationControls> - Timeline controls for animated models
  • <Sidebar> - Export controls and settings panel
  • <PrinterSettings> - 3D printer configuration presets
  • <RenderProgressBar> - Render progress indicator

Utility Components

  • <ErrorBoundary> - React error boundary wrapper
  • <ResizablePanel> - Draggable panel resizing

Hooks

useEditor(options)

Manages code editor state with localStorage persistence.

const editor = useEditor({
  defaultCode: 'cube(10);',
  language: 'openscad',
  storageKey: 'my-editor'
});

useGeometry()

Manages 3D geometry state and evaluation.

const { geometry, error, isLoading, evaluate } = useGeometry();

useAnimation(options)

Handles animation timeline and playback.

const animation = useAnimation({
  onFrame: (t) => console.log(`Frame t=${t}`)
});

useViewportMenus()

Manages viewport context menus and interactions.

useWebSocket(url, options)

WebSocket connection for real-time collaboration.

useResizablePanel(options)

Manages resizable panel state.

Utilities

API Client

import { evaluateCode, parseCode, exportGeometry } from '@moicad/gui/lib';

// Evaluate code to geometry
const result = await evaluateCode('cube(10);', 'openscad');

// Parse code to AST
const ast = await parseCode('sphere(5);');

// Export geometry
await exportGeometry(geometry, 'stl', 'output.stl');

Three.js Utilities

import { 
  createGeometryFromData,
  createMeshFromGeometry,
  exportToSTL,
  exportToOBJ
} from '@moicad/gui/lib';

const threeMesh = createMeshFromGeometry(geometry);
const stlData = exportToSTL(geometry);

Animation Utilities

import {
  detectAnimation,
  renderAnimationFrame,
  exportAnimationGIF
} from '@moicad/gui/lib';

const isAnim = detectAnimation(code, language);
const frameGeometry = await renderAnimationFrame(code, 0.5);
await exportAnimationGIF(frames, 'output.gif');

Storage Utilities

import { 
  saveFile,
  loadFile,
  listFiles,
  deleteFile
} from '@moicad/gui/lib';

saveFile('my-model', { code, language });
const file = loadFile('my-model');
const files = listFiles();
deleteFile('my-model');

Printer Presets

import { printerPresets, type PrinterPreset } from '@moicad/gui/lib';

const ender3 = printerPresets.find(p => p.name === 'Ender 3');
console.log(ender3.buildVolume); // [220, 220, 250]

Usage in @moicad/cli

The @moicad/cli package uses the CADEditor component to provide a full-featured web UI:

# Install CLI
npm install -g @moicad/cli

# Launch web UI (loads CADEditor from @moicad/gui via CDN)
moicad

The CLI:

  1. Serves a minimal HTML page from packages/cli/src/server.ts
  2. Uses import maps to load @moicad/gui from CDN at runtime
  3. Renders CADEditor to the DOM
  4. Routes API calls to the local Bun server

This approach keeps the CLI binary lightweight (~1.75 MB) while providing the full-featured GUI.

Architecture Diagram:

Browser
  ├─ HTML (from CLI server)
  ├─ React 19.2.4 (esm.sh)
  ├─ Three.js 0.182.0 (esm.sh)
  ├─ Monaco 0.55.1 (esm.sh)
  ├─ @moicad/gui CADEditor (CDN.js)
  └─ @moicad/sdk (CDN.js)

Local Bun Server (port 42069)
  ├─ /api/evaluate
  ├─ /api/parse
  ├─ /api/export
  └─ /manifold.wasm

Theming

Components use Tailwind CSS classes. To customize:

import '@moicad/gui/styles.css'; // If we export styles

// Or provide your own theme
<Editor
  className="custom-editor-theme"
  theme="vs-dark" // Monaco theme
/>

TypeScript

All components, hooks, and utilities are fully typed with TypeScript definitions included.

import type {
  EditorRef,
  AnimationControlsProps,
  FileManagerRef,
  GeometryData,
  PrinterPreset
} from '@moicad/gui';

API Configuration

By default, components expect API endpoints at:

  • POST /api/evaluate - Code evaluation
  • POST /api/parse - Code parsing
  • POST /api/export - Geometry export

Configure custom endpoints:

import { setAPIBaseURL } from '@moicad/gui/lib';

setAPIBaseURL('http://localhost:42069');

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+

Requires WebAssembly support for @moicad/sdk.

License

MIT

Links