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

@openhi/ours

v0.1.1

Published

The Open Unified Resource Standard in TypeScript: resource shapes, ontology assembly, and the checks a publisher should pass before publishing.

Readme

@openhi/ours

The Open Unified Resource Standard in TypeScript: the resource shapes, a way to assemble an ontology from documents however you obtained them, and the cross-resource checks a publisher should pass before publishing.

OURS is a shared format for describing which standards you use, how you use them, and how data moves between them, so another system can integrate without asking you first.

npm install @openhi/ours

Full documentation, including the specification itself, is at ours.dev.

Reading a published ontology

An ontology is discoverable from a domain alone, at /.well-known/ours.json.

import { assembleBundle, wellKnownOntologyUrl } from "@openhi/ours";

const get = (url: string) => fetch(url, { redirect: "follow" }).then((r) => r.json());

const ontology = await get(wellKnownOntologyUrl("example.org"));
const models = await get(ontology.models);

const bundle = assembleBundle({ ontology, models: [models] });

for (const model of bundle.models.values()) {
  console.log(model.name, model.mapsTo?.map((m) => m.schema));
}

assembleBundle takes documents, not URLs or paths. Transport is deliberately not this package's business: the same ontology may be read from disk, fetched over HTTP, or built in memory by a generator, and all three should produce the same object.

A document may be a single resource or a collection Bundle; resourcesIn unwraps either, so a reader never has to care which a publisher chose.

Publishing nothing, explicitly

models, vocabularies and mappings are all required on an Ontology. A publisher with no vocabularies serves an empty collection at the URL rather than leaving the pointer out:

import { emptyBundle } from "@openhi/ours";

// GET https://ours.example.org/vocabularies.json
serve(emptyBundle());

An absent URL cannot be told apart from one that has not been published yet, so a consumer would have to guess whether to keep looking. An empty bundle at a live URL is a definite answer, and the point of the format is that nobody should have to ask.

Validating before you publish

Parsing tells you a model is well formed. It cannot tell you the schema it points at was actually published, or that a relationship names a model that exists. Those are the failures a consumer meets as a broken integration rather than as a parse error.

import { validateBundle, hasErrors } from "@openhi/ours";

const issues = validateBundle(bundle);
if (hasErrors(issues)) {
  for (const issue of issues) console.error(issue.level, issue.resource, issue.message);
  process.exit(1);
}

Errors are things that will break a consumer. Warnings are things worth knowing: a model with no mapsTo is valid, but it is invisible to the integration OURS exists to enable. Pass { warnOnMissingMapsTo: false } for an ontology that is deliberately all your own.

Vocabularies are JSON Schema

Every Vocabulary also serialises to an ordinary JSON Schema enumeration, published beside it as .schema.json. A model binds a property to it with a plain $ref, so any off-the-shelf validator enforces the codes without knowing what OURS is.

import { vocabularySchemaFor, vocabularySchemaUrl } from "@openhi/ours";

What is here

| Export | | |---|---| | ontologySchema, modelSchema, vocabularySchema, bundleSchema | The resource shapes, as zod schemas | | wellKnownOntologyUrl | Find an ontology from a domain alone | | parseResource, resourcesIn | Read one document, whatever kind it is | | assembleBundle, toPublishedBundles | In-memory ontology, and back again | | validateBundle, hasErrors | Cross-resource checks | | walkSchema, refsIn, resolveRef | JSON Schema helpers | | walkSchemaInScope, scopedRefsIn, declaredIds | The same, aware of $id scope |

Types are exported alongside every schema. The API reference covers each one.

License

MIT. Copyright OpenHI, Inc.