Library / SDK
FluxML/Flux.jl avatar
FluxML/Flux.jl

Flux.jl: a pure-Julia machine learning library where any parameterised function is a model

Relax! Flux is the ML library that doesn't make you tensor

4,750 stars624 forksJuliaNOASSERTION

At a glance

What is it?
Flux.jl builds neural networks out of ordinary Julia functions and Julia's own autodiff and GPU support, with no Python layer underneath. It is a good fit if you already write Julia and a poor fit if you need a large catalogue of pretrained architectures.
Who is it for?
Adopt Flux.jl if your work already lives in Julia and you want models expressed as ordinary functions trained with Flux.setup and Flux.train!. Do not adopt it if you need a wide library of pretrained architectures or a Python-compatible ecosystem, because the README points to the model zoo rather than shipping one.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 4 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 27, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Flux.jl solves for Julia programmers

Flux.jl exists so that machine learning in Julia does not require leaving Julia. The README describes it as a 100% pure-Julia stack that provides lightweight abstractions on top of Julia's native GPU and AD support. That sentence is the whole pitch: the automatic differentiation and the GPU array handling come from the language ecosystem, and Flux supplies the layer vocabulary and the training loop on top.

The audience follows from that. If your data pipeline, your solver or your simulation is already written in Julia, Flux removes the process boundary between that code and the model. There is no Python runtime to marshal tensors across, and no second package manager. The cost is that you inherit Julia's package ecosystem, its compile times and its version constraints rather than PyTorch's.

The README frames the design goal as making the easy things easy while remaining fully hackable. That is not decoration. The library deliberately keeps its abstractions thin, which means a user who wants to replace a gradient rule or a layer can do so without fighting a framework, and a user who wants a ready-made ResNet has to look elsewhere.

Any parameterised function is a Flux model

The mechanism the README demonstrates is that a model is a callable, not an object from a fixed class hierarchy. In Flux 0.15 and later, almost any parameterised function in Julia is a valid Flux model, including a closure over three arrays. The example in the README builds a model as a closure over w, b and v, computes sum(v .* tanh.(w*x .+ b)), and then trains it with the same code path used for built-in layers.

Training is split into two steps. Flux.setup(Adam(), model) walks the model and produces an optimiser state that mirrors its parameter structure. Flux.train! then takes a loss function of the form (m, x, y) -> ..., the model, the data and that state, and performs the updates. Because the state is built from the model rather than from a global registry, a closure and a Chain are handled by the same machinery.

The README also shows the equivalent built-in form as Chain(vcat, Dense(1 => 23, tanh), Dense(23 => 1, bias=false), only). Both forms are valid, and the comment in the example presents them as interchangeable. That equivalence is the design claim worth testing against your own code: if you have a function with trainable arrays inside it, you may not need to rewrite it as a layer graph at all.

Installing Flux.jl and training a first model

The README states that Flux works best with Julia 1.10 or later, so install Julia first and then add the package from the Julia package manager. The repository does not document a separate installer, a container image or a system package; the Julia registry is the distribution channel.

Start a Julia session and add Flux:

julia
using Pkg
Pkg.add("Flux")

After the resolver finishes, the package is available to any script in that environment. A minimal fitting run follows the shape given in the README: build data, define a callable model, set up an optimiser state, and loop over epochs.

julia
using Flux
data = [(x, 2x - x^3) for x in -2:0.1f0:2]
model = let
  w, b, v = (randn(Float32, 23) for _ in 1:3)
  x -> sum(v .* tanh.(w*x .+ b))
end
opt_state = Flux.setup(Adam(), model)
for epoch in 1:100
  Flux.train!((m, x, y) -> (m(x) - y)^2, model, data, opt_state)
end

What you should see is a model whose predictions approach the cubic 2x - x^3 over the sampled interval. The README plots the truth curve and the learned curve with Plots to show the fit. If you prefer the layer form, the same example can be written as Chain(vcat, Dense(1 => 23, tanh), Dense(23 => 1, bias=false), only), and the README presents the two as equivalent.

Where Flux.jl is the wrong tool

Flux.jl is not a model distribution. The README points to the model zoo repository for examples rather than shipping a catalogue of pretrained architectures inside the package. If your task is to fine-tune an existing checkpoint, or to reproduce a published architecture that someone else has already implemented in another framework, you will spend your first days porting rather than training. That is a structural consequence of the thin-abstraction design, not an oversight.

There is also a version boundary in the README itself. The statement that almost any parameterised function is a valid Flux model is attributed to Flux 0.15. Code and tutorials written for earlier versions may use a different training API, so a search result from a few years ago is not necessarily applicable to the version you install. The README does not document a migration path from older training idioms.

Finally, the repository is licensed under terms that GitHub reports as NOASSERTION. The README does not summarise them. If the licence terms matter to your organisation, read LICENSE.md directly rather than assuming a permissive default, and take your own advice on the legal question.

Flux.jl compared with Lux.jl and with PyTorch

The two comparisons people search for are Flux.jl against Lux.jl and Flux.jl against PyTorch, and they are different kinds of question.

Lux.jl is the closest comparison because it is also Julia. The difference in approach is where the parameters live. Flux keeps them inside the model object or closure and lets Flux.setup discover them, which is why a closure over three arrays works. A design that separates the model definition from an explicit parameter container gives you a pure, stateless function and passes parameters in as an argument. That separation makes some things easier to reason about and makes the simple case more verbose. The README's closure example is the clearest illustration of what Flux trades away for that convenience.

PyTorch is a different question, because it is a different language. Flux has no Python interop story in the README, and it inherits Julia's compile-time behaviour, its package resolution and its smaller pool of third-party model code. What you get in exchange is that your model and your surrounding Julia code are the same program, with no serialisation boundary between them.

Maintenance, releases and the cost of upgrading

The repository is not archived, and the last push was on 2026-08-16. The most recent release listed is v0.16.11 on 2026-08-06, preceded by v0.16.10 on 2026-04-17 and v0.16.9 on 2026-02-01. That cadence, roughly one release every two to three months across the listed entries, is the practical upgrade cost: you should expect to move patch versions periodically and to read NEWS.md when you do.

The README's own version note is the warning worth carrying forward. The claim that almost any parameterised function is a valid model is tied to Flux 0.15, which means the training API has moved within living memory of the current release. Pin your Flux version in your project environment, and read NEWS.md before bumping it rather than after your training run breaks.

On licensing, the repository reports NOASSERTION and the README does not restate the terms. That is a gap you should close by reading LICENSE.md yourself.

Editorial conclusion

Adopt Flux.jl if your work already lives in Julia and you want models expressed as ordinary functions trained with Flux.setup and Flux.train!. Do not adopt it if you need a wide library of pretrained architectures or a Python-compatible ecosystem, because the README points to the model zoo rather than shipping one. Before committing, check the Project.toml compat entries against your installed Julia version, confirm the version you get from the registry is current, and read the licence file to establish the terms for yourself.

Frequently asked questions

Is Flux.jl free or paid?

The repository is a public open source project and the README does not describe any paid tier or commercial edition. The licence is reported as NOASSERTION, so read LICENSE.md for the actual terms.

Is Julia really as fast as C?

The README does not make any performance claim about Julia or about Flux, so this cannot be answered from the project's own documentation. It describes Flux as a pure-Julia stack built on Julia's native GPU and AD support, and nothing more specific.

Is Flux AI better than DALL-E?

Flux.jl is a machine learning library for building and training models in Julia, not an image generation product, so it is not comparable to DALL-E. The README contains no image generation example.

Does NASA use Julia?

The README says nothing about NASA or about any organisation using Julia or Flux. The only usage guidance it gives is to cite the project's work if you use Flux in your research.

Official sources

  1. FluxML/Flux.jl on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fluxml-flux-jl.svg)](https://hysenlabs.com/projects/fluxml-flux-jl)
Community notes

Community notes