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

@carbonenginejs/format-stl

v0.1.2

Published

STL format reader/writer with printability inspection helpers for CarbonEngineJS geometry data.

Readme

@carbonenginejs/format-stl

Pure-JavaScript CarbonEngineJS-facing package for the STL triangle-mesh format. It reads ASCII/binary STL, writes ASCII/binary STL from the shared CarbonEngineJS JSON mesh schema, and can inspect geometry for the common topology problems that block useful 3D prints.

CarbonEngine and Fenris Creations (CCP Games) are named in this package for interoperability and target-ecosystem context only. STL itself is not a CCP format, and this package contains no CarbonEngine or Fenris Creations (CCP Games) source code.

Package

Install

npm install @carbonenginejs/format-stl

Public API

The package root exports one public class: CjsFormatStl. The Cjs prefix marks this as a CarbonEngineJS format/construction boundary, not an engine runtime class.

import CjsFormatStl from "@carbonenginejs/format-stl";

const stl = new CjsFormatStl({
    emit: "json",             // "json" only for reads
    source: "mesh.stl",       // name written to grannyFileSource
    binary: true,             // true writes binary STL; false writes ASCII STL
    solidName: "mesh",
    scale: 1,
    recalculateNormals: true,
    weldVertices: false,      // false preserves STL facet normals on read
    weldTolerance: 1e-5,      // used by read welding and inspect topology
    skipDegenerate: true,
    requireWatertight: false, // true rejects writes with printability blockers
    classes: {
        Root: CjsGeometryRoot,
        Mesh: CjsGeometryMesh,
        IndexGroup: CjsGeometryIndexGroup
    }
});

const json = stl.Read(stlBytes);
const report = stl.Inspect(json);
const bytes = stl.Write(json, { requireWatertight: true });

The named export is the same class for callers that prefer named imports:

import { CjsFormatStl } from "@carbonenginejs/format-stl";

Format Rules

  • The package root exports one public format class: CjsFormatStl.
  • Instance methods are PascalCase because format instances can hydrate or sit beside CarbonClasses without colliding with camelCase data fields.
  • Static one-shot methods are camelCase because they live on CjsFormatStl itself, not on hydrated CarbonClass instances.
  • src/CjsFormatStl.js is the public format boundary. STL parser, writer, topology, and hydration helpers live under src/core.
  • Read / static read return the shared JSON schema. emit: "raw" is not exposed because parser state is intentionally internal.
  • Write / static write return Uint8Array for binary STL and string for ASCII STL.
  • Inspect / static inspect accepts STL text, STL bytes, a shared JSON root, or one shared JSON mesh.
  • ToJSON / static toJSON converts format output to JSON-compatible data. It is not an STL writer and does not return JSON text.

JSON Graph

STL is triangle-only. It cannot represent UVs, materials, bones, morph targets, animations, transforms, or tangent-space data. The read path emits the shared mesh-side schema with unsupported branches present as empty arrays:

Root
|-- grannyFileFormatRevision, grannyFileSource
|-- meshes: Mesh[]
|   |-- name, minBounds, maxBounds
|   |-- boneBindings: []
|   |-- morphTargets: []
|   |-- vertex: VertexChannels
|   |   |-- position, normal
|   |   |-- tangent: [], binormal: []
|   |   |-- texcoord0: [], texcoord1: []
|   |   `-- blendIndice: [], blendWeight: []
|   `-- indices: IndexGroup[]
|       `-- name, bytesPerIndex, faces
|-- models: []
`-- animations: []

IndexGroup.faces is a flat triangle-index array in groups of three.

STL Coverage

  • ASCII STL read/write
  • Binary STL read/write
  • Per-facet STL normals
  • Optional vertex welding on read
  • Shared JSON root or mesh input for writes
  • Node convenience helpers: readFile(path, options) and writeFile(path, input, options)
  • Sniff helpers: isStl(input) and isBinaryStl(input)

Printability Inspection

Inspect is deliberately conservative. It does not repair meshes, but it does tell callers whether a mesh has the obvious blockers before writing or sending it to a slicer:

  • open edges
  • non-manifold edges
  • inconsistent winding edges
  • degenerate triangles
  • shell count
  • unique vertex and edge counts
  • axis-aligned bounds

requireWatertight: true runs the same checks during Write and throws if the mesh is not closed and consistently wound.

Options

  • emit: "json" default. Other values currently throw.
  • source: default "memory". Written to grannyFileSource and reports.
  • binary: default true. true writes binary STL bytes; false writes ASCII STL text.
  • solidName: default "carbonenginejs". Used for ASCII solid names and the binary header.
  • scale: default 1. Applied when writing JSON geometry to STL.
  • recalculateNormals: default true. Writer recomputes STL facet normals from triangle winding. false uses averaged vertex normals when present.
  • weldVertices: default false. On read, false preserves each STL facet as separate vertices so facet normals remain exact. true welds matching positions by weldTolerance and regenerates vertex normals.
  • weldTolerance: default 1e-5. Used for read welding and inspect topology.
  • skipDegenerate: default true. Writer skips zero-area triangles.
  • requireWatertight: default false. Writer throws when inspection finds printability blockers.
  • classes: optional for new CjsFormatStl(options), Read, and static read. Accepted keys are Root, Mesh, and IndexGroup, exposed as CjsFormatStl.CLASS_KEYS.

Helper Direction

Cutting a model into printable pieces should be a higher-level geometry helper, not a half-hidden STL parser feature. The useful version needs plane or volume cuts, cap generation, consistent winding, optional alignment keys, and a fresh inspection pass for every produced piece.

Turning normal maps into real geometry is also a conversion helper rather than an STL feature. Normal maps describe surface direction, not direct height, so a good helper will need a base mesh or tessellated surface, UVs, tangent frames, height/displacement controls, and validation against the target print scale.

Both helpers should eventually live beside this package or in shared geometry math once @carbonenginejs/core-math exists.

Tests

npm test

Tests are fully self-contained and use inline geometry. They do not require local asset folders, network access, or game files.

License

MIT (see LICENSE and NOTICE).

This package contains no CarbonEngine or Fenris Creations (CCP Games) code. Its input/output shape targets the shared CarbonEngineJS JSON mesh schema used for CarbonEngine interoperability.