removed from unescaped ids |\n\n### Vector Index Queries (version-branched)\n\n| Version | Syntax |\n|---|---|\n| Neo4j \u003c 2026.01 | `CALL db.index.vector.queryNodes(idx, k, $emb) YIELD node, score` |\n| Neo4j >= 2026.01 | `SEARCH n IN (VECTOR INDEX idx FOR $emb LIMIT k) SCORE AS score` |\n\n### Cypher Dialect Prefix Rule\n\n- Target >= 2025.06, dialect = Cypher 25: prepend `CYPHER 25` to every top-level query\n- Target >= 2025.06, dialect = Cypher 5: prepend `CYPHER 5` (keeps deprecated forms working)\n- Target 4.x or 5.x: no prefix needed; fetch changelog per [references/cypher-queries.md](references/cypher-queries.md)\n\n### `id(n)` → `elementId(n)` Caveats\n\n`elementId()` returns a string (e.g., `\"4:abc123:0\"`), not an integer. Fix downstream code that stores or compares it as `int`. Do NOT use `elementId()` values for numeric operations.\n\n```diff\n- WHERE id(n) = $nodeId # $nodeId was integer\n+ WHERE elementId(n) = $nodeId # $nodeId must now be string\n```\n\n---\n\n## Step 3 — Driver Migration\n\nPick the section(s) matching languages found in Step 1.\n\n---\n\n### Python Driver (5.x → 6.x)\n\n**Min requirements**: Python >= 3.10, `neo4j` package (6.0+, released Jan 12 2026)\n\n#### Package Rename — do this first\n\n```diff\n# requirements.txt\n- neo4j-driver>=5.0.0\n+ neo4j>=6.0.0\n```\n\n`neo4j-driver` package is deprecated since 6.0 and receives no further updates.\n\n#### Removed APIs\n\n| Old | New | Notes |\n|---|---|---|\n| `session.read_transaction(fn)` | `session.execute_read(fn)` | |\n| `session.write_transaction(fn)` | `session.execute_write(fn)` | |\n| `session.last_bookmark()` | `session.last_bookmarks()` | Returns `Bookmarks` (plural) |\n| `Bookmark` class | `Bookmarks` class | |\n| `TRUST_ALL_CERTIFICATES` | `trusted_certificates=TrustAll()` | |\n| `TRUST_SYSTEM_CA_SIGNED_CERTIFICATES` | `trusted_certificates=TrustSystemCAs()` | |\n| `neo4j.conf`, `neo4j.data` modules | Removed — use top-level `neo4j.*` | |\n\n#### Resource Management Change\n\nDrivers and sessions no longer auto-close on GC. Add explicit cleanup:\n\n```diff\n- driver = GraphDatabase.driver(URI, auth=(USER, PASS))\n- # used without explicit close\n+ with GraphDatabase.driver(URI, auth=(USER, PASS)) as driver:\n+ with driver.session(database=\"neo4j\") as session:\n+ ...\n```\n\nOr call `.close()` explicitly. Repeated `.close()` is a no-op.\n\n#### Error Handling Changes\n\n| Old exception | New exception | Trigger |\n|---|---|---|\n| `ClientError` (for timeout) | `ConnectionAcquisitionTimeoutError` | Acquisition timeout |\n| `AuthError` (invalid config) | `ConfigurationError` | Invalid auth params |\n| `ValueError` raised for `Query` obj | `TypeError` | Passing `Query` to `Transaction.run` |\n\n#### Key APIs Unchanged\n\n`execute_query()`, `GraphDatabase.driver()`, `neo4j+s://` URI, `auth=(user, pw)`, session `run()`.\n\nFull changelog: [references/python-driver.md](references/python-driver.md)\n\n---\n\n### JavaScript / Node.js Driver (5.x → 6.x)\n\n**Min requirements**: Node.js >= 18 (check `engines` in driver's `package.json`); package `neo4j-driver`\n\n#### Removed APIs\n\n| Old | New | Notes |\n|---|---|---|\n| `session.readTransaction(fn)` | `session.executeRead(fn)` | |\n| `session.writeTransaction(fn)` | `session.executeWrite(fn)` | |\n| `session.lastBookmark()` | `session.lastBookmarks()` | Returns array |\n| `resultSummary.updateStatistics` | `resultSummary.counters` | |\n| `driver.verifyConnectivity()` → `ServerInfo` | `driver.getServerInfo()` → `ServerInfo` | `verifyConnectivity()` now returns `void` |\n\n#### Deprecated in 6.0 (will be removed in 7.0)\n\n| Old | New |\n|---|---|\n| `isRetriableError(err)` | `isRetryable(err)` |\n| `neo4jError.retriable` | `neo4jError.retryable` |\n| `notificationCategory` | `notificationClassification` |\n\n#### Integer Handling\n\nNeo4j integers map to `neo4j.Integer` (64-bit). Use `.toNumber()` or `.toInt()` for arithmetic. Large values (> 2^53) lose precision — store as string with `.toString()`.\n\n```javascript\n// Safe pattern\nconst count = record.get('count').toNumber()\n```\n\nFull changelog: [references/javascript-driver.md](references/javascript-driver.md)\n\n---\n\n### Java Driver (5.x → 6.x)\n\n**Min requirements**: Java 21; Maven `org.neo4j.driver:neo4j-java-driver:6.x`\n\n#### Maven Coordinates\n\n```diff\n\u003cdependency>\n \u003cgroupId>org.neo4j.driver\u003c/groupId>\n \u003cartifactId>neo4j-java-driver\u003c/artifactId>\n- \u003cversion>5.x.x\u003c/version>\n+ \u003cversion>6.0.0\u003c/version>\n\u003c/dependency>\n```\n\n#### Removed APIs\n\n| Removed | Replacement | Notes |\n|---|---|---|\n| `RxSession` / `RxTransaction` | Use async `AsyncSession` or sync `Session` | Reactive API removed |\n| `Bookmark` multi-value constructor | `Bookmark.from(iterable)` | |\n| `session.readTransaction(fn)` | `session.executeRead(fn)` | |\n| `session.writeTransaction(fn)` | `session.executeWrite(fn)` | |\n| `TrustStrategy.certFile()` | `TrustStrategy.trustCustomCertificateSignedBy(path)` | |\n| `Notification.severity()` | `Notification.severityLevel()` | Returns typed enum |\n\n#### Dependency Note (BOM)\n\n`neo4j-java-driver-bom` no longer imports `netty-bom` as of 6.0.1. If using Netty native transport, add explicit `netty-bom` import.\n\n#### Logging\n\nLegacy `Logging` API deprecated → configure `System.Logger` instead.\n\nFull changelog: [references/java-driver.md](references/java-driver.md)\n\n---\n\n### .NET Driver (5.x → 6.x)\n\n**Min requirements**: .NET 8, 9, or 10 (.NET Standard 2.1 dropped); NuGet `Neo4j.Driver 6.x`\n\n#### NuGet Package\n\n```diff\n- \u003cPackageReference Include=\"Neo4j.Driver\" Version=\"5.*\" />\n+ \u003cPackageReference Include=\"Neo4j.Driver\" Version=\"6.*\" />\n```\n\n`Neo4j.Driver.Signed` no longer receives updates — switch to `Neo4j.Driver` (now signed).\n\n#### Removed APIs\n\n| Removed | Replacement | Notes |\n|---|---|---|\n| `ILogger` | `INeo4jLogger` | Interface renamed |\n| `ConfigBuilder.WithIpv6Enabled()` | Remove call — IPv6 always enabled | |\n| `Config.Ipv6Enabled` property | Remove — always true | |\n| Simple driver | Use standard `IDriver` | Removed entirely |\n\nFull changelog: [references/dotnet-driver.md](references/dotnet-driver.md)\n\n---\n\n### Go Driver (5.x → 6.x)\n\n**Min requirements**: Go 1.24; module `github.com/neo4j/neo4j-go-driver/v6`\n\n#### go.mod Update\n\n```diff\n- require github.com/neo4j/neo4j-go-driver/v5 v5.x.x\n+ require github.com/neo4j/neo4j-go-driver/v6 v6.x.x\n```\n\nUpdate all imports from `/v5/` to `/v6/`.\n\n#### Removed APIs and Replacements\n\n| Old | New | Notes |\n|---|---|---|\n| `neo4j.NewDriver(...)` | `neo4j.NewDriverWithContext(...)` | Context-aware; or just use `neo4j.NewDriver` (now has context) |\n| `neo4j.Config` struct | `config.Config` | Import `github.com/neo4j/neo4j-go-driver/v6/neo4j/config` |\n| `neo4j.ServerAddressResolver` | `config.ServerAddressResolver` | |\n| `neo4j.LogLevel` / `neo4j.ERROR` etc. | `log.Level` / `log.ERROR` | Import `neo4j/log` sub-package |\n| `log.Console` | `log.ToConsole` | |\n| `log.Void` | `log.ToVoid` | |\n| `neo4j.Single[T]` | `neo4j.SingleT[T]` (still present; context variant preferred) | |\n| `neo4j.Driver` interface | `neo4j.DriverWithContext` | `*WithContext` variants are now primary |\n| `neo4j.Session` interface | `neo4j.SessionWithContext` | |\n| `Config.RootCAs` field | `Config.TlsConfig` | Pass `*tls.Config` directly |\n| Notification constants (old pkg) | `notifications.*` equivalents | Import `neo4j/notifications` |\n\n#### Context API Consolidation\n\nIn v6, `neo4j.NewDriverWithContext` is the canonical constructor. The old `*WithContext` method names are deprecated (targeted for removal in v7) — base names now include context by default.\n\n```diff\n- driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(user, pass, \"\"))\n+ driver, err := neo4j.NewDriverWithContext(uri, neo4j.BasicAuth(user, pass, \"\"))\n```\n\nFull migration guide: [references/go-driver.md](references/go-driver.md)\n\n---\n\n## Step 4 — Version Compatibility Matrix\n\n| Neo4j version | Cypher dialect | Driver 6.x compatible | Notes |\n|---|---|---|---|\n| 4.4 LTS | Cypher 4 | Yes (bolt compat) | Support ended Nov 2025 |\n| 5.26 LTS | Cypher 5 | Yes | Supported until Nov 2028 |\n| 2025.01–2025.05 | Cypher 5 | Yes | CalVer era begins |\n| 2025.06+ | Cypher 5 or 25 | Yes | Cypher 25 new default |\n| 2026.01+ | Cypher 25 | Yes | `SEARCH` clause available |\n| 2026.07.0 | Cypher 25 | Yes | **Skip this patch** — block-format UTF-8 regression makes `trim()` fail queries and corrupt stored strings; upgrade target is 2026.07.1 |\n| 2026.08+ | Cypher 25 | Yes | `UUID` type + string interpolation added; `UUID` properties require driver >= 6.2 (Python >= 6.3) — older drivers return placeholder `MAP` and warn `03N95`; 2026.08 bundles Java driver 6.2.1; **skip 2026.08.0** (query-failure bug) — target 2026.08.1+ |\n| 2026.09+ | Cypher 25 | Yes | `SEARCH` clause accepts `FULLTEXT INDEX`; page cache reserves full `server.memory.pagecache.size` at startup |\n\nStore format: no changes between 4.4 and 2026.x. `block` format default for new Enterprise dbs since 5.22. `high_limit` and `standard` deprecated in 5.23, removed after 2026 LTS — Neo4j refuses to start on a `high_limit` store after that LTS; run offline `neo4j-admin database migrate --to-format=block \u003cdb>` on or before the LTS.\n\nServer JVM: 2026.x runs on Java SE 21 or 25; Java 21 support ends with the 2026 LTS — move servers to Java 25 [2026.08 deprecation].\n\n**No downgrades supported** — take a backup before any server upgrade.\n\n---\n\n## Step 5 — Test After Migration\n\n```bash\n# Python: run with dev mode to surface all deprecation warnings\npython -W error::DeprecationWarning -m pytest tests/\n\n# JS: run tests\nnpm test\n\n# Java\nmvn test\n\n# .NET\ndotnet test\n\n# Go\ngo test ./...\n```\n\nAfter test run: if any `DeprecationWarning` or deprecated-API log appears, treat as ERROR — fix before proceeding.\n\nFor Cypher: run each migrated query through `EXPLAIN` first:\n\n```bash\n# Via Query API v2\ncurl -X POST https://\u003chost>/db/\u003cdatabase>/query/v2 \\\n -u \u003cuser>:\u003cpassword> -H \"Content-Type: application/json\" \\\n -d '{\"statement\": \"EXPLAIN \u003cyour query>\"}'\n```\n\n---\n\n## Common Migration Errors\n\n| Error | Cause | Fix |\n|---|---|---|\n| `id(n)` returns string, int comparison fails | `elementId()` returns string | Update stored IDs to string; fix WHERE clauses |\n| `Cannot merge node using null property value` | MERGE key resolved to null | Validate params before MERGE |\n| `Neo4j.Driver.Exceptions.AuthenticationException` | Wrong credential config after .NET rename | Update `INeo4jLogger` usage; verify config |\n| `TypeError: neo4j-driver is deprecated` | Old package installed | Replace with `neo4j>=6.0.0` in requirements |\n| `AttributeError: 'Session' has no 'read_transaction'` | Python 5→6, method removed | Replace with `execute_read()` |\n| `RxSession not found` | Java 6.x, Reactive API removed | Migrate to async or sync session |\n| `undefined is not a function (.readTransaction)` | JS 6.x, method removed | Replace with `executeRead()` |\n| Go: `undefined: neo4j.Config` | v5 import path still present | Update all imports to `/v6/` |\n| `PERIODIC COMMIT not supported` | Cypher 25, clause removed | Use `CALL (...) IN TRANSACTIONS` |\n| `Unknown function id()` | id() removed in Cypher 25 | Replace with `elementId()` |\n\n---\n\n## References\n\nLoad on demand — high discovery rate because explicitly linked:\n- [references/cypher-queries.md](references/cypher-queries.md) — version-branched Cypher changelog selection (4.x, 5.x, 2025.x)\n- [references/python-driver.md](references/python-driver.md) — Python changelog URLs, full version history\n- [references/javascript-driver.md](references/javascript-driver.md) — JS changelog URLs by version\n- [references/java-driver.md](references/java-driver.md) — Java changelog URLs by version\n- [references/dotnet-driver.md](references/dotnet-driver.md) — .NET changelog URLs by version\n- [references/go-driver.md](references/go-driver.md) — Go migration guide with 5.0 and 6.0 sections\n\nFor any syntax not covered above, fetch:\n`https://neo4j.com/docs/cypher-manual/25/deprecations-additions-removals-compatibility/`\n\n---\n\n## Checklist\n\n- [ ] Target Neo4j version confirmed; Cypher dialect selected (Cypher 5 or 25)\n- [ ] Dependency files scanned; all driver versions identified\n- [ ] Cypher substitution table applied to every query in codebase\n- [ ] `id(n)` → `elementId(n)` and downstream int→string conversions fixed\n- [ ] `PERIODIC COMMIT` → `CALL IN TRANSACTIONS` in all batch writes\n- [ ] `CALL { WITH x ... }` → `CALL (x) { ... }` in all subqueries\n- [ ] Package renames done (Python: `neo4j-driver` → `neo4j`)\n- [ ] Deprecated session methods replaced (`read_transaction`/`readTransaction` → `execute_read`/`executeRead`)\n- [ ] Resource cleanup added where missing (Python: context managers or `.close()`)\n- [ ] Bookmark API updated (`last_bookmark` → `last_bookmarks`, `Bookmark` → `Bookmarks`)\n- [ ] Go imports updated from `/v5/` to `/v6/`; `neo4j.Config` → `config.Config`\n- [ ] Java: Java 21 confirmed; RxSession usages removed\n- [ ] .NET: `ILogger` → `INeo4jLogger`; `Neo4j.Driver.Signed` → `Neo4j.Driver`\n- [ ] Tests pass with no DeprecationWarnings\n- [ ] `EXPLAIN` run on all migrated Cypher queries; no errors\n","licenseDocuments":[]}}
The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
Development · SKILL.md

neo4j-migration-skill

neo4j-migration-skill

Migrates Neo4j driver code and Cypher queries from older versions (4.x, 5.x) to current (2025.x/2026.x, Cypher 25). Covers Python, JavaScript/Node.js, Java, .NET, and Go drivers — package renames, removed APIs, version requirements, diff-ready fixes. Also handles Cypher syntax migration — QPE paths, CALL subqueries, id() → elementId(), PERIODIC COMMIT → CAL…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill documentation

GitHub

name: neo4j-migration-skill description: Migrates Neo4j driver code and Cypher queries from older versions (4.x, 5.x) to current (2025.x/2026.x, Cypher 25). Covers Python, JavaScript/Node.js, Java, .NET, and Go drivers — package renames, removed APIs, version requirements, diff-ready fixes. Also handles Cypher syntax migration — QPE paths, CALL subqueries, id() → elementId(), PERIODIC COMMIT → CALL IN TRANSACTIONS, and all Cypher 25 removals. Does NOT write new Cypher queries — use neo4j-cypher-skill. Does NOT cover DB administration or server ops — use neo4j-cli-tools-skill. Does NOT provision new Neo4j instances — use neo4j-getting-started-skill. allowed-tools: WebFetch Bash version: 1.0.11

When to Use

  • Upgrading driver dependency from 4.x or 5.x to 6.x
  • Migrating Cypher queries to Cypher 25 syntax
  • Fixing deprecated API warnings after a driver or Neo4j version bump
  • Auditing a codebase for removed/deprecated Neo4j APIs before upgrading

When NOT to Use

  • Writing new Cypher queries → neo4j-cypher-skill
  • DB admin (backup, restore, import, cypher-shell) → neo4j-cli-tools-skill
  • Starting fresh → neo4j-getting-started-skill
  • GDS algorithm migration — not covered here; consult GDS release notes

Entry Criteria

Before starting, ask:

  1. Target Neo4j version — needed to select Cypher dialect and driver version
  2. Languages in use — scan package.json, requirements.txt, pom.xml, *.csproj, go.mod
  3. Current driver versions — read from dependency files; do NOT guess

If target is >= 2025.06: ask whether Cypher 5 or Cypher 25 dialect will be used (both supported; Cypher 25 is the new default).


Step 1 — Scan Codebase

# Find Cypher strings (queries embedded in source)
grep -rn "MATCH\|MERGE\|CREATE\|CALL\|RETURN" --include="*.py" --include="*.js" \
  --include="*.ts" --include="*.java" --include="*.cs" --include="*.go" \
  --include="*.cypher" --include="*.cql" . | grep -v ".git"

# Find dependency files
find . -name "requirements*.txt" -o -name "package.json" -o -name "pom.xml" \
  -o -name "*.csproj" -o -name "go.mod" | grep -v ".git" | grep -v node_modules

Collect findings before modifying anything. List all deprecated patterns found.


Step 2 — Cypher Migration (4.x / 5.x → Cypher 25)

Apply to every Cypher string, .cypher file, OGM/SDN @Query annotation, and template literal.

Complete Substitution Table

Old syntaxCypher 25 replacementNotes
[:REL*1..5](()-[:REL]->()){1,5}QPE quantifier group
[:REL*](()-[:REL]->()){1,}Unbounded QPE
[:REL*0..5](()-[:REL]->()){0,5}Zero-hop allowed
shortestPath((a)-[*]->(b))SHORTEST 1 (a)(()-[]->()){1,}(b)QPE shortest path
allShortestPaths((a)-[*]->(b))ALL SHORTEST (a)(()-[]->()){1,}(b)QPE all-shortest
id(n)elementId(n)Returns string, not int
CALL { WITH x ... }CALL (x) { ... }Explicit import syntax
PERIODIC COMMITCALL (...) { ... } IN TRANSACTIONS OF 1000 ROWSBatched writes
-- comment// commentSQL comment invalid
SET n = r (structural val)SET n = properties(r)Extract map first
MERGE (a {x:1})-[:T]->(b {x:a.x})Rewrite — cross-entity MERGE refs disallowedSplit into MATCH+MERGE
CREATE INDEX ... OPTIONS { indexProvider: ... }Remove indexProvider from OPTIONSProvider selection removed
db.create.setVectorProperty(...)Use native VECTOR property typeProcedure removed
dbms.upgrade() / dbms.upgradeStatus()Use cypher-shell :sysinfoProcedures removed
USE composite.'1'USE `composite.1`Backtick entire qualified name
RETURN 1 as my$IdentifierRETURN 1 as `my$Identifier`$ removed from unescaped ids

Vector Index Queries (version-branched)

VersionSyntax
Neo4j < 2026.01CALL db.index.vector.queryNodes(idx, k, $emb) YIELD node, score
Neo4j >= 2026.01SEARCH n IN (VECTOR INDEX idx FOR $emb LIMIT k) SCORE AS score

Cypher Dialect Prefix Rule

  • Target >= 2025.06, dialect = Cypher 25: prepend CYPHER 25 to every top-level query
  • Target >= 2025.06, dialect = Cypher 5: prepend CYPHER 5 (keeps deprecated forms working)
  • Target 4.x or 5.x: no prefix needed; fetch changelog per references/cypher-queries.md

id(n) → elementId(n) Caveats

elementId() returns a string (e.g., "4:abc123:0"), not an integer. Fix downstream code that stores or compares it as int. Do NOT use elementId() values for numeric operations.

- WHERE id(n) = $nodeId   # $nodeId was integer
+ WHERE elementId(n) = $nodeId  # $nodeId must now be string

Step 3 — Driver Migration

Pick the section(s) matching languages found in Step 1.


Python Driver (5.x → 6.x)

Min requirements: Python >= 3.10, neo4j package (6.0+, released Jan 12 2026)

Package Rename — do this first

# requirements.txt
- neo4j-driver>=5.0.0
+ neo4j>=6.0.0

neo4j-driver package is deprecated since 6.0 and receives no further updates.

Removed APIs

OldNewNotes
session.read_transaction(fn)session.execute_read(fn)
session.write_transaction(fn)session.execute_write(fn)
session.last_bookmark()session.last_bookmarks()Returns Bookmarks (plural)
Bookmark classBookmarks class
TRUST_ALL_CERTIFICATEStrusted_certificates=TrustAll()
TRUST_SYSTEM_CA_SIGNED_CERTIFICATEStrusted_certificates=TrustSystemCAs()
neo4j.conf, neo4j.data modulesRemoved — use top-level neo4j.*

Resource Management Change

Drivers and sessions no longer auto-close on GC. Add explicit cleanup:

- driver = GraphDatabase.driver(URI, auth=(USER, PASS))
- # used without explicit close
+ with GraphDatabase.driver(URI, auth=(USER, PASS)) as driver:
+     with driver.session(database="neo4j") as session:
+         ...

Or call .close() explicitly. Repeated .close() is a no-op.

Error Handling Changes

Old exceptionNew exceptionTrigger
ClientError (for timeout)ConnectionAcquisitionTimeoutErrorAcquisition timeout
AuthError (invalid config)ConfigurationErrorInvalid auth params
ValueError raised for Query objTypeErrorPassing Query to Transaction.run

Key APIs Unchanged

execute_query(), GraphDatabase.driver(), neo4j+s:// URI, auth=(user, pw), session run().

Full changelog: references/python-driver.md


JavaScript / Node.js Driver (5.x → 6.x)

Min requirements: Node.js >= 18 (check engines in driver's package.json); package neo4j-driver

Removed APIs

OldNewNotes
session.readTransaction(fn)session.executeRead(fn)
session.writeTransaction(fn)session.executeWrite(fn)
session.lastBookmark()session.lastBookmarks()Returns array
resultSummary.updateStatisticsresultSummary.counters
driver.verifyConnectivity() → ServerInfodriver.getServerInfo() → ServerInfoverifyConnectivity() now returns void

Deprecated in 6.0 (will be removed in 7.0)

OldNew
isRetriableError(err)isRetryable(err)
neo4jError.retriableneo4jError.retryable
notificationCategorynotificationClassification

Integer Handling

Neo4j integers map to neo4j.Integer (64-bit). Use .toNumber() or .toInt() for arithmetic. Large values (> 2^53) lose precision — store as string with .toString().

// Safe pattern
const count = record.get('count').toNumber()

Full changelog: references/javascript-driver.md


Java Driver (5.x → 6.x)

Min requirements: Java 21; Maven org.neo4j.driver:neo4j-java-driver:6.x

Maven Coordinates

<dependency>
  <groupId>org.neo4j.driver</groupId>
  <artifactId>neo4j-java-driver</artifactId>
- <version>5.x.x</version>
+ <version>6.0.0</version>
</dependency>

Removed APIs

RemovedReplacementNotes
RxSession / RxTransactionUse async AsyncSession or sync SessionReactive API removed
Bookmark multi-value constructorBookmark.from(iterable)
session.readTransaction(fn)session.executeRead(fn)
session.writeTransaction(fn)session.executeWrite(fn)
TrustStrategy.certFile()TrustStrategy.trustCustomCertificateSignedBy(path)
Notification.severity()Notification.severityLevel()Returns typed enum

Dependency Note (BOM)

neo4j-java-driver-bom no longer imports netty-bom as of 6.0.1. If using Netty native transport, add explicit netty-bom import.

Logging

Legacy Logging API deprecated → configure System.Logger instead.

Full changelog: references/java-driver.md


.NET Driver (5.x → 6.x)

Min requirements: .NET 8, 9, or 10 (.NET Standard 2.1 dropped); NuGet Neo4j.Driver 6.x

NuGet Package

- <PackageReference Include="Neo4j.Driver" Version="5.*" />
+ <PackageReference Include="Neo4j.Driver" Version="6.*" />

Neo4j.Driver.Signed no longer receives updates — switch to Neo4j.Driver (now signed).

Removed APIs

RemovedReplacementNotes
ILoggerINeo4jLoggerInterface renamed
ConfigBuilder.WithIpv6Enabled()Remove call — IPv6 always enabled
Config.Ipv6Enabled propertyRemove — always true
Simple driverUse standard IDriverRemoved entirely

Full changelog: references/dotnet-driver.md


Go Driver (5.x → 6.x)

Min requirements: Go 1.24; module github.com/neo4j/neo4j-go-driver/v6

go.mod Update

- require github.com/neo4j/neo4j-go-driver/v5 v5.x.x
+ require github.com/neo4j/neo4j-go-driver/v6 v6.x.x

Update all imports from /v5/ to /v6/.

Removed APIs and Replacements

OldNewNotes
neo4j.NewDriver(...)neo4j.NewDriverWithContext(...)Context-aware; or just use neo4j.NewDriver (now has context)
neo4j.Config structconfig.ConfigImport github.com/neo4j/neo4j-go-driver/v6/neo4j/config
neo4j.ServerAddressResolverconfig.ServerAddressResolver
neo4j.LogLevel / neo4j.ERROR etc.log.Level / log.ERRORImport neo4j/log sub-package
log.Consolelog.ToConsole
log.Voidlog.ToVoid
neo4j.Single[T]neo4j.SingleT[T] (still present; context variant preferred)
neo4j.Driver interfaceneo4j.DriverWithContext*WithContext variants are now primary
neo4j.Session interfaceneo4j.SessionWithContext
Config.RootCAs fieldConfig.TlsConfigPass *tls.Config directly
Notification constants (old pkg)notifications.* equivalentsImport neo4j/notifications

Context API Consolidation

In v6, neo4j.NewDriverWithContext is the canonical constructor. The old *WithContext method names are deprecated (targeted for removal in v7) — base names now include context by default.

- driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(user, pass, ""))
+ driver, err := neo4j.NewDriverWithContext(uri, neo4j.BasicAuth(user, pass, ""))

Full migration guide: references/go-driver.md


Step 4 — Version Compatibility Matrix

Neo4j versionCypher dialectDriver 6.x compatibleNotes
4.4 LTSCypher 4Yes (bolt compat)Support ended Nov 2025
5.26 LTSCypher 5YesSupported until Nov 2028
2025.01–2025.05Cypher 5YesCalVer era begins
2025.06+Cypher 5 or 25YesCypher 25 new default
2026.01+Cypher 25YesSEARCH clause available
2026.07.0Cypher 25YesSkip this patch — block-format UTF-8 regression makes trim() fail queries and corrupt stored strings; upgrade target is 2026.07.1
2026.08+Cypher 25YesUUID type + string interpolation added; UUID properties require driver >= 6.2 (Python >= 6.3) — older drivers return placeholder MAP and warn 03N95; 2026.08 bundles Java driver 6.2.1; skip 2026.08.0 (query-failure bug) — target 2026.08.1+
2026.09+Cypher 25YesSEARCH clause accepts FULLTEXT INDEX; page cache reserves full server.memory.pagecache.size at startup

Store format: no changes between 4.4 and 2026.x. block format default for new Enterprise dbs since 5.22. high_limit and standard deprecated in 5.23, removed after 2026 LTS — Neo4j refuses to start on a high_limit store after that LTS; run offline neo4j-admin database migrate --to-format=block <db> on or before the LTS.

Server JVM: 2026.x runs on Java SE 21 or 25; Java 21 support ends with the 2026 LTS — move servers to Java 25 [2026.08 deprecation].

No downgrades supported — take a backup before any server upgrade.


Step 5 — Test After Migration

# Python: run with dev mode to surface all deprecation warnings
python -W error::DeprecationWarning -m pytest tests/

# JS: run tests
npm test

# Java
mvn test

# .NET
dotnet test

# Go
go test ./...

After test run: if any DeprecationWarning or deprecated-API log appears, treat as ERROR — fix before proceeding.

For Cypher: run each migrated query through EXPLAIN first:

# Via Query API v2
curl -X POST https://<host>/db/<database>/query/v2 \
  -u <user>:<password> -H "Content-Type: application/json" \
  -d '{"statement": "EXPLAIN <your query>"}'

Common Migration Errors

ErrorCauseFix
id(n) returns string, int comparison failselementId() returns stringUpdate stored IDs to string; fix WHERE clauses
Cannot merge node using null property valueMERGE key resolved to nullValidate params before MERGE
Neo4j.Driver.Exceptions.AuthenticationExceptionWrong credential config after .NET renameUpdate INeo4jLogger usage; verify config
TypeError: neo4j-driver is deprecatedOld package installedReplace with neo4j>=6.0.0 in requirements
AttributeError: 'Session' has no 'read_transaction'Python 5→6, method removedReplace with execute_read()
RxSession not foundJava 6.x, Reactive API removedMigrate to async or sync session
undefined is not a function (.readTransaction)JS 6.x, method removedReplace with executeRead()
Go: undefined: neo4j.Configv5 import path still presentUpdate all imports to /v6/
PERIODIC COMMIT not supportedCypher 25, clause removedUse CALL (...) IN TRANSACTIONS
Unknown function id()id() removed in Cypher 25Replace with elementId()

References

Load on demand — high discovery rate because explicitly linked:

For any syntax not covered above, fetch: https://neo4j.com/docs/cypher-manual/25/deprecations-additions-removals-compatibility/


Checklist

  • Target Neo4j version confirmed; Cypher dialect selected (Cypher 5 or 25)
  • Dependency files scanned; all driver versions identified
  • Cypher substitution table applied to every query in codebase
  • id(n) → elementId(n) and downstream int→string conversions fixed
  • PERIODIC COMMIT → CALL IN TRANSACTIONS in all batch writes
  • CALL { WITH x ... } → CALL (x) { ... } in all subqueries
  • Package renames done (Python: neo4j-driver → neo4j)
  • Deprecated session methods replaced (read_transaction/readTransaction → execute_read/executeRead)
  • Resource cleanup added where missing (Python: context managers or .close())
  • Bookmark API updated (last_bookmark → last_bookmarks, Bookmark → Bookmarks)
  • Go imports updated from /v5/ to /v6/; neo4j.Config → config.Config
  • Java: Java 21 confirmed; RxSession usages removed
  • .NET: ILogger → INeo4jLogger; Neo4j.Driver.Signed → Neo4j.Driver
  • Tests pass with no DeprecationWarnings
  • EXPLAIN run on all migrated Cypher queries; no errors
Saved skills