The Knowledge Graph for TypeScript
Define your ontology with Zod. Query with a fluent builder. Extend it at runtime when your agents need more.
Define. Connect. Query. Evolve.
Your schema is your database. Your types are your queries.
import { defineNode, defineEdge, defineGraph, createStore } from "@nicia-ai/typegraph";
import { z } from "zod";
// 1. Define your ontology
const Person = defineNode("Person", {
schema: z.object({ name: z.string(), role: z.string() })
});
const Project = defineNode("Project", {
schema: z.object({ name: z.string(), status: z.string() })
});
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] } }
});
// 2. Query with full type safety
const results = await store.query()
.from("Person", "p")
.whereNode("p", p => p.role.eq("Engineer"))
.traverse("worksOn", "e")
.to("Project", "proj")
.select(ctx => ({ person: ctx.p.name, project: ctx.proj.name }))
.execute();import { defineNode, searchable, embedding } from "@nicia-ai/typegraph";
import { z } from "zod";
// 1. Declare semantic + fulltext fields right in the Zod schema
const Document = defineNode("Document", {
schema: z.object({
title: searchable({ language: "english" }),
body: searchable({ language: "english" }),
embedding: embedding(1536),
})
});
// 2. Hybrid retrieval: BM25 fulltext + vector similarity, fused with RRF
const hits = await store.search.hybrid("Document", {
limit: 10,
vector: { fieldPath: "embedding", queryEmbedding: await embed(q) },
fulltext: { query: q },
});
// 3. Or compose fulltext into any graph traversal — authorised search,
// multi-tenant filters, anything you can already express in a query.
const scoped = await store.query()
.from("User", "u").whereNode("u", u => u.id.eq(currentUserId))
.traverse("canRead", "e").to("Document", "d")
.whereNode("d", d => d.$fulltext.matches(query, 10))
.select(ctx => ctx.d).execute();import { defineGraphExtension } from "@nicia-ai/typegraph";
// 1. An agent proposes a typed kind from observed data.
const proposal = defineGraphExtension({
nodes: {
Paper: {
description: "An academic paper inferred from the corpus",
properties: {
title: { type: "string", minLength: 1 },
doi: { type: "string", minLength: 1 },
year: { type: "number", int: true, min: 1900, max: 2100 },
},
unique: [{ name: "paper_doi_unique", fields: ["doi"] }],
},
},
});
// 2. Operator approves; commit atomically as a new schema version.
const evolved = await store.evolve(proposal);
// 3. Read and write the new kind dynamically — no codegen, no redeploy.
const papers = evolved.getNodeCollection("Paper")!;
await papers.create({
title: "Attention Is All You Need",
doi: "10.5555/3295222.3295349",
year: 2017,
});import { createStore, asRecordedInstant } from "@nicia-ai/typegraph";
// 1. Turn on recorded/system-time capture for committed writes.
const store = createStore(graph, backend, { history: true });
// 2. Capture a deterministic recorded-time anchor after an agent decides.
await store.nodes.Decision.create({ answer: "approve source A" });
const decisionTime = await store.recordedNow();
if (decisionTime === undefined) throw new Error("no recorded history yet");
// 3. Later, replay the exact graph the agent saw.
const replay = store.asOfRecorded(decisionTime);
const sameAnswer = await replay
.query()
.from("Decision", "d")
.select(ctx => ctx.d.answer)
.first();
// Valid time and recorded time can be pinned independently.
const whatWeKnewThen = store
.asOf("2026-01-01T00:00:00.000Z")
.asOfRecorded(asRecordedInstant("2026-02-01T00:00:00.000Z"));The graph lifecycle
Stop stitching graph tools together.
Keep schema, search, reasoning, merge, and history in one typed system.
Define
Zod schemas for compile time type safety and runtime validation.
defineGraphRetrieve
Typed query builders plus BM25, vector, graph, and hybrid retrieval.
search.hybridReason
Ontology powered reasoning plus graph algorithms over the same graph.
store.algorithmsEvolve
Update schema at runtime, or have agents propose the change for review.
store.evolveMerge
Branch and merge safely with entity resolution, conflicts, and provenance.
mergeReplay
Valid time and recorded time show who knew what when.
asOfRecordedExample showcase
Complete workflows, not toy demos.
Research Copilot
A literature-review assistant over landmark ML papers. It blends semantic retrieval, topic hierarchy expansion, citation-authority ranking, shortest-path lineage, and collaborator discovery in one SQLite graph.
semantic retrieval
Embedding fields rank papers against the query.
ontology expansion
Topic hierarchy traversal improves recall.
graph algorithms
Degree and shortest path explain why each paper matters.
typed traversal
The digest is assembled through the query builder.
FHIR Graph Merge
MergeTwo ingestion agents disagree on patient identity. Branches isolate writes; merge resolves duplicates, repoints clinical edges, and reports provenance.
Agent Decision Replay
ReplaySave a recorded-time anchor when the agent decides, then rerun the same reasoning code against the exact graph it saw.
Breach Forensics
ForensicsPin the access graph to the compromise instant and traverse the real blast radius after risky edges were revoked or deleted.
Stay in the loop
Occasional updates on new features, guides, and releases. No spam.