Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

rustnx

NetworkX, but fast. rustnx is a Rust-powered backend for NetworkX. You keep writing normal NetworkX code, and supported algorithms run in Rust instead of Python, often 50–100× faster.

import networkx as nx

nx.config.backend_priority = ["rustnx"]   # or: NETWORKX_BACKEND_PRIORITY=rustnx

G = nx.barabasi_albert_graph(4000, 4, seed=1)
nx.betweenness_centrality(G)              # runs in Rust: 0.4s instead of 41s

Nothing else changes. Anything rustnx doesn't support, such as other functions, multigraphs or callable weights, keeps running in NetworkX, so turning it on never breaks working code.

Native graphs: skip NetworkX entirely

For big graphs, build the graph in Rust directly. There's no conversion step, and it uses a fraction of the memory:

import networkx as nx
import rustnx

rustnx.enable()  # use rustnx where it can; everything else falls back to NetworkX

G = rustnx.DiGraph([("a", "b", 2.5), ("b", "c", 1), ("c", "a", {"weight": 4})])
nx.pagerank(G)                       # runs in Rust
nx.is_tree(G)                        # not in rustnx: converted to NetworkX automatically

G = rustnx.Graph.from_arrays(src, dst, weights)   # NumPy arrays; nodes 0..n-1
1M-edge directed graph networkx.DiGraph rustnx.DiGraph(edges) rustnx.DiGraph.from_arrays
Build time 10.0 s 2.7 s 0.48 s
Memory 323 MiB ~65 MiB ~47 MiB
pagerank, first call 4.1 s 0.04 s 0.04 s
  • The same results as NetworkX. Nodes come in order of first appearance, each node's neighbors in insertion order, and duplicate edges merge as add_edge would. So every algorithm returns what it would on a networkx.Graph built from the same edges.
  • Read-only. It has nodes(), edges(data=True), neighbors, successors, predecessors, degree, has_edge, has_node and len. G.to_networkx() gives the full NetworkX API.
  • Edge attributes must be numeric (or None). Graphs can be pickled.
  • Call rustnx.enable() first. Without it, NetworkX raises NotImplementedError when a rustnx graph reaches a function rustnx doesn't implement, instead of converting it.

rustworkx-compatible API

The same Rust core also serves rustworkx's API:

import rustnx.rx as rx      # instead of: import rustworkx as rx

g = rx.PyDiGraph()
g.extend_from_weighted_edge_list([(0, 1, 2.0), (1, 2, 1.0), (2, 0, 4.0)])
rx.strongly_connected_components(g)
rx.dijkstra_shortest_path_lengths(g, 0, float)
  • It behaves the same, not just the same names. PyGraph and PyDiGraph follow rustworkx's index model. Indices of removed nodes and edges are reused, most recently removed first. Graphs are multigraphs by default, and multigraph=False merges duplicate edges as rustworkx does. Neighbors are visited in petgraph's order, so order-dependent results (strongly_connected_components, topological_sort) match rustworkx exactly. Exceptions use rustworkx's names (NullGraph, DAGHasCycle, NoEdgeBetweenNodes, FailedToConverge and so on).
  • It's tested against the real rustworkx. tests/test_rx_api.py applies random sequences of adds and removals to both libraries and compares every query and algorithm.
  • Supported: the core graph-building, editing and query methods, plus betweenness_centrality, closeness_centrality, pagerank, dijkstra_shortest_path_lengths, all_pairs_dijkstra_path_lengths, the connected, strongly and weakly connected component functions, topological_sort, is_directed_acyclic_graph and networkx_converter. Not yet: subgraphs, compose, contraction, matrix and file I/O, and check_cycle=True.
  • Speed: the algorithms are as fast as rustworkx's or faster (betweenness 1.8×, closeness 23×, strong components 2.5×). Building graphs is slower: the graph is stored in Python, so adding 500k edges takes 0.8 s, against rustworkx's 0.04 s.

Supported algorithms

Function Notes
betweenness_centrality Unweighted and weighted, normalized, endpoints, and k sampling (picks the same nodes as NetworkX for a given seed). Parallel.
edge_betweenness_centrality Unweighted and weighted, normalized, and k sampling (same nodes as NetworkX for a given seed). Parallel. Rescaled by the installed NetworkX's own code.
closeness_centrality Unweighted and distance=, wf_improved, single node u=. Parallel. Results are bit-for-bit identical to NetworkX.
single_source_shortest_path_length Same nodes and same dict order as NetworkX, with cutoff.
single_source_dijkstra_path_length Same order as NetworkX, with cutoff. Integer weights give integer distances. Raises the same error on negative cycles.
connected_components, number_connected_components, is_connected Components come out in the same order as NetworkX.
pagerank All options: alpha, personalization, nstart, dangling, weight, tol, max_iter. Raises PowerIterationFailedConvergence like NetworkX.
strongly_connected_components, number_strongly_connected_components, is_strongly_connected Same components in the same order as NetworkX.
weakly_connected_components, number_weakly_connected_components, is_weakly_connected Same components in the same order as NetworkX.
topological_sort, topological_generations, is_directed_acyclic_graph Same order as NetworkX. If the graph changes mid-iteration, it raises the same errors as NetworkX.
eccentricity, diameter, radius, center, periphery Unweighted: bit-parallel BFS. Weighted: parallel Dijkstra. Same errors as NetworkX (disconnected graphs, negative weights). usebounds=True, e=/sp= and trees in center run in NetworkX.
average_shortest_path_length, wiener_index As above; weighted sums are added in NetworkX's order, so float results match exactly.
all_pairs_shortest_path_length, all_pairs_dijkstra_path_length Parallel, in batches; same order as NetworkX.
shortest_path, shortest_path_length, single_source_shortest_path, single_target_shortest_path, bidirectional_shortest_path, has_path The same paths as NetworkX, ties included, in the same dict order. shortest_path with no source and no target runs in NetworkX.
dijkstra_path, dijkstra_path_length, single_source_dijkstra, single_source_dijkstra_path The same paths as NetworkX, ties included. The paths dict follows the installed NetworkX's order, which changed in 3.6. Weighted shortest_path between two nodes uses bidirectional_dijkstra, which runs in NetworkX.
all_pairs_shortest_path, all_pairs_dijkstra_path, all_pairs_dijkstra Parallel, in batches.
descendants, ancestors Same sets and errors as NetworkX.
triangles, clustering, average_clustering, transitivity Unweighted, directed and undirected, with nodes=. Parallel. Results are bit-for-bit identical to NetworkX. Weighted clustering runs in NetworkX.

Benchmarks

python benchmarks/bench.py on a 4-core machine (NetworkX 3.6.1):

Function Graph NetworkX rustnx Speedup
betweenness_centrality 4,000 nodes / 16k edges 40.9 s 0.38 s 107×
betweenness_centrality (weighted) 4,000 / 16k 115.3 s 1.24 s 93×
edge_betweenness_centrality 4,000 / 16k 42.3 s 0.46 s 93×
edge_betweenness_centrality (weighted) 4,000 / 16k 106.8 s 1.33 s 80×
closeness_centrality 4,000 / 16k 5.45 s 0.0097 s 562×
single_source_dijkstra_path_length 160,000 / 319k 0.38 s 0.063 s 6×
single_source_shortest_path_length 160,000 / 319k 0.11 s 0.020 s 5×
connected_components 200,000 / 300k 0.23 s 0.040 s 6×
pagerank 200,000 / 1M (directed) 5.76 s 0.024 s 243×
pagerank (weighted) 200,000 / 1M (directed) 3.81 s 0.024 s 161×
strongly_connected_components 200,000 / 1M (directed) 1.96 s 0.052 s 38×
topological_sort 200,000 / 499k (DAG) 0.40 s 0.023 s 17×
weakly_connected_components 200,000 / 1M (directed) 0.39 s 0.036 s 11×
diameter 5,000 / 15k 11.2 s 0.014 s 807×
average_shortest_path_length 5,000 / 15k 10.8 s 0.014 s 783×
wiener_index 5,000 / 15k 10.0 s 0.012 s 829×
eccentricity (weighted) 5,000 / 15k 57.0 s 1.41 s 40×
all_pairs_dijkstra_path_length 5,000 / 15k 60.2 s 4.90 s 12×
all_pairs_shortest_path_length 5,000 / 15k 9.6 s 2.56 s 4× (building 25M Python dict entries dominates)
dijkstra_path (50 pairs) 200,000 / 1M 117 s 3.3 s 35×
single_source_dijkstra_path 200,000 / 1M 4.56 s 0.83 s 5.5×
single_source_shortest_path 200,000 / 1M 1.10 s 0.57 s 1.9× (building the path lists dominates)
clustering 100,000 / 500k (Barabási–Albert) 5.09 s 0.092 s 55×
transitivity 100,000 / 500k (Barabási–Albert) 5.12 s 0.088 s 58×
triangles 100,000 / 500k (Barabási–Albert) 1.52 s 0.091 s 17×

The rustnx column is a repeat call. The first call on a graph also converts it to rustnx's format (about 0.15–0.25 s for a 1M-edge directed graph), and NetworkX caches that conversion on the graph. For the heavy algorithms conversion is negligible. For the linear-time ones, the first call is still faster than NetworkX, but by less.

Compared with other Rust backends

python benchmarks/compare.py runs the same calls through each installed backend and checks every result against NetworkX (same machine, NetworkX 3.6.1, rustworkx 0.18.1 via nx-rustworkx 0.2.1, franken-networkx 0.2.1). Times are repeat calls; the first call also includes conversion.

Function (graph) rustnx nx-rustworkx FrankenNetworkX
betweenness_centrality (2k nodes) 0.099 s 0.161 s 8.23 s (no speedup)
closeness_centrality (2k nodes) 0.0030 s 0.104 s 0.0031 s
pagerank (100k nodes, 500k edges) 0.014 s 0.212 s, differs from NetworkX 0.063 s
single_source_dijkstra_path_length (90k nodes) 0.025 s 0.094 s 0.123 s
connected_components (200k nodes) 0.040 s 0.072 s 0.036 s
strongly_connected_components (100k nodes) 0.020 s 0.041 s, different order 0.054 s
topological_sort (100k nodes) 0.010 s 0.019 s, different order 0.040 s

rustnx is also the fastest on first calls for all seven, because its conversion is about 5–20× quicker than nx-rustworkx's and 25–55× quicker than FrankenNetworkX's. It matches NetworkX's output, including order, for all seven.

On small graphs (under 500 nodes), the linear-time functions stay in NetworkX automatically, because the dispatch overhead outweighs the work. The centrality functions are faster in Rust at every size.

Correctness

Results must match NetworkX, or the speed is worthless. Two test layers check that:

  1. tests/: about 1,400 randomized comparisons against NetworkX, run on directed and undirected graphs, int, float and missing weights, self-loops, and shuffled or non-integer node labels. They check values, dict ordering and error messages.

  2. NetworkX's own test suite, with every supported call routed through rustnx:

    NETWORKX_TEST_BACKEND=rustnx NETWORKX_FALLBACK_TO_NX=True \
        pytest --pyargs networkx
    

    Result: 0 failures on NetworkX 3.4.2, 3.5 and 3.7 (9,066 tests passed on 3.7), with over 300,000 calls handled by rustnx. CI runs both layers on NetworkX 3.4, 3.5 and the latest release.

rustnx checks every call against the installed NetworkX's own signature. If a newer NetworkX adds a parameter, rustnx ignores it while it is left at its default. If the caller actually uses it, rustnx hands the call back to NetworkX.

Betweenness sums per-source contributions in parallel. It matches NetworkX to about 1e-15 relative error rather than bit-for-bit, and it gives the same result on any machine regardless of thread count.

How it works

nx.betweenness_centrality(G)
        │  NetworkX dispatch (backend_priority = ["rustnx"])
        ▼
rustnx.interface      convert G once: nodes → 0..n-1, adjacency → CSR arrays
        │             (NetworkX caches this on G for later calls)
        ▼
rustnx._core (Rust)   algorithm on flat arrays, GIL released, parallel via rayon
        │
        ▼
dict keyed by your original nodes, in NetworkX's order

Neighbor order in the Rust arrays follows NetworkX's adjacency dicts exactly. That's why traversal order, tie-breaking and result ordering all match.

Releasing

The Wheels workflow builds packages for Linux (x86-64, ARM), macOS (Intel, Apple Silicon) and Windows, plus a source package. It then installs each wheel on that platform and runs the test suite against it. The workflow runs on every pull request.

To publish a release:

  1. One-time setup: on PyPI, add a trusted publisher for fabuseless/rustnx, workflow wheels.yml, environment pypi. Then create an environment named pypi in the repo's GitHub settings. No API token is needed.
  2. Set the version in pyproject.toml and Cargo.toml, and move the changelog's Unreleased entries under the new version.
  3. Push a tag such as v0.1.0a1. If every build and test passes, the workflow uploads the packages to PyPI.

Development

uv venv && source .venv/bin/activate
uv pip install maturin networkx pytest numpy scipy
maturin develop --release
pytest                                  # rustnx comparison tests
python benchmarks/bench.py --quick      # benchmarks

Layout:

  • src/: Rust core. graph.rs handles conversion and CSR storage; algorithms/ holds the traversals and centrality.
  • python/rustnx/: the NetworkX backend. interface.py is the entry point; algorithms.py holds the NetworkX-compatible wrappers.
  • tests/: comparisons against NetworkX.
  • benchmarks/: speed comparisons.

Roadmap

  • More algorithms: bidirectional_dijkstra, weighted clustering.
  • Multigraph support.

License

BSD 3-Clause, the same license as NetworkX. See LICENSE. Release notes are in CHANGELOG.md.

Metadata

Release files for rustnx 0.1.0a2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rustnx 0.1.0a2
File Size Uploaded
rustnx-0.1.0a2.tar.gz 77.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for rustnx 0.1.0a2
File
rustnx-0.1.0a2-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
rustnx-0.1.0a2-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
rustnx-0.1.0a2-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.3 MB

Release files / rustnx-0.1.0a2.tar.gz

Download URL rustnx-0.1.0a2.tar.gz
Size 77.7 kB
Tags Source
SHA-256 checksum
How to use checksums
85fff661617318181a8589216b9c418ca2580d8a3e0e6606b729fe472984b5d9
BLAKE2b-256 checksum
How to use checksums
9197ef12130b90e12ee0524d934aa9d7c443c233c3c6c4d8edac9cbe37b91bdb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / rustnx-0.1.0a2-cp310-abi3-win_amd64.whl

Download URL rustnx-0.1.0a2-cp310-abi3-win_amd64.whl
Size 364.6 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e34a9f50bcc052e48f4b0e4eb5d1b85093cf5244ef3e895065d1355ad49ec25d
BLAKE2b-256 checksum
How to use checksums
ea2a8c0d9ebff9c1404e1c9548f489d7737fd1bce38e499ca8764cbb1167a566
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 482.2 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
446deed25f9ec28847b8cf7a7fe3f2e2afaa039ef12685661d34a268f2bd4f99
BLAKE2b-256 checksum
How to use checksums
c628a51c6d4e78b5cd790007c3785780ff2a9c35c5fddaa7c9f9e97b850a690b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL rustnx-0.1.0a2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 468.9 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
c49187033ca77fe0b7eb223583e385d84edc0ad0e0a036a6a7b3600bf3ca39e1
BLAKE2b-256 checksum
How to use checksums
18e8f0fc0b0a366ff95c0d143ed1200103da5a6063066bd51bf65918ce69d508
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / rustnx-0.1.0a2-cp310-abi3-macosx_11_0_arm64.whl

Download URL rustnx-0.1.0a2-cp310-abi3-macosx_11_0_arm64.whl
Size 439.1 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a95caa8eda2c930835410f67a1fcd8432d233b6cdc850e8cae9c2f7ee79208f8
BLAKE2b-256 checksum
How to use checksums
a9ffd785ca6fcc881636c539fb49bf1b8d949cc1b391579be056d40a671a5506
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / rustnx-0.1.0a2-cp310-abi3-macosx_10_12_x86_64.whl

Download URL rustnx-0.1.0a2-cp310-abi3-macosx_10_12_x86_64.whl
Size 451.4 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bcfc30fc7488ece2d14cfc8838e041d528e03215d7f0851b141595de401c6c97
BLAKE2b-256 checksum
How to use checksums
836b23d1bf110500bb2dbd3b93127ddca75ce5935b1f745d30f5afae9d402533
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0a2 This release

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page