Open-source project
JuliaGraphs/GraphNeuralNetworks.jl avatar
JuliaGraphs/GraphNeuralNetworks.jl

GraphNeuralNetworks.jl: Graph Convolution Layers for Flux and Lux

Graph Neural Networks in Julia

308 stars73 forksJuliaMIT

At a glance

What is it?
The repository ships four packages rather than one, splits the frontend between Flux and Lux users, and hides the message-passing engine in a backend that end users are told not to import directly. That split is the main thing to understand before adding it to a Julia project.
Who is it for?
Adopt it if your model already lives in Julia and you want graph convolutions that compose with Flux or Lux rather than a Python runtime you would have to bridge. Do not adopt it if your team is committed to PyTorch or TensorFlow tooling, or if you need a layer that the repository does not implement, because GNNlib is explicitly not meant for direct use and you would be writing the layer yourself.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 21 days ago.
What is it written in?
Mainly Julia, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

Four packages, two frontends, and one backend you are told not to touch

The repository is not a single library. The README lists four packages: GraphNeuralNetworks.jl for Flux users, GNNLux.jl for Lux users, GNNGraphs.jl for graph data structures and helpers, and GNNlib.jl for the message-passing framework. Only the first two are installed by hand. The README states plainly that there is no need to install GNNGraphs or GNNlib directly, because the frontend packages re-export them. GNNlib carries a stronger warning: it is "not intended for direct use by end-users" even though it is re-exported.

That layout answers a real question for Julia users. Flux and Lux differ in how they handle model parameters, and a graph layer library has to pick a side or duplicate itself. This project duplicates the frontend and shares everything underneath, which is why the same layer set appears in both docs badges at the top of the README. The cost is that a bug report or a question has to name the right package. If you file against GNNLux.jl for something that lives in GNNlib.jl, you are pointing at the wrong repository folder.

The recent releases reflect that split. GraphNeuralNetworks-v0.6.12 shipped on 2026-07-31, while GNNlib-v1.4.0 and GNNlib-v1.3.0 both landed on 2026-07-22. The backend is versioned and released independently of the Flux frontend.

Gather/scatter versus sparse matrix multiplication

The README describes GNNlib.jl as implementing "the message-passing framework based on the gather/scatter mechanism or sparse matrix multiplication." Two execution strategies, one framework. That is the architectural fact worth knowing, because the two paths have different memory and sparsity characteristics. Gather/scatter materializes per-edge messages; sparse matrix multiplication keeps the adjacency in a sparse structure and multiplies. Which one a given layer uses is not stated in the README, so if that choice matters for your graph sizes, you have to read the source or the documentation rather than assume.

Above that sits GNNGraphs.jl, which supplies the graph data structures and helper functions. The README says those structures integrate with Graphs.jl, the general Julia graph package. That integration is the reason this library is usable at all in a Julia pipeline: you can build a graph with the standard tooling and hand it to a convolutional layer without a conversion step that the README mentions.

The layers themselves live in GNNlib.jl as "shared implementations for the layers used by the two frontend packages." So the flow is: a graph structure from GNNGraphs, a layer implementation from GNNlib, and a parameter-handling wrapper from whichever frontend you installed. The README lists custom layer definitions as a supported feature, which is the escape hatch when the built-in set does not cover your case.

Installation is one line, but the line depends on your training stack

The README gives two commands and they are not interchangeable. Flux users run:

pkg> add GraphNeuralNetworks

Lux users run:

pkg> add GNNLux

Both packages are registered in the General registry, so no git URL or development path is involved. The README explicitly says not to install GNNGraphs or GNNlib yourself. If you find yourself adding GNNlib to a Project.toml by hand, something has gone wrong with the frontend dependency, not with your understanding of the setup.

Beyond installation, the README points to an examples folder and a notebooks folder inside GraphNeuralNetworks, and to the documentation site for "a comprehensive introduction." It does not reproduce a training loop, a layer constructor signature, or a config file in the README text itself. That is a deliberate choice to keep the README short, but it means the first useful step after installing is opening the examples directory, not reading further down the page. There are no environment variables or config keys documented in the supplied material, so any claim about configuration would be invented.

What the feature list actually commits to

The shared feature list is short and specific: common graph convolutional layers, computation on batched graphs, custom layer definitions, CUDA and AMDGPU support, integration with Graphs.jl, examples of node-, edge-, and graph-level tasks, and heterogeneous and dynamical graphs and convolutions.

Batched graphs deserve a note. Graph batching is where graph libraries usually get awkward, because padding a set of graphs into one tensor wastes memory and changes the semantics of pooling. The README says batched computation is supported but does not describe the batching representation. If your dataset is a collection of small graphs rather than one large one, that representation is the first thing to check in the documentation.

The heterogeneous and dynamical entries are the most distinctive. Heterogeneous graphs carry multiple node and edge types; dynamical graphs change over time. Many graph learning libraries handle the first and ignore the second. The README lists both as supported, with no caveat about which layer types apply to which. Treat that as a scope statement, not a guarantee that every layer works on every graph kind.

GPU support is stated as CUDA and AMDGPU. No performance numbers, no memory guidance, and no statement about which operations fall back to the CPU.

The backend is the wrong tool when you need to extend it

The clearest limitation is stated by the project itself. GNNlib.jl is "not intended for direct use by end-users" even though the frontends re-export it. If the layer you need is not among the shared implementations, the documented path is custom layer definitions through the frontend, not patching the backend. Whether the frontend re-export gives you enough surface to write a genuinely new message-passing scheme is not something the README answers.

Version skew is the second constraint. GNNlib and GraphNeuralNetworks carry separate version numbers and separate release dates. A project pinning GraphNeuralNetworks-v0.6.12 resolves GNNlib through the dependency graph, and the two do not move together. When you debug a numerical result, the version that matters may be the one you never typed into the package manager.

Third, the frontend split is a real fork in the road. Committing to GraphNeuralNetworks means committing to Flux's parameter model for that part of your code. Switching to Lux later is not a rename; it is a different package with a different frontend, and the README presents them as parallel options rather than a migration path. Pick once, deliberately.

Finally, the README does not state a minimum Julia version, a supported GPU driver range, or a compatibility matrix. Those are the questions that decide whether an install succeeds on a given machine, and the supplied material is silent on all of them.

PyTorch Geometric is the comparison that matters, and the difference is the host language

The README says the project is "largely inspired by PyTorch Geometric, Deep Graph Library, and GeometricFlux.jl." PyTorch Geometric is the obvious alternative and the difference is not the layer catalogue. It is where the code runs. PyTorch Geometric assumes a Python process, PyTorch tensors, and the PyTorch autograd and optimizer stack. GraphNeuralNetworks.jl assumes Julia, Flux or Lux, and the Julia package manager. If your data pipeline, your differential equation solver, or your statistical model is already Julia, the Python option means a language boundary in the middle of training. That boundary is the reason this repository exists.

GeometricFlux.jl is the other reference point, and it is named as an inspiration rather than as a competitor. It targets Flux. This project's answer to the Flux-only constraint was to add a Lux frontend alongside it, which is a different response to the same problem.

Deep Graph Library takes a third position, with its own graph abstraction rather than an integration with an existing graph package. GraphNeuralNetworks.jl instead leans on Graphs.jl for structures. If your graphs already come from Graphs.jl, that integration is the concrete advantage over all three. If they do not, you are adopting Graphs.jl as well.

Maintenance cost and the MIT licence

The repository is not archived and the most recent push in the supplied metadata is 2026-08-26, with GraphNeuralNetworks-v0.6.12 released on 2026-07-31. The version numbering and the separate GNNlib releases suggest active, incremental maintenance rather than a frozen project. There is a published JMLR paper, Lucibello and Rossi, Journal of Machine Learning Research volume 26, number 80, 2025, which gives the project an academic citation path and a reason for the API to stay stable enough to describe in print.

Upgrade cost concentrates in one place: the frontend you chose. Because GNNGraphs and GNNlib are re-exported rather than imported directly, a breaking change in the backend can reach you through a frontend version bump without appearing in your own code. Reading the release notes for the frontend package before upgrading is the practical mitigation, and the release notes are the material you would need to consult.

The licence is MIT. That is permissive and short, and it imposes no copyleft obligation on your own code. It also comes with no warranty, which is standard. Nothing here is legal advice; if your organisation has licence review, MIT is the identifier to put in front of it, and the citation requirement in the README is a request, not a licence term.

Editorial conclusion

Adopt it if your model already lives in Julia and you want graph convolutions that compose with Flux or Lux rather than a Python runtime you would have to bridge. Do not adopt it if your team is committed to PyTorch or TensorFlow tooling, or if you need a layer that the repository does not implement, because GNNlib is explicitly not meant for direct use and you would be writing the layer yourself. Before committing, verify which frontend matches your training stack, confirm that the layers you need appear in the documentation, and check the version numbers of GraphNeuralNetworks and GNNlib in your Manifest, since the two are released on separate schedules.

Official sources

  1. JuliaGraphs/GraphNeuralNetworks.jl on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes