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

@mlightcad/cad-html-plugin

v1.7.1

Published

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://img.shields.io/npm/v/@mlightcad/cad-html-plugin.svg)](https://www.npmjs.com/package/@mlightcad/cad-html-plugin)

Readme

@mlightcad/cad-html-plugin

License: MIT npm version

HTML export for @mlightcad/cad-simple-viewer: snapshot format, offline viewer runtime, and optional plugin integration.

| Command | Description | |---------|-------------| | -chtml | Export via command-line prompts (no dialog; AutoCAD-style - prefix) | | chtml | Same as -chtml when no UI command is registered (e.g. cad-simple-viewer only). In cad-viewer, chtml opens an export options dialog instead |

The plugin path is designed for lazy loading so the export bundle is only downloaded when a user runs -chtml or confirms export from the chtml dialog (or runs chtml in a host that has no dialog command). Low-level APIs (packHtml, snapshot types, scene collectors) are also exported for custom pipelines and the headless CLI @mlightcad/cad-simple-viewer-cli.

Key features

  • Display-only snapshot — layers, layouts, line/mesh batches, extents, and drawing units (no editable DXF/DWG payload)
  • Self-contained HTML — gzip/base64 snapshot + inline viewer runtime; opens offline in any modern browser
  • Multi-file ACEX package — generic viewer.html + fixed drawing.acex.json + per-chunk *.acex.gz; export downloads a zip (unzip before hosting for progressive load). The shell does not hard-code a drawing-specific data path: it probes sibling drawing.acex.json, supports ?manifest= / ?acex= URLs, and can open a local package folder or a pasted manifest URL when the default file is missing
  • Offline viewer — select / pan / zoom (extents, window, original view), layer panel, layout switching, measurement, Design Review markup annotations, object snap (OSNAP). Select, pan, and zoom tools exit any active measurement or review drawing tool.
  • i18n — embedded English / Chinese / Czech / Turkish UI; initial language follows the browser (zh* → Chinese, cs* → Czech, tr* → Turkish, otherwise English); the toolbar language button opens a strip to pick a locale, and the choice persists in localStorage
  • Plugin API — implements AcApPlugin; register once with registerLazyHtmlPlugin
  • Composable API — build snapshots from your own pipeline or call packHtml / buildAcExPackage with a pre-built snapshot

Installation

pnpm add @mlightcad/cad-html-plugin

Peer dependencies:

  • @mlightcad/cad-simple-viewer (for -chtml / scene snapshot builder)
  • @mlightcad/data-model
  • @mlightcad/three-renderer
  • three

Runtime dependency (bundled with this package):

  • fflate

Build

The package produces two artifacts:

| Output | Description | |--------|-------------| | dist/index.js | Library entry (snapshot types, codec, packHtml, createHtmlPlugin, …) | | dist/register.js | Lightweight lazy-registration entry (safe for static import in app bundles) | | dist/viewer-runtime.iife.js | Offline viewer bootstrap (loaded/inlined into exported HTML) |

pnpm --filter @mlightcad/cad-html-plugin build

Copy or serve viewer-runtime.iife.js from your app assets when using the browser export path (see Integration below).

Usage

Lazy registration (recommended)

Register the plugin with the document manager's plugin manager. Import from the /register subpath so only the registration stub enters your initial bundle; the main plugin chunk loads on first use of -chtml or chtml (see command table above):

import { AcApDocManager } from '@mlightcad/cad-simple-viewer'
import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register'

AcApDocManager.createInstance({
  container: document.getElementById('cad-container')!
})

// viewerRuntimeUrl is HTML-export only — not required to open DXF/DWG
registerLazyHtmlPlugin(AcApDocManager.instance.pluginManager, {
  viewerRuntimeUrl: './viewer-runtime.iife.js'
})

Do not import registerLazyHtmlPlugin from the package root (@mlightcad/cad-html-plugin) in application code — that resolves to the full library build and defeats lazy loading.

After registration (command-line export):

await AcApDocManager.instance.editor.executeCommand('-chtml')
// or
AcApDocManager.instance.sendStringToExecute('-chtml')

In cad-viewer, use chtml to open the export options dialog; -chtml remains available on the command line for prompt-based export.

cad-viewer registers this plugin automatically via registerLazyPlugins() in its app bootstrap and registers the chtml dialog command separately.

End-to-end export (command or convertor)

import { AcApHtmlConvertor } from '@mlightcad/cad-html-plugin'

// Self-contained .html (default)
await new AcApHtmlConvertor().convert('my-drawing.dwg')

// Multi-file package as one .zip download (unzip before hosting)
await new AcApHtmlConvertor().convert('my-drawing.dwg', {
  exportFormat: 'multi'
})

-chtml prompts for export format (Single / Multi). In cad-viewer, the chtml dialog offers the same choice.

Multi-file package (low-level)

See docs/acex-package-format.md for the on-disk format, and docs/acex-web-hosting-guide.md for static hosting / CDN deployment (includes a live progressive demo).

import {
  ACEX_DEFAULT_MANIFEST_FILE,
  buildAcExPackage,
  zipAcExPackageFiles,
  packHtmlPackage
} from '@mlightcad/cad-html-plugin'

// Always writes viewer.html + drawing.acex.json + chunks/
// (baseName is retained for API compatibility; it does not rename the manifest).
const pkg = buildAcExPackage(snapshot, {
  viewerRuntime: runtime,
  baseName: 'my-drawing'
})
// pkg.manifestFileName === ACEX_DEFAULT_MANIFEST_FILE ('drawing.acex.json')
const zipBytes = zipAcExPackageFiles(pkg)
// Or serve pkg.files as a static directory after unzip

How generic viewer.html finds data (in order):

  1. Query string — ?manifest=<url> or ?acex=<url> (relative or absolute http(s))
  2. Sibling file — ./drawing.acex.json next to the HTML
  3. If missing — UI to pick a local package folder (must contain drawing.acex.json) or paste a manifest URL

Unsupported package / snapshot versions surface as an on-page error.

Low-level snapshot assembly

import {
  ACEX_SNAPSHOT_VERSION,
  type AcExSnapshotV1,
  buildViewerMetadata,
  collectBatchesFromObject3D,
  buildOsnapCatalog,
  packHtml,
  HTML_VIEWER_RUNTIME_FILE
} from '@mlightcad/cad-html-plugin'

const snapshot: AcExSnapshotV1 = /* built via AcApHtmlSnapshotBuilder or manually */

const runtime = await fetch(`./${HTML_VIEWER_RUNTIME_FILE}`).then(r => r.text())
const html = packHtml(snapshot, {
  title: 'My Drawing',
  viewerRuntime: runtime
})

Scene → snapshot (viewer integration)

import { AcApHtmlSnapshotBuilder } from '@mlightcad/cad-html-plugin'

const snapshot = await new AcApHtmlSnapshotBuilder().buildAsync(
  view.cadScene,
  document.database,
  { title: 'Drawing', background: view.backgroundColor }
)

Headless / CLI

For DXF/DWG → HTML without a browser UI, use @mlightcad/cad-simple-viewer-cli with examples/export-html.scr (single-file) or examples/export-html-multi.scr (multi-file zip), or your own .scr that runs -chtml. It runs the same snapshot + pack pipeline inside Playwright.

Integration checklist

When embedding HTML export in a web app:

  1. Build @mlightcad/cad-html-plugin and expose viewer-runtime.iife.js at a URL your app can fetch (e.g. Vite public/ copy — see cad-viewer-example / cad-simple-viewer-example vite configs). Skip this step if you do not use HTML export — opening DXF/DWG does not need this file or this package.
  2. Register via @mlightcad/cad-html-plugin/register (or load the plugin eagerly).
  3. Pass viewerRuntimeUrl to registerLazyHtmlPlugin / createHtmlPlugin / AcApHtmlConvertor (default ./viewer-runtime.iife.js). Do not put this on AcApDocManager.createInstance().
  4. Ensure fonts used by the drawing are reachable during export if you rely on web-font substitution.

The generated HTML itself needs no backend; only the export step may fetch the runtime bundle and fonts.

Subpath exports:

import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register'
import '@mlightcad/cad-html-plugin/viewer-runtime' // dist/viewer-runtime.iife.js

Main exports

| Export | Role | |--------|------| | createHtmlPlugin | Async factory used by the lazy loader | | HTML_PLUGIN_NAME, HTML_PLUGIN_TRIGGERS | Plugin id and command triggers | | @mlightcad/cad-html-plugin/register | registerLazyHtmlPlugin and registration constants | | AcApExportHtmlCmd, AcApHtmlConvertor | -chtml command and full export workflow | | AcApHtmlSnapshotBuilder | Live Three.js scene → AcExSnapshotV1 | | packHtml, AcExPackHtmlOptions | Assemble self-contained HTML from snapshot + runtime | | packHtmlEmbeddedPackage, shouldEmbedAcExChunks | Progressive self-contained HTML (large drawings) | | packHtmlPackage, buildAcExPackage, zipAcExPackageFiles | Multi-file package shell, builder, and export zip | | ACEX_DEFAULT_MANIFEST_FILE, ACEX_DEFAULT_MANIFEST_HREF, package bootstrap helpers | Canonical drawing.acex.json name and generic viewer resolve / probe / directory-fetch helpers | | HTML_VIEWER_RUNTIME_FILE | Default runtime filename (viewer-runtime.iife.js) | | AcExSnapshot, ACEX_SNAPSHOT_VERSION, batch/layer types | Snapshot schema | | Package format doc | docs/acex-package-format.md | | Web hosting guide | docs/acex-web-hosting-guide.md | | encodeSnapshot, decodeSnapshot | Gzip/base64 codec for embedded payloads | | collectBatchesFromObject3D | THREE.js scene → line/mesh batches | | buildViewerMetadata | Database → viewer meta (units, extents, background, …) | | buildOsnapCatalog, OSNAP primitive helpers | Analytic snap geometry for the offline viewer | | AcExHtmlI18n, detectAcExHtmlLocale, detectBrowserAcExHtmlLocale, resolveAcExHtmlLocale | Viewer UI strings and locale detection |

Project layout

| Path | Role | |------|------| | src/register.ts | Lazy plugin registration (/register entry) and createHtmlPlugin | | src/AcApHtmlPlugin.ts | Plugin lifecycle (onLoad / onUnload) | | src/AcApExportHtmlCmd.ts | -chtml command (command-line prompts) | | src/AcApHtmlConvertor.ts | Export orchestration (snapshot, runtime fetch, download) | | src/AcApHtmlSnapshotBuilder.ts | Three.js scene → snapshot builder | | src/AcExSnapshotTypes.ts | Snapshot schema (v1) | | src/AcExSnapshotCodec.ts | Encode/decode embedded snapshot script tag | | src/AcExSceneBatchCollector.ts | THREE.js traversal → export batches | | src/AcExHtmlPackager.ts | packHtml / packHtmlPackage — shell + snapshot or package marker + runtime | | src/AcExHtmlEmbeddedPackage.ts | Auto progressive embed for large self-contained HTML (+ per-chunk AES) | | src/AcExPackageBuilder.ts | Multi-file package builder (viewer.html + drawing.acex.json + chunks) | | src/AcExHtmlPackageBootstrap.ts | Generic package resolve (query / sibling / probe / local directory fetch) | | src/AcExHtmlPackageSourceGate.ts | Folder / URL picker when sibling drawing.acex.json is missing | | src/AcExHtmlViewerRuntime.ts | Offline viewer (built as IIFE) | | src/AcExHtmlShell.ts | Static HTML/CSS shell markup | | src/AcExOsnap*.ts | Object snap index and primitives | | src/AcExMeasurement.ts | Distance/area measurement in the offline viewer | | src/AcExMeasurementSidecar.ts | Measurement sidecar JSON import/export (*.measurement.json, compatible with cad-simple-viewer) | | src/AcExMarkup.ts | Design Review markup tools (cloud, callout, text, rect, circle, arrow, stamp) with sidecar JSON import/export | | src/AcExHtmlI18n.ts | English / Chinese / Czech / Turkish UI messages |

Role in MLightCAD

This package combines the export format / offline viewer runtime with viewer integration (plugin, snapshot builder, -chtml command). @mlightcad/cad-simple-viewer stays free of HTML export code; heavy export logic can be lazy-loaded. cad-viewer adds a chtml dialog command on top. @mlightcad/cad-simple-viewer-cli provides a Node/Playwright entry point for batch conversion via .scr scripts.

License

MIT