A flexible, database-agnostic knowledge graph implementation for TypeScript. Build powerful graph-based knowledge representations with support for multiple database backends including Cloudflare D1, SQLite, and more.
- 🗄️ Multiple Database Backends - SQLite, Cloudflare D1, Cloudflare Durable Objects (SqlStorage), LibSQL (Turso)
- 🔍 Full-Text Search - Built-in search indexing and querying
- 🧠 Knowledge Extraction - Extract entities and relationships from text
- 📊 Graph Algorithms - Path finding, centrality, community detection
- 🎨 Graph Visualization - Generate Mermaid diagrams for easy embedding and sharing
- 🚀 High Performance - Optimized queries with proper indexing
- 🔒 Type Safe - Full TypeScript support with generics
- 💾 Transaction Support - Atomic operations for data consistency
- 🎯 Flexible Schema - Extensible node and edge types
npm install @fluxgraph/knowledge
# For SQLite support
npm install better-sqlite3
# For Cloudflare D1 support
npm install @cloudflare/workers-types
# For LibSQL support
npm install @libsql/clientFor rendering Mermaid diagrams in the browser:
<!-- Add to your HTML --><scriptsrc="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>import{KnowledgeGraph,SQLiteAdapter,CommonEdgeType}from'@fluxgraph/knowledge';// Define your own node typesenumMyNodeType{PERSON='PERSON',ORGANIZATION='ORGANIZATION',LOCATION='LOCATION',DOCUMENT='DOCUMENT',}// Define your own edge types (can also extend CommonEdgeType)enumMyEdgeType{EMPLOYED_BY='EMPLOYED_BY',FOUNDED='FOUNDED',INVESTED_IN='INVESTED_IN',}// Create adapter and knowledge graphconstadapter=newSQLiteAdapter({connection: './my-knowledge.db',// or ':memory:' for in-memory});constgraph=newKnowledgeGraph<MyNodeType>(adapter);awaitgraph.initialize();// Add nodesconstperson=awaitgraph.addNode({type: MyNodeType.PERSON,label: 'Alice Johnson',properties: {email: 'alice@example.com',age: 28,},});constcompany=awaitgraph.addNode({type: MyNodeType.ORGANIZATION,label: 'TechCorp',properties: {industry: 'Technology',},});// Create relationships (using custom edge type)awaitgraph.addEdge({type: MyEdgeType.EMPLOYED_BY,fromNodeId: person.id,toNodeId: company.id,properties: {since: '2020-01-15',},});// Query the graph (using CommonEdgeType)constcolleagues=awaitgraph.queryRelated(person.id,{depth: 2,edgeTypes: [CommonEdgeType.COLLEAGUE_OF],});// Searchconstresults=awaitgraph.search({query: 'alice tech',limit: 10,});// Generate Mermaid visualizationimport{MermaidGraphVisualizer,MermaidUtils}from'@fluxgraph/knowledge';constvisualizer=newMermaidGraphVisualizer(graph);// Generate diagram for a node and its connectionsconstdiagram=awaitvisualizer.generateFromNode(person.id,2,{direction: 'TD',includeProperties: true,});// Convert to Markdown for documentationconstmarkdown=MermaidUtils.toMarkdown(diagram,'Person Network');console.log(markdown);// Or generate HTML page for web viewingconsthtml=MermaidUtils.wrapInHtml(diagram,{title: 'Knowledge Graph',theme: 'default',});To use a knowledge graph, create an adapter instance for your database and pass it to KnowledgeGraph. This gives you full control over the adapter configuration.
import{KnowledgeGraph,SQLiteAdapter}from'@fluxgraph/knowledge';constadapter=newSQLiteAdapter({connection: './database.db',debug: true,});constgraph=newKnowledgeGraph(adapter);awaitgraph.initialize();import{D1Adapter,KnowledgeGraph}from'@fluxgraph/knowledge';exportdefault{asyncfetch(request: Request,env: Env){constadapter=newD1Adapter({database: env.DB});constgraph=newKnowledgeGraph(adapter);awaitgraph.initialize();// Use the graph...},};import{SqlStorageAdapter,KnowledgeGraph}from'@fluxgraph/knowledge';// Inside your Durable Object classexportclassMyDurableObject{constructor(privatestate: DurableObjectState){}asyncfetch(request: Request){// Use the Durable Object's SQL storageconstadapter=newSqlStorageAdapter();adapter.setSqlStorage(this.state.storage.sql);constgraph=newKnowledgeGraph(adapter);awaitgraph.initialize();// Use the graph...}}import{BaseAdapter,KnowledgeGraph}from'@fluxgraph/knowledge';classMyCustomAdapterextendsBaseAdapter{// Implement required methods...}constgraph=newKnowledgeGraph(newMyCustomAdapter(config));Nodes represent entities in your knowledge graph:
constnode=awaitgraph.addNode({type: NodeType.PERSON,// or custom stringlabel: 'Unique Label',// Human-readable identifierproperties: {// Custom propertieskey: 'value',nested: {data: true},},confidence: 0.95,// Confidence score (0-1)sourceSessionId: 'session-123',// Track data source});Edges represent relationships between nodes:
constedge=awaitgraph.addEdge({type: EdgeType.KNOWS,fromNodeId: node1.id,toNodeId: node2.id,properties: {since: '2020',strength: 'strong',},bidirectional: true,// Creates edges in both directions});Built-in node types:
PERSON,ORGANIZATION,LOCATION,EVENTDOCUMENT,CONCEPT,TOPIC,SKILLPRODUCT,SERVICE,FINANCIAL,GOAL
Built-in edge types:
- Relationships:
KNOWS,FRIEND_OF,COLLEAGUE_OF - Family:
PARENT_OF,CHILD_OF,SIBLING_OF - Work:
EMPLOYED_BY,MANAGES,REPORTS_TO - Location:
LIVES_AT,WORKS_AT,LOCATED_IN - Ownership:
OWNS,CREATED_BY
constdocuments=awaitgraph.queryByType(NodeType.DOCUMENT,{limit: 50,offset: 0,minConfidence: 0.7,});constnetwork=awaitgraph.queryRelated(nodeId,{depth: 3,// Traversal depthdirection: 'both',// 'in', 'out', or 'both'edgeTypes: [EdgeType.KNOWS],// Filter by edge typesincludeEdges: true,// Include edges in result});// Shortest pathconstpath=awaitgraph.findShortestPath(fromId,toId,{edgeTypes: [EdgeType.KNOWS,EdgeType.COLLEAGUE_OF],});// All paths (with graph algorithms)import{GraphAlgorithms}from'@fluxgraph/knowledge/algorithms';constalgorithms=newGraphAlgorithms(graph);constallPaths=awaitalgorithms.findAllPaths(fromId,toId,maxLength);constresults=awaitgraph.search({query: 'machine learning python',nodeTypes: [NodeType.DOCUMENT,NodeType.SKILL],fuzzy: true,limit: 20,minScore: 0.5,});Extract entities and relationships from text:
import{KnowledgeExtractor}from'@fluxgraph/knowledge/extraction';constextractor=newKnowledgeExtractor(graph);// Extract from textconstextraction=awaitextractor.extractFromText('Alice Johnson (alice@example.com) works at TechCorp in San Francisco.',{extractEntities: true,extractRelationships: true,minConfidence: 0.6,});// Process and add to graphconst{ nodesAdded, edgesAdded }=awaitextractor.processExtractedKnowledge(extraction,{mergeStrategy: 'merge'});// Extract from conversationconstmessages=[{role: 'user',content: 'I work with Bob on the AI project'},{role: 'assistant',content: 'Tell me more about the AI project'},];constconversationKnowledge=awaitextractor.extractFromConversation(messages);// Add custom entity patternextractor.addEntityPattern({pattern: /PROJECT-\d{4}/g,type: NodeType.PROJECT,extractor: (match)=>({label: match[0],properties: {projectId: match[0],type: 'internal',},}),});// Add custom relationship patternextractor.addRelationshipPattern({pattern: /(\w+)manages(\w+)/g,type: EdgeType.MANAGES,extractor: (match,nodes)=>({fromNodeLabel: match[1],toNodeLabel: match[2],properties: {extractedFrom: 'text'},}),});import{GraphAlgorithms}from'@fluxgraph/knowledge/algorithms';constalgorithms=newGraphAlgorithms(graph);// Centrality measuresconstdegree=awaitalgorithms.degreeCentrality(nodeId);constpagerank=awaitalgorithms.pageRank();// Community detectionconstcommunities=awaitalgorithms.detectCommunities();// Find cliquesconstcliques=awaitalgorithms.findCliques(minSize);// Detect cyclesconstcycles=awaitalgorithms.detectCycles();// Clustering coefficientconstcoefficient=awaitalgorithms.clusteringCoefficient(nodeId);// Connected componentsconstcomponents=awaitalgorithms.findConnectedComponents();@fluxgraph/knowledge generates Mermaid diagrams for knowledge graph visualization. Mermaid is a lightweight, text-based diagramming format that's widely supported.
import{MermaidGraphVisualizer,MermaidUtils}from'@fluxgraph/knowledge';constvisualizer=newMermaidGraphVisualizer(graph);// Visualize a specific node and its neighborhoodconstdiagram=awaitvisualizer.generateFromNode(nodeId,depth,{direction: 'TD',// Top-Down, or 'LR' for Left-RightincludeProperties: true,maxNodes: 50,});// Search and visualizeconstsearchDiagram=awaitvisualizer.generateFromSearch('engineer',{maxNodes: 20,});// Visualize by node typesconsttypesDiagram=awaitvisualizer.generateFromNodeTypes(['PERSON','ORGANIZATION']);// As Markdown (for documentation)constmarkdown=MermaidUtils.toMarkdown(diagram,'Graph Title');// As HTML page (for web viewing)consthtml=MermaidUtils.wrapInHtml(diagram,{title: 'My Knowledge Graph',theme: 'default',// or 'dark', 'forest', 'neutral'});// Get Mermaid Live Editor URLconsteditorUrl=MermaidUtils.generateLiveEditorUrl(diagram);- ✅ No Dependencies: Works with any Mermaid renderer
- ✅ Lightweight: Text-based format, minimal overhead
- ✅ Portable: Works in Markdown, GitHub, GitLab, etc.
- ✅ Version Control: Text format is diff-friendly
- ✅ Easy Integration: Embed in docs, wikis, or web pages
- ✅ Interactive: Supports clicking, zooming in compatible viewers
See Visualization Documentation for complete details.
// Batch add nodesconstresult=awaitgraph.batchAddNodes([{type: NodeType.PERSON,label: 'Person 1'},{type: NodeType.PERSON,label: 'Person 2'},{type: NodeType.PERSON,label: 'Person 3'},]);console.log(`Added ${result.successful} nodes, ${result.failed} failed`);// Batch add edgesconstedgeResult=awaitgraph.batchAddEdges([{type: EdgeType.KNOWS,fromNodeId: id1,toNodeId: id2},{type: EdgeType.KNOWS,fromNodeId: id2,toNodeId: id3},]);import{SQLiteAdapter}from'@fluxgraph/knowledge/adapters';constadapter=newSQLiteAdapter({connection: './db.sqlite'});awaitadapter.transaction(async(tx)=>{// All operations in transactionawaittx.execute('INSERT INTO kg_nodes ...');awaittx.execute('INSERT INTO kg_edges ...');// Rollback on errorif(error){awaittx.rollback();}});conststats=awaitgraph.getStats();console.log({nodes: stats.nodeCount,edges: stats.edgeCount,averageDegree: stats.averageDegree,density: stats.density,nodesByType: stats.nodesByType,edgesByType: stats.edgesByType,});┌─────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────┤
│ KnowledgeGraph API │
├─────────────────────────────────────────┤
│ Extraction │ Algorithms │ Search │
├─────────────────────────────────────────┤
│ Database Adapter Layer │
├──────────┬──────────┬──────────────────┤
│ SQLite │ D1 │ LibSQL │
└──────────┴──────────┴──────────────────┘
The knowledge graph uses the following tables:
kg_nodes- Stores all graph nodeskg_edges- Stores relationships between nodeskg_node_indices- Indexes for efficient node lookupskg_edge_indices- Indexes for efficient edge lookupskg_search_index- Full-text search indexkg_graph_metadata- Graph-level metadata
- Use Indexes: The library automatically creates indexes for common queries
- Batch Operations: Use batch methods for bulk inserts
- Limit Depth: Keep traversal depth reasonable (usually ≤ 3)
- Cache Results: Cache frequently accessed paths and queries
- Vacuum Regularly: Run
graph.vacuum()periodically for SQLite
- 🧠 Personal Knowledge Management - Build a personal knowledge base
- 💼 CRM Systems - Track customer relationships and interactions
- 🔬 Research Tools - Organize research data and citations
- 🤖 AI Memory Systems - Long-term memory for chatbots and agents
- 📊 Recommendation Engines - Build recommendation systems
- 🏢 Enterprise Knowledge Bases - Organizational knowledge management
- 📚 Educational Platforms - Track learning paths and prerequisites
- 🔍 Fraud Detection - Analyze relationship networks
See the examples directory for:
- Basic usage and CRUD operations
- Knowledge extraction from documents
- Building a chat memory system
- Social network analysis
- Recommendation engine
- Migration from other graph databases
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
MIT © Stu Kennedy