# Gen.jl: programmable inference for probabilistic programs in Julia

> Gen.jl is a general-purpose probabilistic programming system embedded in Julia whose distinguishing feature is that inference algorithms themselves are written in the same language as the models. This article covers how the trace-based design works, how to install it, and where the programmable-inference approach costs more than it returns.

**probcomp/Gen.jl** — A general-purpose probabilistic programming system with programmable inference

- Repository: https://github.com/probcomp/Gen.jl
- Website: https://gen.dev
- Stars: 1,851 · Forks: 164
- Language: Julia
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/probcomp-gen-jl

## The problem Gen.jl solves, and who it is aimed at

Most probabilistic programming systems give you a modeling language and a fixed menu of inference algorithms. If your model falls outside what that menu supports, you either reshape the model until it fits or leave the system. Gen.jl takes the opposite position: the README describes it as "a general-purpose probabilistic programming system with programmable inference, embedded in Julia", and the emphasis falls on the second half of that phrase. Inference algorithms are ordinary Julia code that you can write, modify and compose, and the system supplies the machinery underneath them.

The intended user is therefore not someone who wants to call fit and receive a posterior. It is a researcher or engineer who already knows which inference strategy their problem needs, or who is developing a new one, and wants to spend their time on the algorithm rather than on the plumbing of traces, addresses and gradients. The topics attached to the repository (Bayesian, computer vision, robotics, differentiable programming) point at the same audience: people with structured models where off-the-shelf inference is a poor match.

That framing is a real constraint, not a marketing position. The README's feature list is dominated by inference families (Sequential Monte Carlo, variational inference, MCMC, parameter optimization, wake-sleep learning) and by extension points (custom proposals, custom variational families, custom MCMC kernels, custom gradients). Nothing in the list promises that a beginner can describe a model and get an answer without choosing an algorithm.

## Generative functions, traces, and why the trace is the interface

The modeling language is built on generative functions. The documentation describes a domain-specific language, referred to as the DML, for writing and composing probabilistic programs, and the README links to a reference page for it. A model written this way records each random choice it makes at a named address. The record of those choices, together with the values drawn, is the trace, and the trace is what inference algorithms read and write.

This is the design decision that everything else follows from. Because choices are addressed, an inference algorithm can propose a new value for one address while leaving the rest of the trace untouched, and it can do so without knowing what the model means. The README frames the payoff directly: you can write custom proposals, variational families, MCMC kernels or SMC updates "without worrying about the math". The claim is not that the math disappears, but that the system handles the bookkeeping of updating a trace and its probability density when a proposal is accepted.

The second mechanism worth naming is incremental computation. The README refers to "specialized modeling constructs that speed-up inference by supporting incremental computation", with a tutorial on scaling with these constructs. The idea is that when only part of a trace changes, only the affected part of the computation should be recomputed. For models with many addresses, that is the difference between an inference loop that runs and one that does not. It also means the model author carries some responsibility: a model written without regard to which parts of the computation depend on which choices will not benefit.

Bayesian structure learning is handled through involutive MCMC and SMCP3, both of which the README lists as supported. These are the mechanisms for cases where the structure of the model itself, not just its parameters, is uncertain.

## Installing Gen.jl and running a first model

Gen.jl installs through the Julia package manager. From the Julia REPL, press ] to enter Pkg mode and add the package. The README gives this exact command:

```
add Gen
```

To track the development version instead, the README gives an alternative that adds the repository directly:

```
add https://github.com/probcomp/Gen.jl.git
```

After installation the package is loaded like any other Julia dependency. This is the line the README shows for a script or a REPL session:

```julia
using Gen
```

If you want to confirm that the installation is sound before writing any model code, the README documents a local test run through Pkg:

```julia
using Pkg; Pkg.test("Gen")
```

Expect the test suite to take a while and to pull in test-only dependencies; it exercises the package rather than a single example. Once that passes, the natural first step is the modeling reference and the tutorials linked from the README, which cover the DML and the inference methods in turn. The README does not print a complete end-to-end model in the repository root, so the first real program comes from the documentation site at gen.dev rather than from the README itself.

One practical note: the README's installation section does not state a minimum Julia version. Project.toml in the repository root is where that constraint lives, and it is the file to read before installing into an older Julia environment.

## Where the programmable-inference design becomes a burden

The same openness that makes Gen.jl useful makes it expensive. A fixed-inference system hides the algorithm; Gen.jl exposes it, and exposing it means you are responsible for it. Choosing among SMC, variational inference and MCMC is a modeling decision with consequences for correctness and runtime, and the README does not pretend otherwise. If you cannot say why one of those is appropriate for your problem, the feature list will not help you decide.

The second cost is the generative function interface. Custom models, custom distributions and custom gradients are all supported, but they are supported through defined APIs, and the README links to how-to pages for each. Implementing that interface correctly for a new distribution is more work than registering a log-density function in a system that only needs one. The return on that work appears when you want to do something the system did not anticipate.

Third, the incremental computation constructs are opt-in and their benefit is model-dependent. The README presents them as a way to speed up inference, not as a default. A model that ignores them will still run; it may simply be slower than the same model written with them.

Finally, the ecosystem is Julia-shaped. The packages you would reach for to load data, plot results or deploy a service need Julia equivalents, and the README's own contribution guidance points to GitHub discussions and issues rather than to a large third-party plugin market. That is a smaller surface than systems embedded in Python, and it is the trade you accept for the modeling and inference language being the same language.

## How Gen.jl differs from Stan and PyMC

Stan and PyMC both start from a model specification and hand it to an inference engine the user does not write. In Stan's case the model is compiled from its own language and the sampler is chosen from the available options; in PyMC the model is Python and the samplers are library functions. Neither expects the user to author an MCMC kernel.

Gen.jl inverts that relationship. The README's feature list includes custom proposals, custom variational families, custom MCMC kernels and custom SMC updates as first-class capabilities, alongside involutive MCMC and SMCP3 for structure learning. These are not configuration options on an existing sampler; they are places where you supply the algorithm. The comparison is therefore not about which system has better defaults. It is about whether your problem is served by defaults at all. For a hierarchical regression with a few hundred parameters, Stan or PyMC will get you to a posterior with far less code. For a model where the latent structure is itself unknown, or where the proposal distribution must be tailored to the data, Gen.jl is the one that lets you write the part that matters.

The second difference is the host language. Gen.jl is embedded in Julia, and its inference algorithms are Julia. That means the same language covers the model, the inference and any numerical code you need, with no bridge between a modeling DSL and a host runtime. The cost is that the surrounding tooling is Julia's, not Python's.

## Maintenance, releases and what the licence asks of you

The repository is not archived, and the last push was on 2026-06-09. Releases are infrequent: 0.4.8 on 2025-07-12, v0.4.7 on 2024-09-06, and v0.4.6 on 2023-09-20. That cadence matters for planning. If you depend on a documented behaviour, pin the version you tested against rather than tracking master, because the gap between releases is long enough that documentation and code can drift apart between them.

Upgrade cost is mostly the cost of Julia package resolution plus whatever changed in the generative function interface. The README does not document a deprecation policy or a rollback procedure, so the practical approach is to pin in Project.toml and read the release notes before moving.

On licensing, Gen.jl is Apache-2.0 and the LICENSE file sits in the repository root. Apache-2.0 includes an express grant of patent rights and requires that you preserve notices and state changes when you redistribute. That is a permissive licence with fewer conditions than a copyleft one, but the notice and modification-statement requirements are real obligations if you ship a modified copy. Read the LICENSE file itself rather than a summary; nothing here is legal advice.

## Conclusion

Adopt Gen.jl if your model does not fit a fixed inference menu and you are willing to write the inference yourself in Julia; the repository's last push was on 2026-06-09 and release 0.4.8 dates to 2025-07-12, so the code is moving but you should confirm the docs match your installed version before committing. Skip it if you want a one-line fit function, if your team does not write Julia, or if your model is a standard regression that a fixed-inference library already handles. Before adopting, verify that the generative function interface you need is implemented for your custom distributions and gradients, and check the Apache-2.0 LICENSE file for how you intend to redistribute.

## FAQ

### Is Julia still being used?

That question is about the Julia language in general, and nothing in the Gen.jl repository answers it. The repository does show that Gen.jl is a Julia package, that it is not archived, and that its last push was on 2026-06-09.

### How do I install Gen.jl?

From the Julia REPL, press ] to enter Pkg mode and run add Gen. To install the development version instead, the README gives add https://github.com/probcomp/Gen.jl.git.

### What makes Gen.jl different from other probabilistic programming systems?

The README describes it as a general-purpose probabilistic programming system with programmable inference. Inference algorithms are written in Julia, and the feature list includes custom proposals, custom variational families, custom MCMC kernels and custom SMC updates.

### Which inference methods does Gen.jl support?

The README lists Sequential Monte Carlo, variational inference, MCMC and more, plus gradient-based training through parameter optimization and wake-sleep learning, and Bayesian structure learning through involutive MCMC and SMCP3.

## Sources

- [License: Apache-2.0](https://github.com/probcomp/Gen.jl/blob/master/LICENSE)
- [probcomp/Gen.jl on GitHub](https://github.com/probcomp/Gen.jl)
- [Project website](https://gen.dev)
- [README](https://github.com/probcomp/Gen.jl/blob/master/README.md)
- [Releases](https://github.com/probcomp/Gen.jl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/probcomp-gen-jl
