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

@shapething/shacl-renderer

v2.0.0

Published

A SHACL toolkit.

Readme

@shapething/shacl-renderer

A SHACL toolkit for React. Give it a SHACL shapes graph and an RDF data graph and it renders a user interface for them:

  • edit – a form for creating or updating a resource,
  • view – a read-only presentation of a resource,
  • facet – faceted search/filtering over the instances in a graph.

Validation runs live as you edit. The package implements the SHACL 1.2 Core specification and the proposed SHACL-UI (shui:, http://www.w3.org/ns/shacl-ui/) extension: widget selection through declarative scoring, value-node labels via property roles, language resolution, and federated search.

Part of ShapeThing.

Install

npm install @shapething/shacl-renderer react react-dom

react and react-dom (^19) are peer dependencies.

Usage

import { ShaclRenderer, type SubmitResult } from "@shapething/shacl-renderer";
import "@shapething/shacl-renderer/style.css";
import { DataFactory } from "rdf-data-factory";

const factory = new DataFactory();

export function PersonForm() {
  return (
    <ShaclRenderer
      // Either graph can be a URL, a string of RDF (Turtle, JSON-LD, ...), an RdfStore or quads.
      shapesGraph={new URL("https://example.org/shapes.ttl")}
      dataGraph={new URL("https://example.org/people/alice.ttl")}
      focusNode={factory.namedNode("https://example.org/people/alice")}
      nodeShapes={[factory.namedNode("https://example.org/shapes#PersonShape")]}
      mode="edit" // "edit" | "view" | "facet"
      onSubmit={(result: SubmitResult) => {
        // result.dataGraph is a snapshot of the edited data;
        // result.additions / result.deletions are the quads that changed.
        console.log(result.additions, result.deletions);
      }}
    />
  );
}

ShaclRenderer accepts any subset of the Environment fields. Fields you leave out fall back to their defaults. When nodeShapes is omitted, it is resolved from the shapes that target the focusNode. The package also exports the types you need to configure it, write a custom widget, or write your own preprocessor: Environment, RawEnvironment, SubmitResult, Preprocessor, WidgetProps, WidgetComponent, WidgetMeta, Widgets, PropertyUIElement, and the values defaultPreprocessors, defaultWidgets, defaultEnvironment and minimalEnvironment.

Stylesheet

The components render into the light DOM and ship their styles as one stylesheet. Import it once, wherever your application loads global CSS:

import "@shapething/shacl-renderer/style.css";

Web component

For pages that don't use React themselves, a <shacl-renderer> custom element is also available. You still need to load the stylesheet and install react/react-dom, because the element uses them internally.

<link rel="stylesheet" href="/node_modules/@shapething/shacl-renderer/dist/style.css" />
<script type="module">
  import "@shapething/shacl-renderer/webcomponent";
</script>

<shacl-renderer
  shapes="/shapes.ttl"
  data="/alice.ttl"
  focus-node="https://example.org/people/alice"
  node-shapes="https://example.org/shapes#PersonShape"
  mode="edit"
></shacl-renderer>

Attributes cover the string and boolean settings. Anything else (pre-parsed stores, custom widgets, preprocessors, locale loaders) goes through the element's environment JavaScript property. Submitting dispatches a shacl-submit CustomEvent whose detail is the SubmitResult.

Tools

The ./tools entry point holds SHACL-driven code generation and conversion utilities. They live in a separate entry so the renderer bundle doesn't pull in their dependencies:

import { generate, jsToRdf, rdfToJs, shaclToType } from "@shapething/shacl-renderer/tools";
  • generate: generates fake data that conforms to a shape (uses @faker-js/faker).
  • jsToRdf / rdfToJs: convert between plain JavaScript objects and RDF, guided by a shape.
  • shaclToType: generates TypeScript type declarations from node shapes.

Astro content loader

The Node-only ./astro entry point builds on these tools: an Astro content loader with one entry per shape target (keyed by its IRI, read with rdfToJs), which can also write a zod schema for the collection (generated from shaclToType, needs ts-to-zod installed):

// src/content.config.ts
import { astroLoader } from "@shapething/shacl-renderer/astro";
import { defineCollection } from "astro:content";
import { PersonSchema } from "./person";

const people = defineCollection({
  // Paths are globs relative to the Astro project root.
  loader: astroLoader({
    shapes: "./src/rdf/person-shape.ttl",
    data: "./src/rdf/people/*.ttl",
    languages: ["en"],
    schemaFile: "./src/person.ts",
  }),
  schema: PersonSchema,
});

Funding

This project is funded through NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.

License

GPL-3.0-only