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

@opengeospatial/jsonld-ui-utils

v0.4.2

Published

A JavaScript/TypeScript library that renders JSON-LD feature data as interactive HTML tables and enriches them with semantic metadata (labels, descriptions) fetched from RDF sources.

Readme

@opengeospatial/jsonld-ui-utils

A JavaScript/TypeScript library that renders JSON-LD feature data as interactive HTML tables and enriches them with semantic metadata (labels, descriptions) fetched from RDF sources.

Features

  • Render JSON-LD objects as nested HTML tables
  • Resolve property names and values to their full URIs using JSON-LD contexts
  • Fetch RDF metadata (labels, descriptions) for resolved URIs
  • Multiple fallback mechanisms: direct fetch, RAINBOW proxy, SPARQL endpoint
  • Built-in caching to avoid redundant network requests
  • Leaflet plugin for GeoJSON layers with automatic popup tables

Installation

npm install @opengeospatial/jsonld-ui-utils
# or
yarn add @opengeospatial/jsonld-ui-utils

Optional peer dependencies

jsonld is an optional peer dependency. Install it if you need to fetch and resolve JSON-LD contexts by URL:

npm install jsonld

proj4 is an optional peer dependency required only when using the Leaflet plugin with non-WGS84 data:

npm install proj4

Browser (IIFE)

<!-- optional: library-provided styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.css"/>

<!-- optional: jsonld peer dep (needed for context URL resolution) -->
<script src="https://cdn.jsdelivr.net/npm/jsonld@8/dist/jsonld.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.min.js"></script>

This exposes jsonldUIUtils as a global variable.

Usage

Quick start

import { loadFeature, createPropertiesTable, augment } from '@opengeospatial/jsonld-ui-utils';

const { feature, context } = await loadFeature('https://example.org/features/my-feature.json');

const container = document.getElementById('feature');
createPropertiesTable(feature, container);
await augment(container, context);

Step by step

1. Load a JSON-LD feature

const { feature, context } = await loadFeature(featureUrl);

loadFeature fetches the document at featureUrl, extracts its @context, recursively loads and merges any referenced context URLs, and returns both the raw feature object and the resolved context.

2. Render the feature as an HTML table

const container = document.getElementById('feature');
createPropertiesTable(feature, container);

This builds a nested HTML table structure inside container. By default it reads from the properties field of the feature object. Pass propertiesField: null to use the entire feature object instead:

createPropertiesTable(feature, container, { propertiesField: null });

The generated elements carry CSS classes you can style:

| Class | Applied to | |---|---| | .object-properties | Wrapper <div> around the top-level table | | .object-table | <table> elements | | .object-property | Property name cells | | .object-value | Property value cells | | .literal-value | Scalar (non-object) values | | .array-entry | Entries within an array value |

Include dist/jsonld-ui-utils.css (or the CDN link above) for default styling of these classes.

3. Augment with semantic metadata

await augment(container, context, {
  fallbackSparqlEndpoints: 'https://example.org/sparql',
});

augment walks the table, resolves each property name and value to its full URI via the JSON-LD context, fetches RDF data for those URIs, and updates the HTML elements with human-readable labels, descriptions, and links.

During and after augmentation, elements receive additional CSS classes:

| Class | Meaning | |---|---| | .resource-loading | Fetch in progress | | .resource-resolved | Label successfully retrieved | | .resource-error | Fetch failed | | .resource-link | <a> added with the resolved URI |

Options

createPropertiesTable(feature, container, options?)

| Option | Type | Default | Description | |---|---|---|---| | propertiesField | string or null | 'properties' | Property on feature to use as the root object. Set to null to use the entire feature. |

augment(rootElem, context, options?)

| Option | Type | Default | Description | |---|---|---|---| | replaceElements | boolean | true | Replace element text with the resolved label. | | labelPredicates | string[] | SKOS prefLabel, DCT/DC title, SDO/FOAF name, RDFS label | RDF predicates checked when extracting a label. | | descriptionPredicates | string[] | SKOS definition, DCT/DC description, RDFS comment | RDF predicates checked when extracting a description. | | fallbackRainbowInstances | string or string[] | — | One or more RAINBOW proxy base URLs tried in order when a direct fetch returns no label. | | fallbackSparqlEndpoints | string or string[] | — | One or more SPARQL endpoint URLs tried in order as a last resort (DESCRIBE <uri>). |

Lower-level API

fetchResource(uri, options?)

Fetch RDF metadata for a single URI and return a ResourceData object:

interface ResourceData {
  uri: string;
  label: string | null;
  description?: string | null;
}
const data = await fetchResource('https://example.org/vocab/MyTerm', {
  fallbackSparqlEndpoints: 'https://example.org/sparql',
});
console.log(data.label); // e.g. "My Term"

loadContext(context)

Load and merge one or more JSON-LD contexts. Accepts a context object, a URL string, or an array of either:

const merged = await loadContext([
  'https://example.org/context1.json',
  'https://example.org/context2.json',
]);

Leaflet plugin

The Leaflet plugin creates a L.GeoJSON layer that automatically renders popup tables for each feature and augments them with RDF metadata.

Same package as above — no separate install needed. Import the plugin entry point:

import { createJsonLDGeoJSONLayer } from '@opengeospatial/jsonld-ui-utils/leaflet';

Browser (IIFE)

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.css"/>

<!-- optional: required only for non-WGS84 data (must come before the plugin) -->
<script src="https://unpkg.com/proj4@latest/dist/proj4.js"></script>

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils-leaflet.min.js"></script>

This exposes jsonldUIUtilsLeaflet as a global variable.

Usage

createJsonLDGeoJSONLayer returns a Promise<L.GeoJSON>:

const layer = await createJsonLDGeoJSONLayer(L, geojsonData, {
  ldContext: 'https://example.org/context.jsonld',
  popupOptions: { maxWidth: 420 },
  augmentOptions: {
    fallbackSparqlEndpoints: 'https://example.org/sparql',
  },
});

layer.addTo(map);

Or with .then():

createJsonLDGeoJSONLayer(L, geojsonData, options).then(layer => {
  layer.addTo(map);
  map.fitBounds(layer.getBounds());
});

Behaviour

  • Each feature with a non-empty properties object gets a popup with a rendered table.
  • If the feature has an id, it is shown as a hover tooltip automatically.
  • The popup table is augmented with RDF labels/descriptions when ldContext is provided.
  • For WGS84 data the function resolves immediately with no additional network requests.

CRS support (beta)

The plugin can render data in coordinate reference systems other than WGS84 by transforming geometries to WGS84 before passing them to Leaflet.

The CRS is detected automatically from the input data in priority order:

  1. JSON-FG coordRefSys — a URI string, a { "type": "Reference", "href": "...", "epoch": ... } object, or an array of these (compound CRS; the first EPSG entry is used)
  2. Legacy GeoJSON crs{ "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::XXXX" } }

If the detected CRS is not already registered with proj4, the plugin fetches its definition from epsg.io on first use and caches it for the lifetime of the page.

Requirements: proj4js must be available. In ESM/CJS projects install it as a peer dependency (npm install proj4). In browser IIFE usage, load the proj4 script before the plugin (see snippet above) so that window.proj4 is present.

// CRS is read automatically from data.crs or data.coordRefSys
const layer = await createJsonLDGeoJSONLayer(L, dataInEpsg5514, options);

// Or supply a CRS explicitly, bypassing auto-detection:
const layer = await createJsonLDGeoJSONLayer(L, data, {
  ...options,
  coordRefSys: 'EPSG:5514',
});

Per the JSON-FG scoping rules, a coordRefSys on an individual feature overrides the collection-level value for that feature's geometry.

Note: Coordinate epochs (present on some dynamic CRS references) are not supported by proj4js and are silently ignored with a console warning.

Options (JsonLDGeoJSONOptions)

| Option | Type | Default | Description | |---|---|---|---| | ldContext | string, object, or array | — | JSON-LD context (URL, object, or array) used to resolve property URIs. | | popupOptions | object | { maxWidth: 400 } | Options passed to Leaflet's bindPopup. | | augmentOptions | object | {} | Options passed to augment() (see above). | | onEachFeature | function | — | Called for every feature before the plugin's own logic, matching Leaflet's onEachFeature signature. | | coordRefSys | string | — | Override CRS detection with an explicit URI (e.g. "EPSG:5514"). | | proj4 | object | — | Inject a specific proj4 instance instead of using the auto-resolved one. |

Any other options are forwarded to L.geoJSON.


Demos

  • Basic demo — renders a JSON-LD feature as an augmented properties table
  • Leaflet demo — GeoJSON layer with popup tables and RDF augmentation
  • Leaflet CRS demo — GeoJSON layer in EPSG:5514 (Czech S-JTSK), auto-detected and reprojected to WGS84

Building from source

yarn install
yarn build      # produces dist/
yarn dev        # start dev server with live reload

License

See LICENSE.