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

@isopodlabs/dwg

v1.2.1

Published

Self contained package for DWG reading, writing and manipulation.

Readme

@isopodlabs/dwg

npm version GitHub stars License

Reads AutoCAD DWG drawings, from R13 to R2018, and ASCII DXF files into the same TypeScript classes. It is written in TypeScript with no native code.

☕ Support My Work

If you use this package, consider buying me a cup of tea to support future updates!

Installation

npm install @isopodlabs/dwg

Supported files

| Format | Versions | |--------|----------| | DWG | R13 (AC1012), R14 (AC1014), R2000 (AC1015), R2004 (AC1018), R2007 (AC1021), R2010 (AC1024), R2013 (AC1027), R2018 (AC1032) | | DXF | ASCII DXF of any of those versions, and R12 |

Binary DXF, R13c3 (AC1013) DWG and DWGs before R13 are not read yet. Writing is not supported.

Reading a DWG

import { DWG, DRW_LINE } from '@isopodlabs/dwg';

const dwg = new DWG('drawing.dwg');
if (!await dwg.ready)
	throw new Error('not a DWG file of a supported version');

console.log(dwg.version);			// 1015 for R2000; see VER
console.log(dwg.vars.UCS.EXTMIN);	// header variables

for (const { h } of dwg.handles) {
	const obj = await dwg.get_object(h);
	if (obj instanceof DRW_LINE)
		console.log(obj.point1, obj.point2);
}

await dwg.close();

The file stays open so that objects can be read when they are asked for, so call close() when you are done.

ready resolves false if the file is not a DWG of a supported version. It rejects with an error that says what is wrong if the file is a DWG that cannot be read, for example if a section is corrupt.

DWG

class DWG {
	constructor(source: string | Uint8Array);		// a file name, or the file's bytes
	ready:				Promise<boolean>;
	version:			VER;
	maintenanceVersion:	number;
	vars:				HeaderVars;					// the header variables
	classes:			Map<number, MoveableClass>;	// the custom classes, by type number
	handles:			{h: number, loc: number}[];	// every object's handle and file location

	get_object(handle: number): Promise<Obj | undefined>;
	owned(owner: number, refs: H[], unsupported?: Map<string, number>): Promise<Entity[]>;
	contents(): Promise<{
		layers:			Map<string, DRW_LAYER>;
		blocks:			Map<string, {block: DRW_BLOCK_HEADER, entities: Entity[]}>;
		entities:		Entity[];						// model space's and the active paper space's
		unsupported:	Map<string, number>;			// entities not read, by the reason
	}>;
	close(): Promise<void>;

	// the symbol tables
	blocks:			Table<DRW_BLOCK_HEADER>;
	layers:			Table<DRW_LAYER>;
	textstyles:		Table<DRW_STYLE>;
	linetypes:		Table<DRW_LTYPE>;
	views:			Table<DRW_VIEW>;
	ucss:			Table<DRW_UCS>;
	vports:			Table<DRW_VPORT>;
	appids:			Table<DRW_APPID>;
	dimstyles:		Table<DRW_DIMSTYLE>;
	vpEntHeaders:	Table<DRW_VP_ENT_HDR>;
	// the entries of dictionaries
	groups:			Table<DRW_GROUP>;
	mlinestyles:	Table<DRW_MLINESTYLE>;
	layouts:		Table<DRW_LAYOUT>;
	plotsettings:	Table<DRW_PLOTSETTINGS>;
}

get_object decodes an object the first time it is asked for, and keeps it only while something else references it. It returns undefined for a handle that is not in the file, or an object of a type that has no class yet.

A Table holds the handles of a symbol table's records or a dictionary's entries, and iterates the objects:

for await (const layer of dwg.layers)
	console.log(layer.name, layer.color);

contents() gives the drawing in the shape a DXF has, so the same code can read either: every block's entities (from its list of handles, or before R2004 by following each entity's link to the next), with each entity's layer named, a polyline's vertices and an insert's attribs read into it, and an insert's block_name set. A DWG names every anonymous block *D, *T... and every layout's paper space *Paper_Space; contents() numbers each after the first from 0, as a DXF writer numbers them (though not with the same numbers). An entity whose layout is known not to be read, such as the modeler geometry R2013 keeps in its AcDs section, is counted in unsupported rather than failing the drawing. owned() is what it uses to read the entities a block header, polyline or insert owns.

Colours

An entity's or layer's color is a Color: an index into the AutoCAD Colour Index (ACI, as 0xRRGGBB), or a true colour. rgbOf(color, layerColor?) gives its 0xRRGGBB whichever it is, a BYLAYER one as the layer's, and undefined for BYBLOCK, which the insert decides.

Handles

Objects refer to one another by handle, a number that get_object looks up. An entity's layer, for example, is entity.layerH, and await dwg.get_object(entity.layerH) is its DRW_LAYER. Fields that hold a handle directly as read from the file are H objects, whose offset() is the handle and whose get_offset(obj.handle) resolves one that is relative to the object holding it.

Important handles in the header include vars.BLOCK_MODEL_SPACE and vars.BLOCK_PAPER_SPACE (the block records of model and paper space), and the table controls such as vars.LAYER_CONTROL.

Reading a DXF

import { readFileSync } from 'fs';
import { DXF, DRW_CIRCLE } from '@isopodlabs/dwg';

const dxf = DXF.read(readFileSync('drawing.dxf', 'utf8'));
for (const e of dxf.entities)
	if (e instanceof DRW_CIRCLE)
		console.log(e.centre, e.radius);

DXF

class DXF {
	static read(data: string | Uint8Array): DXF;
	version:		VER;
	vars:			Map<string, DXFRecord>;						// header variables, by name
	tables:			Map<string, Obj[]>;							// symbol tables, by name
	layers:			Map<string, Obj>;							// layers, by name
	blocks:			Map<string, {block: Obj, entities: Obj[]}>;	// blocks, by name
	entities:		Obj[];										// the ENTITIES section
	objects:		Obj[];										// the OBJECTS section
	unsupported:	Map<string, number>;						// types that have no class yet, with counts
}

A DXF entity names its layer and linetype (layer, linetype) where a DWG one holds their handles. A POLYLINE's vertices are in its vertices, and an INSERT's attributes in its attribs. Angles are converted to radians, as a DWG stores them.

Objects

Every object is an Obj, and every entity is also an Entity:

class Obj {
	handle:		number;
	parentH:	number;							// the owner
	reactors:	number[];
	xdict?:		number;							// the extension dictionary
	eed?:		Map<number, Resbuf[]>;			// extended data, by application handle
}

class Entity extends Obj {
	entmode:		number;						// 0: owned by parentH, 1: paper space, 2: model space
	invisible:		boolean;
	color?:			Color;
	layerH:			number;
	linetypeH:		number;
	linetypeScale:	number;
	lWeight:		LineWidth;
	plotstyleH, materialH, shadowH: number;
	graphics_data?:	Uint8Array;					// proxy or preview graphics
}

interface Color {
	index:		number;							// the colour index: 0 by block, 256 by layer
	rgb?:		number;
	name?:		string;
	book_name?:	string;
	alpha?:		number;
	handle?:	H;
}

Entities

| Class | DWG type | Main fields | |-------|----------|-------------| | DRW_LINE | LINE | point1, point2, thickness, ext_point | | DRW_POINT | POINT | point, thickness, x_axis | | DRW_CIRCLE | CIRCLE | centre, radius | | DRW_ARC | ARC | centre, radius, angle0, angle1 | | DRW_ELLIPSE | ELLIPSE | point1 (centre), point2 (major axis), ratio, angle0, angle1 | | DRW_LWPOLYLINE | LWPOLYLINE | vertlist (x, y, bulge, width0, width1), closed, elevation | | DRW_POLYLINE_2D, _3D, _PFACE, _MESH | POLYLINE | handles of the vertices; DXF: vertices | | DRW_VERTEX_2D, _3D, _MESH, _PFACE, _PFACE_FACE | VERTEX | point, flags; 2D: bulge, widths | | DRW_SPLINE | SPLINE | degree, knots, ctrl_pts (with weights w) or fit_pts | | DRW_TEXT | TEXT | text, insert_point, height, angle, styleH | | DRW_MTEXT | MTEXT | text, point1, height, widthscale, styleH | | DRW_ATTRIB, DRW_ATTDEF | ATTRIB, ATTDEF | text fields, tag; ATTDEF: prompt | | DRW_INSERT, DRW_MINSERT | INSERT, MINSERT | block (handle), base_point, scale, angle; MINSERT: rows and columns | | DRW_BLOCK, DRW_ENDBLK, DRW_SEQEND | BLOCK, ENDBLK, SEQEND | BLOCK: name | | DRW_SOLID, DRW_TRACE | SOLID, TRACE | point1–point4, elevation, thickness | | DRW_FACE_3D | 3DFACE | point1–point4, invisibleflag | | DRW_RAY, DRW_XLINE | RAY, XLINE | point1, point2 (direction) | | DRW_HATCH | HATCH | loops (lines, arcs, ellipses, splines or polylines), pattern, solid, seeds | | DRW_DIMENSION_* | DIMENSION | text_midpt, user_text, styleH, blockH, and the points of each kind | | DRW_LEADER | LEADER | vertexlist, annot_type, AnnotH, styleH | | DRW_IMAGE, DRW_WIPEOUT | IMAGE, WIPEOUT | point1, u_vector, v_vector, size, clip_verts | | DRW_VIEWPORT | VIEWPORT | point, pssize, view | | DRW_MULTILEADER | MULTILEADER | leaders (lines of points), content (text or block), style overrides | | DRW_ARC_DIMENSION | ARC_DIMENSION | as the other dimensions, and the arc's centre and parameters | | DRW_HELIX | HELIX | the fields of a spline, and axis_base_pt, radius, turns, turn_height | | DRW_MLINE | MLINE | verts, each with its direction, miter and the parameters of each line | | DRW_TOLERANCE | TOLERANCE | ins_pt, x_direction, text | | DRW_MESH | MESH | vertex, faces, edges, crease | | DRW_SOLID_3D, DRW_REGION, DRW_BODY, DRW_PLANESURFACE | 3DSOLID, REGION, BODY, PLANESURFACE | acis (SAT text or SAB bytes), wireframe | | DRW_LIGHT | LIGHT | type, position, target, intensity, color, photometric | | DRW_PDFUNDERLAY | PDFUNDERLAY | definition, ins_pt, scale, angle, clip_verts | | DRW_OLE2FRAME | OLE2FRAME | type, data | | DRW_SECTIONOBJECT | SECTIONOBJECT | verts, vert_dir, top_height, bottom_height |

Table records and other objects

DRW_BLOCK_HEADER, DRW_LAYER, DRW_STYLE, DRW_LTYPE, DRW_VIEW, DRW_UCS, DRW_VPORT, DRW_APPID, DRW_DIMSTYLE and DRW_VP_ENT_HDR are table records, each with a name. A block record lists its entities in entities (R2004 and later) or links its first and last in first_last.

The table control objects (ObjControl) and DRW_DICTIONARY give the handles of what they hold in handles; a dictionary also has the entry names. DRW_XRECORD holds data, its group codes and values (Resbufs).

The other objects read are layouts and plot settings; groups; multiline, table, multileader, visual, section view and detail view styles and cell style maps; materials; scales; dictionary variables; fields and field lists; image definitions and reactors; sort tables; spatial filters and indexes; layer indexes; colours; raster variables; the annotation scale contexts of text, dimensions and leaders; geographic data; the sun; render settings and entries; section managers and settings; table geometry; the parameters, grips and evaluation graphs of dynamic blocks; the history of solids; and the associative network: actions, dependencies and action parameters.

ACAD_TABLE is read only as far as the fields every entity has; its graphics are in its anonymous block. A few types are read no further than that, and some newer or third party types have no class: for these get_object returns undefined. Where a file has something whose layout is not known, such as the modeler geometry R2013 keeps in its AcDs section, reading it throws an error saying it is not supported.

Versions

VER names the versions by their release (VER.R2000 is 1015, VER.R2018 is 1032), so versions compare as numbers:

if (dwg.version >= VER.R2007)
	...

License

This project is licensed under the MIT License.