Skip to content

Latest commit

 

History

363 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

GraphForge

PyPI version npm version CLI npm version agent-skills npm version GitHub Release Python 3.10 or newer Node.js 20 or newer Rust 1.96 CI Gate status CodSpeed Documentation openCypher TCK Apache License 2.0

Composable graph tooling for analysis, construction, and refinement

An embedded, openCypher-compatible graph engine with a Rust core, Arrow results, and Parquet persistence — for research and investigative workflows


Table of Contents


Why GraphForge?

We are not building a database for applications. We are building a graph execution environment for thinking.

Modern data science and ML workflows increasingly produce graph-shaped data — entity relationships extracted by LLMs, citation networks, dependency graphs, social connections, knowledge bases. Working with this data shouldn't require running a database server. GraphForge brings openCypher and analyst-intent verbs to notebooks and scripts: zero configuration, Parquet-backed projects, and first-class Arrow results across language bindings.

NetworkX GraphForge Neo4j / Memgraph
Setup pip install Embedded package (graphforge) Run a server
Query language Python API Full openCypher Full Cypher
Persistence Manual Parquet project directory Native
Results Python objects Apache Arrow Tables Driver rows
Notebook-friendly Requires connection
Graph size Millions Research / notebook scale† Billions
TCK compliance N/A Full openCypher TCK corpus ~100%

Use GraphForge for: knowledge graphs, citation networks, research workflows, LLM output storage, social network analysis in notebooks.

Use a production database for: high throughput, multi-user access, or graphs beyond the limits in Scale Limits.

Fixed-hop traversal with LIMIT is the practical scaling path; full-scan aggregations remain edge-count bound. See scale limits for measured ceilings.


Installation

Install GraphForge from PyPI or npm. The current graphforge package is the CurateLabs native engine; earlier pure-Python releases under the same PyPI name predate it.

pip

pip install graphforge

uv (recommended)

uv add graphforge

npm

npm install @curatelabs/graphforge

pnpm

pnpm add @curatelabs/graphforge
python -c "import graphforge; print(graphforge.__version__)"

Requirements: Python 3.10–3.14

See the installation guide for source builds and fuller verification.

Ways to use GraphForge

Surface Current role
Python Thin PyO3 binding, Arrow results, and the graphforge CLI launcher
Node Thin N-API binding over the same Rust-owned behavior
CLI Repository lifecycle, configuration, checkpoints, and portable import/export
VS Code extension Project exploration, Cypher, analyst verbs, result views, and agent interop

Swift and Kotlin bindings remain planned; they are not shipped surfaces.


Quick Start

In-memory graph

from graphforge import GraphForge

forge = GraphForge()

alice = forge.add_node("Person", name="Alice", age=30)
bob = forge.add_node("Person", name="Bob", age=25)
forge.add_edge(alice, "KNOWS", bob, since=2020)

table = forge.execute("""
    MATCH (p:Person)-[:KNOWS]->(friend)
    WHERE p.age > 25
    RETURN p.name AS person, friend.name AS friend, p.age AS age
    ORDER BY p.age DESC
""")

print(table.to_pandas())

Persistent graph

The project directory must already exist — GraphForge initializes a project inside it rather than creating the directory.

from pathlib import Path

Path("research").mkdir(parents=True, exist_ok=True)

forge = GraphForge("research/")
forge.add_node("Paper", title="Graph Neural Networks", year=2024)
forge.close()

forge = GraphForge("research/")
table = forge.execute("MATCH (p:Paper) RETURN p.title AS t")
print(table.column("t")[0].as_py())  # Graph Neural Networks

Analyst verbs

# Centrality — Arrow Table with a score column
table = forge.rank("Person", by="pagerank")

# Opt-in write-back, then query via Cypher
forge.rank("Person", by="pagerank", write_property="rank")
forge.execute("MATCH (n:Person) RETURN n.name, n.rank ORDER BY n.rank DESC LIMIT 5")

# Communities
table = forge.cluster("Person", by="louvain", via="KNOWS")

# Hybrid text + vector search (bring your own embeddings)
table = forge.find("graph neural networks", label="Paper", vector=query_embedding)

Every verb returns an Apache Arrow Table. Use table.to_pandas(), polars.from_arrow(table), or table.to_pylist().


Cypher Features

GraphForge implements the full openCypher language. See TCK Compliance for the current corpus gate.

Clauses

-- Reading
MATCH (n:Person)-[:KNOWS]->(friend)
OPTIONAL MATCH (n)-[:WORKS_AT]->(company)
WHERE n.age > 25
WITH n, count(friend) AS friends
RETURN n.name, friends
ORDER BY friends DESC
LIMIT 10

-- Writing
CREATE (n:Person {name: 'Alice'})
MERGE (n:Person {name: 'Alice'})
SET n.age = 30
REMOVE n.temp
DELETE n
DETACH DELETE n

-- Iteration
UNWIND [1, 2, 3] AS x
RETURN x * 2 AS doubled

-- Subqueries
MATCH (n) WHERE EXISTS { MATCH (n)-[:KNOWS]->() }
RETURN n

Patterns

(n)                                -- Any node
(n:Person)                         -- Node with label
(n:Person {age: 30})               -- Node with property
(a)-[r:KNOWS]->(b)                 -- Directed relationship
(a)-[r:KNOWS|LIKES]->(b)           -- Multiple types
(a)-[*1..3]->(b)                   -- Variable-length (1 to 3 hops)
(a)-[*]->(b)                       -- Any length
p = (a)-[*]->(b)                   -- Bind path to variable

Functions

Category Functions
String toLower, toUpper, trim, split, replace, substring, left, right, reverse, size
Math abs, ceil, floor, round, sqrt, pow, exp, log, sin, cos, tan, pi, e
List head, tail, last, range, size, reverse, sort, collect, reduce, filter, extract
Aggregation count, sum, avg, min, max, collect, stDev, percentileDisc
Predicate all, any, none, single, exists, isEmpty
Temporal date, datetime, localDatetime, time, localtime, duration, now
Spatial point, distance
Graph id, labels, type, keys, properties, nodes, relationships, startNode, endNode
Conversion toInteger, toFloat, toString, toBoolean, coalesce

Temporal types (full precision)

RETURN date('2024-01-15')
RETURN datetime('2024-01-15T14:30:00[Europe/London]')  -- IANA timezone
RETURN duration('P1Y2M3DT4H5M6.789S')
RETURN duration('PT0.000000789S').nanoseconds  -- 789
RETURN localdatetime('+999999999-12-31T23:59:59')
RETURN date('2024-01-01') + duration('P1M')  -- 2024-02-01
RETURN duration.between(date('2020-01-01'), date('2024-01-01'))

Datasets

Canonical open-dataset catalogs (graphforge.datasets, SNAP / LDBC / NetworkRepository convenience loaders) are a backlog extension and are not shipped with v0.5.0. Build graphs with the construction APIs or Cypher today. Planned catalog notes live under Datasets (reference).


Architecture

GraphForge exposes one Rust-owned engine through Cypher and analyst-intent APIs:

forge.execute("MATCH ...")       → Cypher compiler and execution pipeline
forge.rank(..., by=...)          → Rust algorithm dispatch → Arrow Table
forge.cluster(..., by=...)       → Rust algorithm dispatch → Arrow Table
forge.similar(..., by=...)       → Rust algorithm dispatch → Arrow Table
forge.paths(..., by=...)         → Rust algorithm dispatch → Arrow Table
forge.analyze(..., by=...)       → Rust algorithm dispatch → Arrow Table
forge.find(...)                  → Search path → Arrow Table

The Cypher path is four independent Rust layers:

graphforge-cypher → graphforge-ir → graphforge-rel → graphforge-exec
                                      ↘ graphforge-storage (Parquet)

Algorithm verbs bypass the Cypher parser and dispatch directly to typed Rust handlers. Every result is an Apache Arrow Table with public UUID identity. Python and Node adapt arguments and native Arrow data; igraph and NetworkX are optional development parity oracles, never runtime backends or fallbacks. Graph data persists as Arrow/Parquet; metadata uses JSON.


Development

The agent skills package has a deterministic local NPX pack, offline install, and invocation workflow.

Documentation is an Astro Starlight site under docs-site/. Markdown sources stay in docs/; the site syncs allowlisted pages into the Starlight content collection at build time.

# Docs site (local) — see also docs/README.md and docs-site/README.md
pnpm install
pnpm docs:dev          # http://localhost:4321/
pnpm docs:build        # output: docs-site/dist/
pnpm docs:preview      # serve docs-site/dist/
# or: make docs-serve / make docs-build / make docs-clean

# Install with dev dependencies
uv sync --dev

# Run all checks (mirrors CI)
make pre-push

# Targeted Rust gates while iterating
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace

Binding Release Candidate is post-merge, main-only evidence. Dispatch it with the current 40-character main commit SHA; the workflow rejects branch heads and stale commits before any platform matrix build starts.


Roadmap

Version Focus Status
v0.5.2 Coordinated release across crates, PyPI, npm, CLI, skills, and docs Current
v0.5.x Follow-on surfaces (mobile bindings abandoned for now) Planned
v1.0 Long-term API stability commitment Future

Next steps: installquick startdocs site. Contributors start at Contributing; operators at Publishing.

See docs/releases/roadmap.md for delivery detail. Release notes are attached to each immutable GitHub Release.


License

Open source under the Apache License 2.0 (Apache-2.0) © Curate Labs Inc. You may use, modify, and distribute GraphForge, including for commercial purposes, subject to the license terms. See LICENSE and licensing details.

Built on Apache Arrow, DataFusion, Parquet, and the openCypher specification.

About

An embedded, openCypher-compatible graph workspace for Python, Node, (Swift, and Kotlin coming soon)

Resources

Code of conduct

Contributing

Security policy

Stars

52 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages