This repository contains the official Neo4j driver for .NET.
For contribution guidance, see Contributing.
dotnet add package Neo4j.Driver
The package targets .NET 8, .NET 9, and .NET 10.
Neo4j.Driver is strong-named by default. Unlike previous major versions, there is no separate Neo4j.Driver.Signed package.
Neo4j.Driver.Reactive provides reactive (IObservable-based) APIs built on top of the core driver:
dotnet add package Neo4j.Driver.Reactive
Driver upgrades within a major version will not contain breaking API changes, with the exception of the Neo4j.Driver.Preview namespace, which is reserved for feature previews.
Use bolt:// for a direct connection to a single server, or neo4j:// for a routing connection (required for clusters and recommended for Neo4j Aura). Append +s to require TLS (e.g. neo4j+s://), or +ssc to allow self-signed certificates.
using Neo4j.Driver;
await using var driver = GraphDatabase.Driver(
"neo4j+s://<dbid>.databases.neo4j.io",
AuthTokens.Basic("neo4j", "<password>"));IDriver maintains a connection pool internally. Create a single instance per application and share it across threads — IDriver is thread-safe. Sessions and transactions are not thread-safe and should not be shared across threads.
await driver.VerifyConnectivityAsync();Throws an exception if the server is unreachable or the credentials are invalid.
var config = new QueryConfig(database: "neo4j");Specifying the database avoids a server round-trip to determine the home database. Omitting it is only appropriate when working against a single-database deployment where the database name is genuinely unknown.
ExecutableQuery is the most concise API for running a single query in its own transaction. It handles retries and result materialisation automatically.
ExecuteAsync returns an EagerResult<IReadOnlyList<IRecord>> containing all records (Result), the returned column names (Keys), and a query summary (Summary). It can be destructured directly:
var (records, summary, keys) = await driver
.ExecutableQuery("MATCH (n:Movie) RETURN n.title, n.released")
.WithConfig(new QueryConfig(database: "neo4j"))
.ExecuteAsync();To map results directly to a type, chain AsObjectsAsync<T>():
record Movie(string title, int released);
var movies = await driver
.ExecutableQuery("MATCH (n:Movie) RETURN n.title, n.released")
.WithConfig(new QueryConfig(database: "neo4j"))
.ExecuteAsync()
.AsObjectsAsync<Movie>();
foreach (var movie in movies)
Console.WriteLine(movie);For multi-query transactions, use ExecuteReadAsync or ExecuteWriteAsync on a session. The driver automatically retries the work on transient failures.
await using var session = driver.AsyncSession(o => o.WithDatabase("neo4j"));
// Read transaction
var names = await session.ExecuteReadAsync(async tx =>
{
var cursor = await tx.RunAsync("MATCH (p:Person) RETURN p.name AS name");
return await cursor.ToListAsync(r => r["name"].As<string>());
});
// Write transaction
await session.ExecuteWriteAsync(tx =>
tx.RunAsync("CREATE (:Person {name: $name})", new { name = "Alice" }));Use BeginTransactionAsync when you need to co-ordinate a transaction with external work, such as committing only after a side-effect succeeds.
await using var session = driver.AsyncSession(o => o.WithDatabase("neo4j"));
await using var tx = await session.BeginTransactionAsync();
try
{
await tx.RunAsync("CREATE (:Person {name: $name})", new { name = "Bob" });
await tx.CommitAsync();
}
catch
{
await tx.RollbackAsync();
throw;
}Values in a record are exposed as object. Use the As<T>() extension method to convert to the expected type:
string name = record["name"].As<string>();
long count = record["count"].As<long>();| Cypher Type | .NET Driver Type |
|---|---|
| null | null |
| List | IList<object> |
| Map | IDictionary<string, object> |
| Boolean | bool |
| Integer | long |
| Float | double |
| String | string |
| ByteArray | byte[] |
| Point | Point |
| Node | INode |
| Relationship | IRelationship |
| Path | IPath |
| Cypher Type | Driver Type | Convertible CLR Types |
|---|---|---|
| Date | LocalDate |
DateTime, DateOnly (.NET 6+) |
| Time | OffsetTime |
TimeOnly (.NET 6+) |
| LocalTime | LocalTime |
TimeSpan, DateTime |
| DateTime | ZonedDateTime |
DateTimeOffset |
| LocalDateTime | LocalDateTime |
DateTime |
| Duration | Duration |
— |
- Documentation: neo4j.com/docs/dotnet-manual
- Community forum: community.neo4j.com
- Stack Overflow: stackoverflow.com/questions/tagged/neo4j
- Bug reports / feature requests: GitHub Issues
- Enterprise support: support.neo4j.com