TypeScript-first embedded knowledge graph library.
TypeGraph brings property graph modeling and practical ontology support to your existing SQLite or PostgreSQL database. Define nodes and edges with Zod, query with a fluent TypeScript API, and keep graph + app data in one deployment.
- Keep graph data in your existing SQL database (no separate graph service)
- Model richer semantics with
subClassOf,implies,inverseOf, anddisjointWith - Traverse relationships with compile-time type safety
- Start with SQLite, move to PostgreSQL without changing your graph definition
TypeGraph works well for:
- Knowledge graphs and RAG context modeling
- Identity/permissions and other relationship-heavy domain models
- Applications that want graph semantics without extra infrastructure
TypeGraph is not designed for:
- Distributed graph processing
- Built-in graph algorithm workloads (PageRank, shortest path, community detection)
- Billion-scale graphs requiring dedicated graph-engine performance
npm install @nicia-ai/typegraph zod drizzle-orm better-sqlite3
npm install -D @types/better-sqlite3For edge/serverless environments (D1, libsql, bun:sqlite), see the docs: Edge and Serverless.
import { z } from "zod";
import { createStore, defineEdge, defineGraph, defineNode } from "@nicia-ai/typegraph";
import { createLocalSqliteBackend } from "@nicia-ai/typegraph/sqlite";
const { backend } = createLocalSqliteBackend();
const Person = defineNode("Person", {
schema: z.object({ name: z.string(), role: z.string().optional() }),
});
const Project = defineNode("Project", {
schema: z.object({ name: z.string(), status: z.enum(["active", "done"]) }),
});
const worksOn = defineEdge("worksOn");
const graph = defineGraph({
id: "my_app",
nodes: {
Person: { type: Person },
Project: { type: Project },
},
edges: {
worksOn: { type: worksOn, from: [Person], to: [Project] },
},
});
const store = createStore(graph, backend);
const alice = await store.nodes.Person.create({ name: "Alice", role: "Engineer" });
const website = await store.nodes.Project.create({ name: "Website", status: "active" });
await store.edges.worksOn.create(alice, website, {});
const results = await store
.query()
.from("Person", "p")
.traverse("worksOn", "e")
.to("Project", "proj")
.select((ctx) => ({ person: ctx.p.name, project: ctx.proj.name }))
.execute();
console.log(results);
// [{ person: "Alice", project: "Website" }]For production schema management, see: createStoreWithSchema.
- Docs: typegraph.dev
- Overview: What is TypeGraph?
- Setup: Getting Started
- Query builder: Queries Overview
- Application patterns: Common Patterns
- Complete examples: packages/typegraph/examples
- Project docs: Testing, Release Process
MIT