Skip to content

Headless API

The headless API (@polycss/core) gives you direct access to polycss parsers and utilities without React, Vue, or any framework. All exports are also available from polycss (the vanilla package) so vanilla users install just one package.

Parses an OBJ file text string into a ParseResult.

import { parseObj } from "@polycss/core";
const text = await fetch("/cottage.obj").then(r => r.text());
const { polygons, warnings, dispose } = parseObj(text, {
targetSize: 60,
defaultColor: "#cccccc",
});
// polygons — Polygon[] ready for rendering
// warnings — non-fatal issues found during parse
dispose(); // revoke any blob URLs (OBJ rarely creates them)

Options: See ObjParseOptions.


Parses a GLB or glTF file into a ParseResult. Accepts ArrayBuffer or Uint8Array.

import { parseGltf } from "@polycss/core";
const buf = await fetch("/model.glb").then(r => r.arrayBuffer());
const { polygons, objectUrls, dispose } = parseGltf(buf, {
targetSize: 60,
baseUrl: new URL("/model.glb", location.href).href,
});
// polygons — Polygon[]
// objectUrls — blob: URLs for embedded textures (auto-revoked by dispose())
dispose(); // always call on cleanup

Options: See GltfParseOptions.


Parses an MTL file text string into a material map.

import { parseMtl } from "@polycss/core";
const { colors, textures } = parseMtl(mtlText);
// colors — Record<materialName, cssColor>
// textures — Record<materialName, imagePath>

High-level convenience function: fetches a URL, detects OBJ vs GLB/glTF by extension (.obj, .glb, .gltf), parses it, and returns a ParseResult.

import { loadMesh } from "@polycss/core";
const { polygons, dispose } = await loadMesh("/cottage.glb", {
targetSize: 60,
baseUrl: new URL("/cottage.glb", location.href).href,
});
// use polygons...
dispose(); // always call on cleanup

Validates a polygon array. Drops degenerate polygons (collinear, zero-area), auto-triangulates non-coplanar N-gons via fan decomposition, and strips UV arrays that don’t match vertices.length. Returns the validated polygons plus a list of human-readable warnings describing every change made.

import { normalizePolygons } from "@polycss/core";
import type { Polygon } from "@polycss/core";
const raw: Polygon[] = [
{ vertices: [[0,0,0],[1,0,0],[0,1,0]], color: "#f00" },
{ vertices: [[0,0,0],[0,0,0],[0,0,0]] }, // degenerate — will be dropped
];
const { polygons, warnings } = normalizePolygons(raw);
warnings.forEach(w => console.warn(w));

Merges coplanar adjacent polygons that share the same material (color + texture). Reduces DOM element count on large flat surfaces without changing visual output. UV-aware.

import { mergePolygons } from "@polycss/core";
const merged = mergePolygons(polygons);
console.log(`${polygons.length} polygons → ${merged.length} after merge`);

Creates an isometric-style camera state object. Used internally by the imperative createPolyScene API and by <PolyCamera> (React / Vue).

import { createIsometricCamera } from "@polycss/core";
const cam = createIsometricCamera({
rotX: 65,
rotY: 45,
});
// cam.state — current CameraState
// cam.update(partial) — merge partial state
// cam.getStyle(...) — returns CSS property map

Register the <poly-scene>, <poly-mesh>, and <poly-polygon> custom elements by importing the side-effect entry point:

<script type="module" src="https://esm.sh/polycss/elements"></script>
<poly-scene perspective="1000" rot-x="65" rot-y="45">
<poly-mesh src="/cottage.glb"></poly-mesh>
</poly-scene>

See the polycss README for the full custom element attribute reference.


Import pathContents
@polycss/reactReact components: PolyScene, PolyMesh, Poly, PolyCamera, hooks
@polycss/vueVue components: PolyScene, PolyMesh, Poly, PolyCamera
polycssVanilla imperative API + custom element classes
polycss/elementsSide-effect: registers <poly-scene>, <poly-mesh>, <poly-polygon>
@polycss/corePure parsers / math, zero DOM — parseObj, parseGltf, loadMesh, types