# property-graph

> Base for creating objects that behave like a Property Graph.

Latest version **4.1.0** (published 2026-03-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install property-graph
pnpm add property-graph
yarn add property-graph
bun add property-graph
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.1.0 |
| Published | 2026-03-25 |
| First published | 2021-12-03 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Dependencies | 0 |
| Unpacked size | 61.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Don McCurdy <dm@donmccurdy.com> |
| Maintainers | donmccurdy |

## Links

- npm: https://www.npmjs.com/package/property-graph
- Repository: github:donmccurdy/property-graph
- npm.io page: https://npm.io/package/property-graph

## Recent versions

- 4.1.0 (latest) — 2026-03-25
- 4.0.0-alpha.3 (alpha) — 2025-11-07
- 2.0.0 (next) — 2024-04-04
- 4.0.0 — 2025-11-09
- 4.0.0-alpha.2 — 2025-11-07
- 4.0.0-alpha.1 — 2025-11-07
- 4.0.0-alpha.0 — 2025-11-07
- 3.0.0 — 2024-10-27
- 2.0.0-alpha.1 — 2023-10-25
- 2.0.0-alpha.0 — 2023-10-25
- 1.3.1 — 2023-06-23
- 1.3.0 — 2023-06-23
- 1.2.0 — 2023-04-16
- 1.1.0 — 2023-02-22
- 1.0.3 — 2023-01-23
- … 12 more at https://npm.io/package/property-graph/versions

## README

# property-graph

[![Latest NPM release](https://img.shields.io/npm/v/property-graph.svg)](https://www.npmjs.com/package/property-graph)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/property-graph)](https://bundlephobia.com/package/property-graph)
[![License](https://img.shields.io/badge/license-MIT-007ec6.svg)](https://github.com/donmccurdy/property-graph/blob/main/LICENSE)
[![Build Status](https://github.com/donmccurdy/property-graph/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/donmccurdy/property-graph/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/donmccurdy/property-graph/branch/main/graph/badge.svg?token=S30LCC3L04)](https://codecov.io/gh/donmccurdy/property-graph)

Extensible base for creating objects that behave like a Property Graph.

## Overview

The `property-graph` package provides a set of utility classes to be used for implementating libraries or applications based on a data model represented as a [Property Graph](https://www.dataversity.net/what-is-a-property-graph/#). A Property Graph representation is useful for working with dependency chains, nested resource references, node-based state workflows, and more.

Conceptually, a Property Graph is a [labeled, directed multigraph](https://en.wikipedia.org/wiki/Multigraph#Labeling), in which entities ("nodes") may have named relationships ("edges") with other nodes on the graph. Both nodes and edges may be assigned arbitrary key/value attributes. Beyond that, `property-graph` is intended to be small and practical, rather than providing a large standard library for graph theory — if you need something more comprehensive, I'd suggest [`graphology`](https://graphology.github.io/).

Typically, you'll define custom classes inheriting from the base `GraphNode`. When using TypeScript, an interface should be provided defining the kinds of connections that each type of graph node allows. Then, `.set` and `.get` methods may be used to set key/value attributes (strings, numbers, booleans, ...), and `.getRef` and `.setRef` methods may be used to create edges (or relationships) to other nodes of a compatible type. All references have names, and support compile-time type-checking.

## Features

In a codebase with many distinct types of entities and relationships among them (e.g. "Client has N Projects", "Project has N Tasks"), this project can make management of entities and their relationships considerably easier than writing plain getters/setters for each case.

- **Traversal:** GraphEdges are tracked and can be traversed up or down
- **Disposal:** GraphNode disposal automatically cleans up incoming references from other nodes
- **Finding dependents:** Efficiently locate all GraphNodes that refer _to_ a given GraphNode, or that have references _from_ a given GraphNode
- **Change detection:** GraphNodes dispatch events when changed, which can be optionally propagated throughout the graph
- **Extensibility:** Operations like `.copy()`, `.equals()`, and `.swap(a, b)` can be implemented abstractly

## Usage

**Definitions:**

```typescript
import { GraphNode, RefSet } from 'property-graph';

interface IPerson {
  name: string;
  age: number;
  friends: RefSet<Person>;
  pet: Pet;
}

interface IPet {
  type: 'dog' | 'cat';
  name: string;
}

class Person extends GraphNode<IPerson> {
	getDefaults(): Nullable<IPerson> {
		return {name: '', age: 0, friends: new RefSet(), pet: null};
	}
}
class Pet extends GraphNode<IPet> {
	getDefaults(): Nullable<IPet> {
		return {type: 'dog', name: ''};
	}
}
```

**Basic usage:**

```typescript
const graph = new Graph();

const spot = new Pet(graph)
  .set('type', 'dog')
  .set('name', 'Spot');

const jo = new Person(graph)
  .set('name', 'Jo')
  .set('age', 41)
  .setRef('pet', spot);

const sam = new Person(graph)
  .set('name', 'Sam')
  .set('age', 45)
  .addRef('friends', jo);
```

**Lifecycles:**

```typescript
jo.equals(sam); // recursive equality → false

console.log(sam.listRefs('friends')); // → [jo]

jo.dispose();

console.log(sam.listRefs('friends')); // → []
```

## API

### Literal Attributes

Literal attributes (string, number, boolean, ...) are modified with two methods:

- `node.get('key'): Literal`
- `node.set('key', value: Literal): this`

### References


References support one named connection to a single graph node of a given type:

- `node.getRef('key'): GraphNode`
- `node.setRef('key', node: GraphNode): this`

### Reference Lists

Reference Lists support a named list of connections to graph nodes of a given type:

- `node.addRef('key', node: GraphNode): this`
- `node.removeRef('key', node: GraphNode): this`
- `node.listRefs('key'): GraphNode[]`

### Reference Maps

Reference Maps support a named map having any number of subkeys, where each subkey points to a graph node of a given type:

- `node.getRefMap('key', 'subkey'): GraphNode`
- `node.setRefMap('key', 'subkey', node: GraphNode): this`
- `node.listRefMapKeys('key'): string[]`
- `node.listRefMapValues('key'): GraphNode[]`

## References

- [The Property Graph Database Model](http://ceur-ws.org/Vol-2100/paper26.pdf)
- [Graph Fundamentals — Part 2: Labelled Property Graphs](https://medium.com/terminusdb/graph-fundamentals-part-2-labelled-property-graphs-ba9a8edb5dfe)
- [OpenCypher – Property Graph Model](https://github.com/opencypher/openCypher/blob/master/docs/property-graph-model.adoc)

---
_Source: https://npm.io/package/property-graph · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
