Gen.jl: Programmable Inference in Julia, and What That Costs You
A general-purpose probabilistic programming system with programmable inference
At a glance
- What is it?
- Gen.jl is an MIT Probabilistic Computing Project system that lets you write your own inference algorithms instead of picking from a fixed menu. It is a research-grade tool with a specific audience, a specific set of trade-offs, and a Julia dependency.
- Who is it for?
- Adopt Gen.jl if you are a researcher or graduate student who needs to write a custom MCMC kernel, proposal distribution, or SMC update and can afford to work in Julia.
- Can I use it commercially?
- Yes. Apache-2.0 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 99 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
The problem Gen.jl actually targets: inference you cannot express in a fixed library
Most probabilistic programming tools ship a fixed set of inference algorithms. You write a model, pick NUTS or a mean-field variational family, and accept whatever the library gives you. That works until your model has discrete structure, a non-standard proposal distribution, or a likelihood that only makes sense under a bespoke particle filter. At that point you either abandon the tool or write inference by hand.
Gen.jl takes the second path and makes it the design centre. The README describes inference algorithms as programmable: you can write custom proposals, variational families, MCMC kernels, and SMC updates without implementing the underlying math yourself. The stated audience is people doing Bayesian structure learning, computer vision, robotics, and differentiable programming, judged by the repository topics and the feature list. That is a research audience, not an application-development audience.
Traces, generative functions, and why the inference is separable from the model
The mechanism visible in the material is a separation between the model and the inference procedure. Models are written in what the README calls an expressive modeling language for writing and composing probabilistic programs. Inference algorithms operate on the resulting execution traces through a defined interface, which is why the same model can be handed to sequential Monte Carlo, variational inference, or MCMC without rewriting it.
The payoff is in the extension points. The README lists well-defined APIs for custom generative models, custom distributions, and custom gradients, plus specialized modeling constructs that support incremental computation. Incremental computation is the load-bearing idea: when an MCMC kernel changes one random choice, the system can avoid recomputing the whole trace. That is what makes a general-purpose system usable on models where a naive re-execution would be too slow.
Gen.jl also exposes two less common algorithms by name: involutive MCMC for Bayesian structure learning, and SMCP3 for advanced particle filtering. Those are the features that distinguish it from a generic PPL, and they are also the features with the smallest user base and the least surrounding material.
Installation and the first commands you actually type
The install path is standard Julia. From the REPL, press ] to enter Pkg REPL mode and run:
add Gen
For the development version the README gives:
add https://github.com/probcomp/Gen.jl.git
Then, in the REPL or at the top of a script:
using Gen
To check the installation locally, the README suggests:
using Pkg; Pkg.test("Gen")
That is the entire quickstart in the supplied material. There is no configuration file, no environment variable, and no service to start. The configuration surface is Julia's own package environment, which means version resolution happens through Pkg and the package's compat bounds. If you are coming from a Python PPL, the absence of a config key list is not an omission; there is nothing to configure at the system level.
Where Gen.jl is the wrong tool
The honest limitation is documentation shape. The README points outward to gen.dev and to stable and dev documentation sites rather than carrying a self-contained guide. Several of the most interesting features, including custom proposal tutorials and the scaling-with-SML tutorial, live at URLs under those sites. If a page exists only under docs/dev and not docs/stable, you are reading against unreleased behaviour.
The release cadence reinforces this. The three most recent releases listed are 0.4.8 in July 2025, v0.4.7 in September 2024, and v0.4.6 in September 2023. That is roughly one release per year. A project on that cadence is not going to absorb a breaking change in a dependency quickly, and pre-1.0 versioning means minor bumps can carry breaking changes by convention.
The second limitation is the cost of the abstraction. Programmable inference is only valuable if you intend to program inference. If your model fits a standard algorithm, the trace interface and generative-function API are overhead you pay without return. A user who wants to fit a hierarchical regression and get posterior summaries should use something with a single obvious entry point.
How it differs from Stan and Turing.jl
Stan is the clearest contrast. Stan compiles a declarative model block and runs Hamiltonian Monte Carlo with a fixed sampler. You do not write inference; you write a log-density and let the tool handle the rest. Gen.jl inverts that: the model is Julia code, and the inference is something you can author. If your problem is well served by HMC on a differentiable density, Stan's constraint is a feature, because it removes decisions you do not need to make.
Turing.jl is the closer comparison, since both are Julia and both target Bayesian inference. The difference stated in Gen.jl's own material is the emphasis on programmable inference and on specialized modeling constructs for incremental computation. Turing.jl's model is a more conventional PPL surface. Choosing between them comes down to whether you need to write a custom kernel or proposal. If you do, Gen.jl's APIs for custom generative models, distributions, and gradients are the reason to be there. If you do not, the extra machinery is a cost.
Maintenance, licensing, and the cost of staying current
Gen.jl is Apache-2.0 licensed. That is a permissive licence with an explicit patent grant, which matters if you are embedding the library in a commercial product. This is not legal advice; read the LICENSE file and your own counsel's guidance before relying on it.
The maintenance picture is a research project at the MIT Probabilistic Computing Project, with a contact address of gen-contact@mit.edu and citation requested via the 2019 PLDI paper. That framing tells you what to expect: the project is sustained by academic work, not by a company with a support contract. Your upgrade cost is therefore mostly your own time. When a new release lands, you re-run your model suite against it, and because the version is 0.4.x you should read the release notes rather than assume compatibility.
The repository is not archived and was last pushed in June 2026, so the project is alive. Alive is not the same as fast-moving, and the release history above is the evidence for that distinction.
Who should commit to Gen.jl
The fit is narrow and clear. You are a researcher or advanced practitioner working in Julia, your model has structure that a fixed sampler cannot express, and you are willing to learn the trace and generative-function APIs. Bayesian structure learning via involutive MCMC and SMCP3 particle filtering are the two capabilities the README names that are hardest to find elsewhere, and they are the strongest reason to accept the learning curve.
The misfit is equally clear. If you need a supported inference backend with a stable book-length manual, a predictable release train, and no expectation that you will write inference code, Gen.jl asks more of you than it returns. The material does not include benchmarks, user counts, or performance numbers, and none should be inferred from it. The decision rests on whether programmable inference is a requirement in your work or a feature you would never exercise.
Editorial conclusion
Adopt Gen.jl if you are a researcher or graduate student who needs to write a custom MCMC kernel, proposal distribution, or SMC update and can afford to work in Julia. Do not adopt it if you want a batteries-included inference backend for a production model: the documentation is hosted at gen.dev and probcomp.github.io rather than in a single stable book, the release cadence is roughly annual, and the programming model expects you to understand traces and generative functions before you get useful output. Verify first that your Julia version satisfies the package's compat bounds, that the specific algorithm you need (say, involutive MCMC for structure learning) has a stable-docs page rather than only a dev-docs page, and that you can run using Pkg; Pkg.test("Gen") cleanly on your machine before committing a project to it.
Community notes