# How to Integrate Neo4j as a Graph Store Backend in Semantica: A Complete Setup Guide

> Easily integrate Neo4j as a graph store backend in Semantica. Follow our guide to install the Neo4j driver, configure Semantica, and connect your graph database for powerful AI applications.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-16

---

**To integrate Neo4j as a graph store backend in Semantica, install the Neo4j Python driver, configure the backend in your [`semantica.yaml`](https://github.com/semantica-agi/semantica/blob/main/semantica.yaml) file or via CLI flags, and instantiate the `GraphStore` with the `"neo4j"` backend identifier.**

Semantica provides a pluggable graph-store architecture that supports multiple backends including Neo4j, Amazon Neptune, FalkorDB, and an in-memory store. This guide walks you through configuring Neo4j integration using the actual source implementation from the `semantica-agi/semantica` repository.

---

## Architecture Overview

The Neo4j integration in Semantica consists of three core modules:

| Component | File Path | Purpose |
|-----------|-----------|---------|
| **Neo4jStore** | [`semantica/graph_store/neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/neo4j_store.py) | Low-level CRUD operations, Cypher query generation, and transaction management |
| **Backend Registry** | [`semantica/graph_store/registry.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/registry.py) | Maps the `"neo4j"` string identifier to the `Neo4jStore` implementation class |
| **Configuration Parser** | [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py) | Pydantic models for validating Neo4j connection settings (URI, auth, TLS) |

All high-level graph operations in Semantica route through the `GraphStore` facade, which delegates to `Neo4jStore` when the `backend` parameter is set to `"neo4j"`.

---

## Step 1: Install the Neo4j Python Driver

Semantica keeps the core framework lightweight by not bundling backend-specific drivers. Add the official Neo4j driver to your environment:

```bash
pip install neo4j

```

The [`neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/neo4j_store.py) module imports the driver at line 251:

```python
from neo4j import GraphDatabase

```

This provides the `GraphDatabase.driver()` method used for connection pooling and session management.

---

## Step 2: Configure the Neo4j Backend

Semantica reads configuration from a YAML file (default: [`semantica.yaml`](https://github.com/semantica-agi/semantica/blob/main/semantica.yaml) in the project root). Add a `graph_db` section with the Neo4j backend specified:

```yaml
graph_db:
  backend: neo4j
  uri: bolt://localhost:7687
  username: neo4j
  password: your_secure_password
  
  # Optional TLS configuration

  tls: false
  # tls_cert_path: /path/to/ca-cert.pem

```

The `GraphStoreConfig` class in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py) validates these fields and provides defaults for optional parameters.

---

## Step 3: Initialize the Graph Store

### Option A: Using the Semantica CLI

The CLI provides a convenience command for connecting to a graph store backend:

```bash
semantica store connect \
    --backend neo4j \
    --uri bolt://localhost:7687 \
    --username neo4j \
    --password your_secure_password

```

The CLI parses these arguments and constructs a `GraphStore` instance with the appropriate configuration.

### Option B: Direct Python Instantiation

```python
from semantica.graph_store import GraphStore

# Configuration auto-discovered from semantica.yaml

store = GraphStore(backend="neo4j")

```

Or pass configuration explicitly:

```python
from semantica.graph_store import GraphStore
from semantica.graph_store.config import GraphStoreConfig

config = GraphStoreConfig(
    backend="neo4j",
    uri="bolt://localhost:7687",
    username="neo4j",
    password="your_secure_password"
)

store = GraphStore(config=config)

```

Internally, `GraphStore.__init__` resolves the backend string through the registry. At line 567 of [`graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/graph_store.py), the implementation performs:

```python
if backend == "neo4j":
    from .neo4j_store import Neo4jStore
    self.store = Neo4jStore(self.config)

```

---

## Step 4: Execute Graph Operations

Once initialized, the `GraphStore` exposes a unified API regardless of backend. All operations delegate to `Neo4jStore` methods that generate and execute Cypher queries.

### Create Nodes

```python

# Create a node with labels and properties

node_id = store.create_node(
    labels=["Person", "Employee"],
    properties={
        "name": "Alice Chen",
        "department": "Engineering",
        "joined": 2023
    }
)
print(f"Created node with ID: {node_id}")

```

### Create Relationships

```python

# Create a directed relationship between nodes

store.create_relationship(
    start_node_id=alice_id,
    end_node_id=bob_id,
    rel_type="MANAGES",
    properties={"since": "2024-01-15"}
)

```

### Run Custom Cypher Queries

The store sanitizes all inputs to prevent Cypher injection:

```python

# Parameterized query execution

results = store.query(
    "MATCH (p:Person {department: $dept})-[:MANAGES]->(sub) RETURN p.name, sub.name",
    parameters={"dept": "Engineering"}
)

for record in results:
    print(f"{record['p.name']} manages {record['sub.name']}")

```

The `Neo4jStore` class implements query parameterization in [`neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/neo4j_store.py) (lines 252–260), ensuring user inputs are never concatenated directly into Cypher strings.

---

## Step 5: Transaction Control

For operations requiring atomicity, use explicit transaction blocks via the `Neo4jTransaction` wrapper:

```python
with store.begin_transaction() as tx:
    # Multiple operations in a single transaction

    tx.run(
        "CREATE (p:Person {id: $id, name: $name})",
        id=1001, name="Dana Smith"
    )
    tx.run(
        "MATCH (m:Person {name: $manager}) CREATE (p)-[:REPORTS_TO]->(m)",
        manager="Alice Chen"
    )
    # Commit occurs automatically on successful exit

```

The `Neo4jTransaction` class in [`neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/neo4j_store.py) handles `session.begin_transaction()` lifecycle management, including proper rollback on exceptions.

---

## Step 6: Verify the Integration

Semantica includes integration tests for the Neo4j backend. After configuring a live Neo4j instance (or using the Neo4j test container), run:

```bash

# Run all Neo4j-specific tests

pytest tests/ -k neo4j -v

# Run the full graph store test suite

pytest tests/test_graph_store.py

```

Key test modules to verify functionality:

| Test File | Coverage |
|-----------|----------|
| [`tests/graph_store/test_neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/tests/graph_store/test_neo4j_store.py) | Connection, CRUD, and query operations |
| [`tests/graph_store/test_cypher_injection.py`](https://github.com/semantica-agi/semantica/blob/main/tests/graph_store/test_cypher_injection.py) | Input sanitization and security |
| [`tests/utils/test_normalize_graph_payload.py`](https://github.com/semantica-agi/semantica/blob/main/tests/utils/test_normalize_graph_payload.py) | Data serialization round-trips |

Successful test execution confirms that `Neo4jStore` correctly implements the `GraphStore` interface contract.

---

## Configuration Reference

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `backend` | Yes | — | Must be `"neo4j"` |
| `uri` | Yes | — | Bolt URI (e.g., `bolt://host:7687`) |
| `username` | Yes | — | Neo4j authentication username |
| `password` | Yes | — | Neo4j authentication password |
| `database` | No | `"neo4j"` | Target database name |
| `tls` | No | `false` | Enable encrypted connections |
| `tls_cert_path` | No | `null` | Path to custom CA certificate |
| `max_connection_pool_size` | No | `50` | Driver connection pool limit |

These fields are defined in the `Neo4jConfig` Pydantic model within [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py).

---

## Summary

- **Install dependency**: `pip install neo4j` to provide the driver that [`neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/neo4j_store.py) imports
- **Configure backend**: Set `backend: neo4j` in [`semantica.yaml`](https://github.com/semantica-agi/semantica/blob/main/semantica.yaml) with connection credentials
- **Instantiate store**: Use `GraphStore(backend="neo4j")` or the CLI `store connect` command
- **Execute operations**: Standard `create_node`, `create_relationship`, and `query` methods automatically generate sanitized Cypher
- **Manage transactions**: Use `begin_transaction()` context manager for atomic multi-operation batches

The Semantica Neo4j integration provides production-ready graph persistence with connection pooling, parameterized queries, and full transaction support.

---

## Frequently Asked Questions

### What versions of Neo4j are compatible with Semantica?

Semantica uses the official `neo4j` Python driver, which supports Neo4j server versions 4.x and 5.x. The driver handles protocol negotiation automatically. Check your driver version with `pip show neo4j` and consult the Neo4j driver documentation for specific server compatibility matrices.

### Can I use Neo4j AuraDB with Semantica?

Yes. Configure the `uri` parameter with your AuraDB connection string (format: `neo4j+s://xxxx.databases.neo4j.io`) and enable TLS by setting `tls: true` in your configuration. AuraDB's required encryption is handled transparently by the driver's `neo4j+s` scheme.

### How does Semantica prevent Cypher injection attacks?

The `Neo4jStore` implementation in [`neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/neo4j_store.py) exclusively uses parameterized queries. All user-provided values are passed through the driver's parameter binding mechanism (e.g., `$param_name` placeholders) rather than string concatenation. This approach eliminates injection vectors at the driver level.

### What happens if the Neo4j connection fails during initialization?

`Neo4jStore.__init__` validates connectivity by attempting a lightweight server handshake. If the connection fails, it raises a `GraphStoreConnectionError` with details from the underlying Neo4j driver exception. The error includes the target URI and suggested troubleshooting steps (check credentials, network, server status).