New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

tiny-graph-db

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tiny-graph-db

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

latest
Source
npmnpm
Version
1.0.4
Version published
Weekly downloads
12
33.33%
Maintainers
1
Weekly downloads
 
Created
Source

TinyGraphDB

A tiny, no-external-dependencies, disk-based graph database for Node.js with rich query, traversal, batch ops, batch cosine similarity, and semantic filtering.

  • Persist node-&-relation graphs in a JSON file
  • Query, traverse, mutate, and semantically search graphs in JavaScript
  • Cosine similarity search of nodes & edges via vector embeddings for AI/semantic-graph use cases
  • Batch and hierarchical traversals, semantic+traditional queries, and stats
  • Full API for CRUD, batch, similarity, statistics, import/export, and traversal

Table of Contents

Features

  • Persistent storage
    All nodes & edges auto-saved to a JSON file
  • 🔍 Search: name, metadata, ID, relation endpoints, and semantic/meta comparison
  • 🧮 Cosine Similarity queries for embeddings in metadata (nodes or relations)
  • 🔄 Graph Traversal, walk/batch from node, relation, or metadata; supports direction/depth/name filters
  • ⬇️ Batch update/delete by search criteria (see below)
  • 📈 Stats: node count, edge count, average degree
  • 🔄 Import/export: snapshot/restore full graph
  • ⚡ Fast, super lightweight, perfect for graph semantic search, retrieval-augmented generation, etc.

Installation

npm install tiny-graph-db

Quick Start

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

// Add nodes with embeddings
const nodeA = db.addNode('Paper A', { type: 'paper', embedding: [0.2, 0.1, 0.5] });
const nodeC = db.addNode('Concept X', { type: 'concept', embedding: [0.25, 0.1, 0.55] });
const nodeP = db.addNode('Author', { type: 'person', embedding: [0.9, 0.8, 0.7] });

const rel1 = db.addRelation('mentions', nodeA.id, nodeC.id, { confidence: 0.92 });
const rel2 = db.addRelation('authored_by', nodeA.id, nodeP.id, { confidence: 1.0 });

// Node search by metadata
console.log('All concepts:', db.searchNodes({ metadata: { type: 'concept' } }));

// Cosine similarity search
const qv = [0.2, 0.1, 0.52];
const similar = db.searchNodesByCosineSimilarity(qv, { threshold: 0.99 });
console.log('Semantically closest nodes:', similar);

// Traverse outgoing links from nodeA up to depth 2
const walk = db.traverseFromNode(nodeA.id, { maxDepth: 2, directions: ['outgoing'] });
console.log('Traversal:', walk);

// Batch update: update all "concept" nodes
db.updateBySearch('node', { metadata: { type: 'concept' } }, { metadata: { reviewed: true } });

// Batch delete: remove all relations with low confidence
db.deleteBySearch('relation', { metadata: { confidence: { lt: 0.95 } } });

// Save (usually auto, but explicit call)
db.flushToDisk();

API

Constructor

new TinyGraphDB(filePath?: string)
  • filePath: Path to JSON file (default: './graph_data.json').

Node Operations

MethodDescriptionReturns
addNode(name, metadata = {}, flush = true)Create node with name/metadataNode object
getNode(nodeId)Look up node by IDNode or undefined
getAllNodes()Get all nodesNode[]
updateNode(nodeId, {name?, metadata?})Update name/metadataUpdated node
deleteNode(nodeId)Remove node and all its relationsDeleted node object
deleteBySearch('node', conditions)Batch delete by searchArray of removed

Relation Operations

MethodDescriptionReturns
addRelation(name, fromNodeId, toNodeId, metadata = {}, flush = true)Create edge between nodesRelation object
getRelation(relationId)Fetch edge by IDRelation or undefined
getAllRelations()Get all edgesRelation[]
updateRelation(relationId, {name?, metadata?})Update name/metadataUpdated relation
deleteRelation(relationId)Remove relationDeleted relation object
deleteBySearch('relation', conditions)Batch delete by searchArray of removed
searchNodes(conditions: SearchConditions): Node[]
searchRelations(conditions: SearchConditions): Relation[]

conditions:

  • name: string | RegExp | { contains: string }
  • id, fromNodeId, toNodeId
  • metadata: { [key]: ... } supports:
    • equality, comparison: { eq, ne, gt, gte, lt, lte, contains, startsWith, endsWith, in }
    • cosine similarity: { cosineSimilarity: { queryEmbedding, threshold } }
  • cosineSimilarity (top-level): { queryEmbedding, embeddingKey, threshold }
searchNodesByCosineSimilarity(queryEmbedding: number[], options?): Array
searchRelationsByCosineSimilarity(queryEmbedding: number[], options?): Array
cosineSimilarity(vecA: number[], vecB: number[]): number
  • queryEmbedding: Numeric vector
  • Options:
    • embeddingKey: metadata key for vector (default: 'embedding')
    • threshold: similarity threshold (default: 0.5)
    • limit: max results (default: 10)

Example

db.searchNodesByCosineSimilarity([0.1, 0.2, 0.3], { threshold: 0.8, limit: 3 });

Graph Traversal

MethodDescriptionReturns
traverseFromNode(startNodeId, options)Walks from a node, following edges (see below)Array of [fromNode, relation, toNode]
traverseFromRelation(startRelationId, maxDepth?)Starts traversal from a relationSame as above
traverseFromMetadata(metadataConditions, maxDepth?)Begins traverse from nodes/relations that match metadataSame as above

Options for traverseFromNode:

  • maxDepth: limit depth (Infinity by default)
  • directions: ['outgoing','incoming']
  • relationName: (optional) filter by relation name

Example

db.traverseFromNode(nodeId, { maxDepth: 2, directions: ['outgoing'] });

Result: Array of [fromNode, relation, toNode] triplets in visit order.

Batch Update / Delete

updateBySearch('node' | 'relation', searchConditions, { name?, metadata? }): Array
// Example:
db.updateBySearch('node', { metadata: { genre: 'sci-fi' } }, { name: 'SF Novel' });
deleteBySearch('node' | 'relation', searchConditions): Array
// Example:
db.deleteBySearch('relation', { metadata: { confidence: { lt: 0.9 } } });

GraphRAG & Hierarchical Traversal

Hybrid search and traversal for retrieval-augmented-graph (RAG) and LLM flows

searchAndTraverse(queryEmbedding, options?): Array

Supports:

  • Cosine similarity search + regular filters, for nodes/relations
  • For each initial match, traverses up to N hops, directionally (optionally, end traversal on node only)
  • Returns rich hierarchical JSON

Options:

  • embeddingKey, threshold, limit - see cosine similarity
  • hops: Number of hops to traverse (default: 3)
  • nodeFilters, relationFilters: Additional filters
  • searchNodes, searchRelations: Whether to include nodes, edges, or both
  • directions: e.g., ['outgoing', 'incoming']
  • endOnNode: bool (whether to always finish traversal on nodes)

Example:

const tree = db.searchAndTraverse([0.2, 0.1, 0.5], {
  hops: 2,
  searchNodes: true,
  searchRelations: false,
  nodeFilters: { metadata: { type: 'paper' } },
});
console.log(tree);
// Output: array of hierarchical trees, each rooted on an initial (semantic) hit, with outgoing/incoming relations, connected nodes/edges & so forth

Import / Export

exportData(): { nodes: Node[], relations: Relation[] }
importData(data: { nodes, relations }): void

Export produces the full graph dataset as JSON-serializable data. Import wipes and loads supplied graph, then persists.

Utility

  • getNeighbors(nodeId): All neighbor nodes, with edge and direction
    • Returns: Array of { node, relation, direction }
  • getStats(): { nodeCount, relationCount, avgDegree }
  • flushToDisk(): Explicit save to disk (auto after every mutation unless using flush = false param on add)
  • rebuildNodeRelationsIndex(): Internal; rebuilds edge indices (auto-run after import)

Examples

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 author1  = db.addNode('Frank Herbert', { nationality: 'US' });

// Find all US authors:
db.searchNodes({ metadata: { nationality: 'US' } });

// Find all books published pre-1960:
db.searchNodes({ metadata: { published: { lt: 1960 } } });
const doc = db.addNode('Graph Vector', { embedding: [0.2, 0.4, 0.6] });
// Find similar to [0.2, 0.41, 0.67]:
db.searchNodesByCosineSimilarity([0.2, 0.41, 0.67], { threshold: 0.95 });

3. Traversals

// Walk two hops out from a node
const walk = db.traverseFromNode(doc.id, { maxDepth: 2, directions: ['outgoing'] });

// Start traversal from a relation
const traverseRels = db.traverseFromRelation(rel1.id, 3);

// Traverse from all nodes with type "paper":
db.traverseFromMetadata({ type: 'paper' }, 2);

4. Batch Update & Delete

// Tag all "concept" nodes as reviewed
db.updateBySearch('node', { metadata: { type: 'concept' } }, { metadata: { reviewed: true } });
// Delete all weak relations
db.deleteBySearch('relation', { metadata: { confidence: { lt: 0.8 } } });

5. Hybrid "search and traverse" (GraphRAG pattern)

// Retrieve node (by semantic match) then its 2-hop subgraph
const rag = db.searchAndTraverse([0.25, 0.1, 0.5], { hops: 2 });
console.log(JSON.stringify(rag, null, 2));

6. Utilities

console.log('Stats:', db.getStats());
console.log('Neighbors of nodeA:', db.getNeighbors(nodeA.id));
// Export/import
const json = db.exportData();
db.importData(json);

Performance Benchmarks

FunctionTime (ms)Ops/sec
getNode()0.00018,473,743
traverseFromNode()0.0072138,175
searchNodes()0.17285,787
searchNodesByCosineSimilarity()0.34562,893

Run benchmarks: node src/benchmark.js 1000 2000 5 or npm run benchmark -- 1000 2000 5

Contributing

  • Fork the repo
  • Create a branch: git checkout -b feat/my-feature
  • Commit & push, then open a PR

Please file bugs/requests using GitHub Issues.

License

MIT License (see LICENSE)

Built with ♥ by freakynit

Keywords

graph-database

FAQs

Package last updated on 17 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts