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

brepjs-families

v0.12.0

Published

Declarative family layer for brepjs: element trees, key paths, and projection onto the content-addressed CSG IR

Readme

brepjs-families

Experimental satellite package, published to npm. Early-stage; the API may change.

npm install brepjs-families brepjs

The declarative family layer for brepjs: element trees, key paths, and projection onto the content-addressed CSG IR. You describe a model as a tree of typed elements; resolution turns it into geometry plus durable identity that a BIM export can rely on.

Pipeline: author families → element tree → resolve() (geometry + key paths + relationships) → evaluateModel() (meshes for the viewport) or familiesToBim() in brepjs-bim (IFC export).

The model in one example

import { csg } from 'brepjs';
import { family, el, resolve, evaluateModel, tTranslate, type Element } from 'brepjs-families';

const Door = family<{ width: number; height: number; at: readonly [number, number] }>(
  'Door',
  (p) =>
    el('Box', {
      size: [p.width, 300, p.height],
      transform: [tTranslate([p.at[0], 0, p.at[1]])],
    }),
  { role: 'fill' }
);

const Wall = family<{ length: number; height: number; voids?: readonly Element[] }>('Wall', (p) =>
  el('Box', { size: [p.length, 200, p.height], voids: p.voids ?? [] })
);

const Storey = family<{ items: readonly Element[] }>('Storey', (p) => el('Group', {}, p.items));

const tree = resolve(
  Storey({
    key: 'ground',
    items: [
      Wall({
        key: 'south',
        length: 4000,
        height: 2700,
        voids: [Door({ key: 'entry', width: 1000, height: 2100, at: [1500, 0] })],
      }),
    ],
  })
);

using ev = new csg.Evaluator();
const model = evaluateModel(tree, ev);
model.byKeyPath.get('ground/south'); // mesh + identity for the wall

What the pieces buy you:

  • Families are typed, validated constructors (family(name, render, { props }) takes a zod schema). Invalid props fail at construction, not at export.
  • Composition is structural: a family receives its JSX (or children: prop) children in props.children, a parent's transform carries every descendant with it (translate + tRotate), and fragments inline without touching key paths. A composed family places as a unit while identical children keep sharing one materialization.
  • Identity props (name, psets, material, classification) are accepted by every family and ride past schema validation into ResolvedElement.attributes, so a component carries IFC-facing data without declaring it in its schema; a BIM projection consumes them (storey names, common psets, custom psets, material fallback).
  • Key paths (ground/south/voids:entry) are order-independent identity. Reorder siblings and every element keeps its identity; a BIM projection derives stable IFC GlobalIds from them.
  • The CSG IR is content-addressed: two identical walls evaluate once and share one materialization, while each keeps its own identity.
  • Fill roles make openings real: a role: 'fill' family inside a wall's voids synthesizes an Opening element with a Fills relationship, which a BIM export turns into IfcOpeningElement + IfcRelFillsElement rather than an anonymous boolean hole.
  • Archetypes decouple routing from naming: family('Level', render, { archetype: 'storey' }) still exports as IfcBuildingStorey. The value is an opaque string here (this layer never interprets one), which is what lets the registry's copy-in files be renamed without losing their BIM mapping.
  • JSX optional: jsxImportSource: "brepjs-families" lets you write the same trees as JSX. The plain-function API is primary.

Starter registry

A copy-in starter registry (storey, wall, slab, column, beam, roof, stair, door, window, and room families, spec-shaped props feeding the IFC specs in brepjs-bim 1:1) is distributed shadcn-style, not inside this package: the families become source files you own. npm create brepjs scaffolds a working project, then npx brepjs add wall room copies family sources into src/families/, resolving the registry from GitHub by default or from any static host via --registry. See Copy-In Distribution.

BIM projection

brepjs-bim's familiesToBim() projects a resolved tree into a BimModel: storeys, walls, slabs, columns, beams, roofs, stairs, and wall openings, with property sets, materials, spatial containment, and reorder-stable GlobalIds, exportable to IFC with independent validation. See the families docs and for BIM professionals.

Docs

MIT