A framework-agnostic CAD/DXF/DWG file viewer for the web.
@cadview/dwg, LibreDWG compiled to WebAssembly| Package | Description | Version |
|---|---|---|
@cadview/core |
Core engine — DXF parser, Canvas 2D renderer, interactive viewer | |
@cadview/react |
React component and hook | |
@cadview/svelte |
Svelte 5 component | |
@cadview/vue |
Vue 3 component and composable | |
@cadview/dwg |
DWG file support via LibreDWG WASM (GPL-3.0) |
npm install @cadview/core
npm install @cadview/dwg # optional — adds DWG file support
import { CadViewer } from '@cadview/core';
import { dwgConverter } from '@cadview/dwg'; // optional
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const viewer = new CadViewer(canvas, {
theme: 'dark',
formatConverters: [dwgConverter], // enables .dwg file loading
});
// Load from File input (.dxf or .dwg)
const input = document.querySelector('input[type="file"]')!;
input.addEventListener('change', async () => {
const file = (input as HTMLInputElement).files?.[0];
if (file) await viewer.loadFile(file);
viewer.fitToView();
});
// Or load from URL
const response = await fetch('/drawing.dxf');
const buffer = await response.arrayBuffer();
await viewer.loadBuffer(buffer);
viewer.fitToView();
// Interact
viewer.setTheme('light');
viewer.setTool('select'); // 'pan' | 'select' | 'measure'
viewer.on('select', (e) => console.log('Selected:', e.entity.type));
viewer.on('measure', (e) => console.log('Distance:', e.distance));
// Cleanup
viewer.destroy();
npm install @cadview/core @cadview/react @cadview/dwg
import { useState } from 'react';
import { CadViewer } from '@cadview/react';
import { dwgConverter } from '@cadview/dwg';
function App() {
const [file, setFile] = useState<File | null>(null);
return (
<div style={{ width: '100%', height: '100vh' }}>
<input
type="file"
accept=".dxf,.dwg"
onChange={(e) => setFile(e.target.files?.[0] ?? null)}
/>
<CadViewer
file={file}
theme="dark"
tool="pan"
formatConverters={[dwgConverter]}
onSelect={(e) => console.log('Selected:', e.entity.type)}
onMeasure={(e) => console.log('Distance:', e.distance)}
/>
</div>
);
}
npm install @cadview/core @cadview/svelte @cadview/dwg
<script>
import { CadViewer } from '@cadview/svelte';
import { dwgConverter } from '@cadview/dwg';
let file = $state(null);
</script>
<input type="file" accept=".dxf,.dwg" onchange={(e) => file = e.target.files?.[0]} />
<div style="width: 100%; height: 100vh;">
<CadViewer
{file}
theme="dark"
tool="pan"
formatConverters={[dwgConverter]}
onselect={(e) => console.log('Selected:', e.entity.type)}
onmeasure={(e) => console.log('Distance:', e.distance)}
/>
</div>
npm install @cadview/core @cadview/vue @cadview/dwg
<template>
<input type="file" accept=".dxf,.dwg" @change="onFileChange" />
<CadViewer
:file="file"
theme="dark"
tool="pan"
:formatConverters="[dwgConverter]"
@select="(e) => console.log('Selected:', e.entity.type)"
@measure="(e) => console.log('Distance:', e.distance)"
/>
</template>
<script setup>
import { ref } from 'vue';
import { CadViewer } from '@cadview/vue';
import { dwgConverter } from '@cadview/dwg';
const file = ref(null);
function onFileChange(e) {
file.value = e.target.files?.[0] ?? null;
}
</script>
| Entity | Description |
|---|---|
LINE |
Line segments |
CIRCLE |
Full circles |
ARC |
Circular arcs |
LWPOLYLINE |
Lightweight polylines (with bulge arcs) |
POLYLINE |
Legacy polylines |
ELLIPSE |
Ellipses and elliptical arcs |
SPLINE |
B-splines (NURBS) |
TEXT |
Single-line text |
MTEXT |
Multi-line formatted text |
INSERT |
Block references (with MINSERT grid) |
DIMENSION |
Dimension annotations (via geometry blocks) |
HATCH |
Hatch fills (line, arc, and circle boundary edges) |
POINT |
Point markers |
# Clone the repo
git clone https://github.com/wiscaksono/cadview.git
cd cadview
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Start the demo app (localhost:5173)
pnpm dev
| Command | Description |
|---|---|
pnpm build |
Build all packages |
pnpm dev |
Start all packages in watch mode + demo app |
pnpm test |
Run tests across all packages |
pnpm typecheck |
Type-check all packages |
pnpm clean |
Remove all dist folders and caches |
cadview/
├── packages/
│ ├── core/ # @cadview/core — parser, renderer, viewer (MIT)
│ ├── react/ # @cadview/react — React wrapper (MIT)
│ ├── svelte/ # @cadview/svelte — Svelte 5 wrapper (MIT)
│ ├── vue/ # @cadview/vue — Vue 3 wrapper (MIT)
│ └── dwg/ # @cadview/dwg — DWG support via LibreDWG WASM (GPL-3.0)
├── apps/
│ └── homepage/ # Homepage & live demo (SvelteKit)
└── docs/ # Design documents & plans
MIT — core, react, svelte, and vue packages.
GPL-3.0 — @cadview/dwg package (due to LibreDWG dependency). This package is fully optional — the core viewer works without it.