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

ontology-store

v0.1.2

Published

a client-side RDF store with an OWL API

Readme

ontology-store.js

A fully persistent, immutable RDF store with an OWL API. Check out the docs here (WIP)

ontology-store.js is browser-compatible (non-SPARQL compliant) RDF store specialized for reading and editing the Web Ontology Language (or OWL).

ontology-store.js understands RDF and OWL so you don't have to.

This library:

  1. Reads in an RDF graph (either from an RDF serialization or a JS structure) and stores it into a fully-persistent data structure.
  2. Provides an OWL API to read and write from the data structure using OWL constructs.
  3. Writes the modified graph or sub-graph to a valid RDF serialization (provided by N3.js) or a JS structure.

DISCLAIMER

This library is just in its beginning state. There are performance issues and it has yet to be fully tested. Feel free to contribute and open issues discussing features you'd like to see.

Thank you!

Quick example

// simple example for use within node
const OntologyStore = require('ontology-store');

const ab = 'http://ontology-store.js.org/tests#';
const rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
const rdfs = 'http://www.w3.org/2000/01/rdf-schema#';
const owl = 'http://www.w3.org/2002/07/owl#';

const prefixes = `
@prefix ab:   <${ab}> .
@prefix rdf:  <${rdf}> .
@prefix rdfs: <${rdfs}> .
@prefix owl: <${owl}> .`;

const example = `
  ${prefixes}

  # ontology definition
  ab:ExampleOntology
    a owl:Ontology ;
    rdfs:label "Example Ontology" ;
    rdfs:comment "this is an example ontology" .

  ab:BusinessEntity
    a owl:Class ;
    rdfs:comment "something that belongs to a business or firm" ;
    rdfs:label "Business Entity" .

  # simple class with owl:Class assertion
  ab:Person
    a owl:Class ;
    rdfs:label "Person" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  # subclass
  ab:Employee
    a owl:Class ;
    rdfs:subClassOf ab:Person ;
    rdfs:subClassOf ab:BusinessEntity ;
    rdfs:label "Employee" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  ab:Contractor
    # purposely omit, "a owl:Class"
    rdfs:subClassOf ab:Employee ;
    rdfs:label "Contractor" ;
    rdfs:comment "a contractor is a subclass of an employee" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  ab:HourlyEmployee
    a owl:Class ;
    rdfs:isDefinedBy ab:ExampleOntology ;
    rdfs:subClassOf ab:Employee ;
    rdfs:label "Hourly Employee" .

  ab:SalariedEmployee
    a rdfs:Class ;
    rdfs:subClassOf ab:Employee ;
    rdfs:isDefinedBy ab:ExampleOntology ;
    rdfs:label "Salaried Employee" .

  # simple class with rdfs:Class assertion
  ab:Product
    a rdfs:Class ;
    rdfs:label "Product" ;
    rdfs:isDefinedBy ab:ExampleOntology .
  
  # object property defined with owl:ObjectProperty and rdf:Property
  ab:worksOn
    a owl:ObjectProperty ;
    a rdf:Property ;
    rdfs:domain ab:Employee ;
    rdfs:range ab:Product ;
    rdfs:label "works on" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  # simple rdf:Property
  ab:additionalComments
    a rdf:Property ;
    rdfs:label "additional comments" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  ab:workedOnBy
    a owl:ObjectProperty ;
    rdfs:domain ab:Product ;
    rdfs:range ab:Employee ;
    rdfs:inverseOf ab:worksOn ;
    rdfs:label "worked on" ;
    rdfs:isDefinedBy ab:ExampleOntology .

  # owl datatype property defined with owl:DatatypeProperty
  ab:startDate
    a owl:DatatypeProperty ;
    rdfs:domain ab:Employee ;
    rdfs:label "start date" ;
    rdfs:isDefinedBy ab:ExampleOntology .
`;

OntologyStore.parse(example).then(store => {
  // ===============================================================================================
  // READ ONTOLOGY
  // ===============================================================================================
  /** the first class in the set of all classes */
  const employee = store.classes.get(`${ab}Employee`);
  console.log(employee.label); // logs `Employee`

  // get a list of subclass labels
  const employeeSubclasses = employee.subClasses.seq().map(subclass => subclass.label).toArray();
  console.log(employeeSubclasses.join(', ')) // logs `Contractor, HourlyEmployee, SalariedEmployee`

  // serialize the subset
  employee.subClasses.serialize().then(result => console.log(result));
  /* #result is this:
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
  @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
  @prefix owl: <http://www.w3.org/2002/07/owl#>.

  <http://ontology-store.js.org/tests#Contractor> rdfs:subClassOf <http://ontology-store.js.org/tests#Employee>;
      rdfs:label "Contractor";
      rdfs:comment "a contractor is a subclass of an employee";
      rdfs:isDefinedBy <http://ontology-store.js.org/tests#ExampleOntology>.
  <http://ontology-store.js.org/tests#HourlyEmployee> a owl:Class;
      rdfs:isDefinedBy <http://ontology-store.js.org/tests#ExampleOntology>;
      rdfs:subClassOf <http://ontology-store.js.org/tests#Employee>;
      rdfs:label "Hourly Employee".
  <http://ontology-store.js.org/tests#SalariedEmployee> a rdfs:Class;
      rdfs:subClassOf <http://ontology-store.js.org/tests#Employee>;
      rdfs:isDefinedBy <http://ontology-store.js.org/tests#ExampleOntology>;
      rdfs:label "Salaried Employee".
  */

  // ===============================================================================================
  // MODIFY ONTOLOGY
  // ===============================================================================================
  
  // changes are done immutably
  const newStore = employee.subClasses.create({
    label: 'New Sub Employee',
    comment: 'represents a sub employee',
    definedBy: ontologies => ontologies.seq().first(),
    thenConsume: newSubClass => {
      newSubClass.serialize().then(result => console.log(result));

      /* # results in:
      @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
      @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
      @prefix owl: <http://www.w3.org/2002/07/owl#>.

      <http://ontology-store.js.org/tests#ExampleOntologyf8affcf7-412c-4c42-945e-6edd50166ff6-New%20Sub%20Employee> rdfs:
      isDefinedBy <http://ontology-store.js.org/tests#ExampleOntology>;
          a owl:Class, rdfs:Class;
          rdfs:subClassOf <http://ontology-store.js.org/tests#Employee>;
          rdfs:label "New Sub Employee";
          rdfs:comment "represents a sub employee".
      */
    }
  });

  // do something with `newStore`
  // `store` remains unchanged
});

Install

This library is built using the UMD module definition to allow maximum compatibly.

Please ensure that you have your proxy settings correct before installing.

If you're not using a module system, the library will be available via the global OntologyStore.

npm and/or node

npm install --save ontology-store

then use like so:

const OntologyStore = require('ontology-store');

bower

bower install --save ontology-store.js

then you can use it in a script tag like so:

<script src="./bower_components/ontology-store/docs/ontology-store.js"></script>

or just download the minified JS

Here you go!

Motivation

Supporting an ontology editor user interface requires us to create, edit, and store a valid RDF graph that is aware of supported OWL constructs.

This RDF store is tailored towards building ontologies (metadata) written in OWL and not storing any arbitrary RDF graph (e.g. instances). This RDF store exposes an OWL-aware API to allow for easy access and manipulation of the RDF graph with respect to OWL constructs. Additionally, this RDF store has the ability to both parse and serialize to and from a valid RDF serialization.

So overall, the purpose of this code is to:

  1. provide a backend to parse, store, and serialize an RDF graph of OWL terms and to
  2. provide an API to manipulate an OWL/RDF graph

Design goals (desired features)

  1. Parse and serialize any RDF graph. This does not mean the has to be able to edit/visualize every triple but it should be able to read, store, and re-write an RDF graph without deleting triples. This also requires bnode support.
  2. Store as a fully persistent RDF graph to allow for arbitrary undos and redos. This undo/redo requirement causes a lot of positive and negative trade-offs that will be (TODO) discussed later in this doc.
  3. Allow manipulation of the RDF graph through 'resource sets'. A 'resource set' is an arbitrary set of resources (a resource is simply a node in the RDF graph identified by a URI) that can be manipulated by adding or removing individual resources. An example of a resource set could be the subclasses of "Animal" that could include the resources "Dog" and "Cat". The API should then allow the user to add another resource (e.g. "Bird") or remove the existing resources (i.e. "Dog" and "Cat").
  4. Support for importing other RDF graphs. Terms from other graphs should be reusable in the current graph. Importing isn't simply copying all the terms from one graph into the current graph but bring external terms into the scope of the current graph. The classes and properties of the imported graph don't necessarily have to be completely readonly because assertions made in the current graph will have a different namespace than the external graph therefore eliminating conflicts. Additionally, terms from other graphs should not be copied into the serialization of the current ontology but referenced. Import will be (TODO) discussed throughly later in this doc.

Supported OWL constructs

These are the only current supported OWL constructs. It may be a small subset, but this subset it enough to define mappable vocabulary.

  • RDF: rdf:type, rdf:Property
  • RDFS: rdfs:Class, rdfs:subClassOf, rdfs:subPropertyOf, rdfs:domain, rdfs:range, rdfs:label, rdfs:comment, rdfs:isDefinedBy
  • OWL: owl:Class, owl:ObjectProperty, owl:DatatypeProperty, owl:Ontology, owl:imports, owl:versionInfo

Test cases

The current features of the library have been tested to be stable. Please check the tests output here.