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

svg-shards

v0.3.1

Published

TypeScript OOP library for working with SVG as independent shards

Readme

SVG Shards

TypeScript library for working with SVG as independent, typed shards — parse, query, and manipulate each element with a clean OOP API.

Live Playground → — interactive tutorial with live SVG and API controls.

Try it online

Open the interactive playground to explore every core API with live controls, API log, and shareable lesson links (#basics, #reactive, etc.).

Local dev: npm run playground:dev → http://localhost:3001

Installation

npm install svg-shards

For reactive bindings (optional):

npm install svg-shards @preact/signals-core

Quick Start (npm)

import { createSvgShards } from 'svg-shards';

const svg = createSvgShards.fromElement(document.querySelector('#my-svg'));
if (!svg) throw new Error('No SVG found');

// Access shards by type
svg.elements.rect.forEach((rect) => {
    rect.fill = '#4a90d9';
    rect.width = 200;
});

svg.elements.circle[0].radius = 50;
svg.elements.circle[0].moveTo(100, 100);

// Flat list with labels
svg.getAll().forEach((entry) => console.log(entry.label, entry.type));

React / Angular (npm + bundler)

Use the core API inside your framework lifecycle. For fine-grained updates without re-rendering the whole component, use the reactive subpath:

import { createSvgShards } from 'svg-shards';
import { signal, bindProperty } from 'svg-shards/reactive';

// After mount — wrap an existing SVG in the DOM
const svg = createSvgShards.fromElement(svgRef.nativeElement, { observe: true });
const dot = svg!.getById('dot')!;

const cx = signal(50);
bindProperty(dot, 'cx', cx);

// Update from animation loop, user input, or Angular/React signals
cx.value = 120; // only the cx attribute updates in the DOM

Angular interop: pass an Angular signal() or computed() — they expose .value and work with bindProperty directly.

Vanilla JS (no bundler)

Load a single ESM bundle from a CDN:

<svg id="demo" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <circle id="dot" cx="50" cy="50" r="20" fill="#4a90d9" />
</svg>

<script type="module">
    import { createSvgShards, signal, bindProperty } from 'https://esm.sh/svg-shards/browser';

    const svg = createSvgShards.fromElement(document.getElementById('demo'));
    const dot = svg.getById('dot');

    const cx = signal(50);
    bindProperty(dot, 'cx', cx);

    document.getElementById('demo').addEventListener('click', () => {
        cx.value = cx.value + 10;
    });
</script>

Local file: import ... from './node_modules/svg-shards/dist/browser.mjs'

Reactive API

import { signal, batch, bindProperty, bindTransform, scheduleBatch } from 'svg-shards/reactive';
import { Transformation } from 'svg-shards';

const matrix = signal(Transformation.identity().rotate(45, 50, 50));
bindTransform(shard, matrix);

Features

  • Type-safe — typed classes for rect, circle, path, group, and more
  • Shard-oriented — each SVG element is an independent, manipulable object
  • Stable identity — shard wrappers reused across refresh() via WeakMap cache
  • Auto-sync — opt-in MutationObserver refresh (observe: true)
  • Reactive bindings — optional svg-shards/reactive with @preact/signals-core
  • Direct DOM accessshard.htmlNode always available
  • Zero core dependencies — reactive layer uses optional peer dep
  • Browser bundlesvg-shards/browser for CDN / <script type="module">
  • Highlight plugin — optional @svg-shards/highlighter with demo gallery

Scripts

| Command | Description | | -------------------------- | ----------------------------------------------------------- | | npm run build | Compile core library + browser bundle | | npm run build:all | Compile core + highlighter plugin | | npm run dev | Watch mode | | npm run test | Run tests (Vitest + jsdom) | | npm run lint | ESLint | | npm run playground:build | Build interactive playground → site/ | | npm run playground:dev | Serve playground at http://localhost:3001 | | npm run demo | Build and open highlighter demo at http://localhost:3000/ |

Documentation

License

MIT