JSPM

tiny-graph-db

1.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 20
  • Score
    100M100P100Q47003F
  • License MIT

A tiny, no-external-dependency, disk-based graph database for Node.js with rich set of operations.

Package Exports

  • tiny-graph-db
  • tiny-graph-db/src/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (tiny-graph-db) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

TinyGraphDB

A tiny, no-external-dependencies, disk-based graph database for Node.js with rich set of operations.

  • Persist simple node-&-edge graphs in a JSON file, and query, traverse or mutate them entirely in JavaScript.
  • TinyGraphDB is a great fit for building lightweight, GraphRAG systems β€” where LLMs retrieve knowledge via structured traversals instead of just flat vector search.

Table of Contents


Features

  • βœ… Persistent storage
    Automatically saves all nodes & relations to a JSON file on each change.
  • πŸ” Searchable
    Find nodes or edges by name, metadata, IDs or via complex metadata filters.
  • πŸ”„ Traversals
    Breadth-first-style traversals from any node or relation, with depth, direction and name filters.
  • πŸ”§ CRUD + Batch Ops
    Create, read, update or delete single or multiple nodes/relations by search criteria.
  • πŸ“ˆ Statistics
    Get nodeCount, relationCount and avgDegree.
  • πŸ”„ Import/Export
    Dump your graph into JSON, or load an existing JSON graph.

Installation

npm install tiny-graph-db # NOTE: Available from 10'th July 2025

Quick Start

const TinyGraphDB = require('tiny-graph-db');
const db = new TinyGraphDB();

// Adding some sample data
const node1 = db.addNode('Document1', { type: 'document', content: 'AI research paper' });
const node2 = db.addNode('Concept1', { type: 'concept', domain: 'AI' });
const node3 = db.addNode('Author1', { type: 'person', name: 'John Doe' });

const rel1 = db.addRelation('contains', node1.id, node2.id, { confidence: 0.9 });
const rel2 = db.addRelation('authored_by', node1.id, node3.id, { confidence: 1.0 });

// Search examples
console.log('Search: nodes with type "concept":', db.searchNodes({ metadata: { type: 'concept' } }));
console.log('Search: relations with confidence > 0.8:', db.searchRelations({ metadata: { confidence: { gt: 0.8 } } }));

// Traversal examples
console.log('Traverse: from node1 (depth 2):', db.traverseFromNode(node1.id, { maxDepth: 2, directions: ['outgoing'] }));
console.log('Traverse: from metadata {type: "document"}:', db.traverseFromMetadata({ type: 'document' }, 1));

// Update example
db.updateNode(node1.id, { name: 'Updated Document', metadata: { updated: true } });

console.log('Graph stats:', db.getStats());

API

Constructor

new TinyGraphDB(filePath?: string)
  • filePath: path to JSON file for persistence (default: ./graph_data.json).

Node Operations

Method Description Returns
addNode(name: string, metadata = {}) Creates a node with given name & metadata Node object
getNode(nodeId: string) Fetches a node by its ID Node or undefined
getAllNodes() Returns all nodes Node[]
updateNode(nodeId: string, updates) Update name and/or metadata on a node Updated Node
deleteNode(nodeId: string) Deletes a node and all its connected relations Deleted Node
deleteBySearch('node', conditions) Deletes all nodes matching conditions Node[]

Relation Operations

Method Description Returns
addRelation(name, fromNodeId, toNodeId, metadata = {}) Creates an edge between two existing nodes Relation
getRelation(relationId: string) Fetches a relation by ID Relation or undefined
getAllRelations() Returns all relations Relation[]
updateRelation(relationId, updates) Update name and/or metadata on a relation Updated Relation
deleteRelation(relationId: string) Deletes a single relation Deleted Relation
deleteBySearch('relation', conditions) Deletes all relations matching conditions Relation[]

Graph Traversal

traverseFromNode(startNodeId, options?)
traverseFromRelation(startRelationId, maxDepth?)
traverseFromMetadata(metadataConditions, maxDepth?)
  • options for traverseFromNode:

    • maxDepth: number (default: ∞)
    • directions: ['outgoing','incoming']
    • relationName?: filter by relation name
  • Returns: an array of [ fromNode, relation, toNode ] tuples.


Import / Export

exportData(): { nodes: Node[]; relations: Relation[] }
importData(data: { nodes; relations })
  • exportData() returns a JSON-serializable object.
  • importData(...) wipes current graph and loads provided data, then persists.

searchNodes(conditions: SearchConditions): Node[]
searchRelations(conditions: SearchConditions): Relation[]
  • conditions:

    • name: string | RegExp | { contains: string }

    • id, fromNodeId, toNodeId

    • metadata: { [key]: valueOrFilter }

      • supports { eq, ne, gt, gte, lt, lte, contains, startsWith, endsWith, in }

Examples

const TinyGraphDB = require('tiny-graph-db');
const db = new TinyGraphDB('./example_graph.json');

// β€”β€”β€” Create sample nodes β€”β€”β€”
const book1    = db.addNode('Dune',        { genre: 'sci-fi',   pages: 412,  published: 1965 });
const book2    = db.addNode('Foundation',  { genre: 'sci-fi',   pages: 255,  published: 1951 });
const book3    = db.addNode('Hamlet',      { genre: 'drama',    pages: 160,  published: 1603 });
const author1  = db.addNode('Frank Herbert', { nationality: 'US',  awards: 2 });
const author2  = db.addNode('Isaac Asimov',  { nationality: 'US',  awards: 5 });
const author3  = db.addNode('William Shakespeare', { nationality: 'UK', awards: 0 });

// β€”β€”β€” Create sample relations β€”β€”β€”
const rel1 = db.addRelation('wrote', book1.id,   author1.id, { role: 'author'   });
const rel2 = db.addRelation('wrote', book2.id,   author2.id, { role: 'author'   });
const rel3 = db.addRelation('wrote', book3.id,   author3.id, { role: 'playwright' });
const rel4 = db.addRelation('influenced', author2.id, author1.id, { year: 1960 });
1. Search nodes by exact name
// Find the node whose name is exactly "Dune":
const result = db.searchNodes({ name: 'Dune' });
console.log(result);
// β†’ [ { id: '…', name: 'Dune', metadata: { genre: 'sci-fi', … } } ]
2. Search nodes by name contains (case-insensitive)
// Find all nodes whose name contains "isaac" (will match "Isaac Asimov"):
const result = db.searchNodes({ name: { contains: 'isaac' } });
console.log(result.map(n => n.name));
// β†’ [ 'Isaac Asimov' ]
3. Search nodes by name regex
// Find any book title that starts with 'F' or 'H':
const result = db.searchNodes({ name: /^F|^H/ });
console.log(result.map(n => n.name));
// β†’ [ 'Foundation', 'Hamlet' ]
4. Search nodes by metadata equality and comparison
// All sci-fi books:
const scifi = db.searchNodes({ metadata: { genre: 'sci-fi' } });

// Books published before 1900:
const classics = db.searchNodes({
  metadata: { published: { lt: 1900 } }
});

console.log(scifi.map(n => n.name));     // β†’ [ 'Dune', 'Foundation' ]
console.log(classics.map(n => n.name));  // β†’ [ 'Foundation', 'Hamlet' ]
5. Search nodes by metadata β€œin” list
// Find all authors from US or UK:
const authors = db.searchNodes({
  metadata: { nationality: { in: ['US', 'UK'] } }
});
console.log(authors.map(a => a.name));
// β†’ [ 'Frank Herbert', 'Isaac Asimov', 'William Shakespeare' ]
6. Search relations by relation name and metadata
// All "wrote" relations:
const wroteRels = db.searchRelations({ name: 'wrote' });

// Relations where influence happened after 1950:
const influenceRels = db.searchRelations({
  name: 'influenced',
  metadata: { year: { gt: 1950 } }
});

console.log(wroteRels.length);      // β†’ 3
console.log(influenceRels);         // β†’ [ { id: '…', name: 'influenced', … } ]
7. Combining condition types
// Sci-fi books by authors with >2 awards:
const sciFiBooks = db.searchNodes({
  metadata: { genre: 'sci-fi' }
});
const topAuthors = db.searchNodes({
  metadata: { awards: { gt: 2 } }
});

// Then filter relations:
const result = db
  .getAllRelations()
  .filter(r =>
    r.name === 'wrote'
    && sciFiBooks.some(b => b.id === r.fromNodeId)
    && topAuthors.some(a => a.id === r.toNodeId)
  );
console.log(result);

Utility

  • getNeighbors(nodeId) List all adjacent nodes & relation directions.
  • getStats() { nodeCount, relationCount, avgDegree }

Contributing

  1. Fork the repo
  2. Create a feature branch git checkout -b feat/my-feature
  3. Commit your changes (git commit -m 'Add awesome feature')
  4. Push (git push origin feat/my-feature)
  5. Open a Pull Request

Please file issues for bugs or feature requests via GitHub Issues.


License

This project is licensed under the MIT License. See LICENSE for details.


Built with β™₯ by freakynit