# Turing.jl: Bayesian Inference with Probabilistic Programming in Julia

> Turing.jl is a general-purpose probabilistic programming package for Julia that supports MCMC, variational inference, maximum likelihood, and MAP estimation, with models written using the @model macro. It integrates with Julia's scientific computing ecosystem and has published peer-reviewed papers describing its design.

**TuringLang/Turing.jl** — Bayesian inference with probabilistic programming.

- Repository: https://github.com/TuringLang/Turing.jl
- Website: https://turinglang.org
- Stars: 2,257 · Forks: 245
- Language: Julia
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/turinglang-turing-jl

## What Turing.jl Solves and Who Uses It

Bayesian inference requires specifying a prior over parameters, conditioning a model on observed data, and computing or approximating the posterior distribution. Writing that process by hand in a general-purpose language is tedious and error-prone. Probabilistic programming languages automate it by letting the programmer write the model as code and leaving the inference to the framework.

Turing.jl targets researchers in statistics, machine learning, and scientific computing who need flexible Bayesian models in Julia. The README describes it as a general-purpose package for Bayesian and likelihood-based inference. It is not limited to specific model families: the @model macro can express hierarchical models, time-series models, latent variable models, and custom likelihoods. The package is grant-funded research software, which the README explicitly states, meaning maintenance is driven by research priorities rather than commercial roadmaps.

Two peer-reviewed papers document Turing.jl's design. The first appeared in ACM Transactions on Probabilistic Machine Learning in 2025 (doi 10.1145/3711897); the second, introducing the original design, appeared at AISTATS 2018. The README includes BibTeX entries for both and asks researchers who use Turing.jl in published work to cite them.

## Writing Models with the @model Macro

Models in Turing.jl are written using the @model macro from DynamicPPL.jl. A model function declares priors with the ~ syntax and the likelihood with another ~ statement. The README includes a complete linear regression example:

```julia
@model function linear_regression(x)
    # Priors
    α ~ Normal(0, 1)
    β ~ Normal(0, 1)
    σ ~ truncated(Cauchy(0, 3); lower=0)

    # Likelihood
    μ = α .+ β .* x
    y ~ MvNormal(μ, σ^2 * I)
end
```

The model is conditioned on observed data using the | operator: `linear_regression(x) | (; y = y)`. Sampling then calls the sample function with a sampler and a number of draws:

```julia
chain = sample(rng, posterior, NUTS(), 1000)
```

This produces a chain of 1,000 posterior samples using the No-U-Turn sampler. The syntax is consistent with Julia conventions and does not require a separate DSL or configuration file.

Models can also be written in BUGS syntax via JuliaBUGS.jl or graphically with DoodlePPL. These alternatives are listed in the README but are not part of the Turing.jl package itself.

## Installing Turing.jl

The README gives the installation command for Julia 1.10.8 or later:

```julia
julia> using Pkg; Pkg.add("Turing")
```

Julia itself is installed from the official Julia website (julialang.org/install). No additional configuration is needed beyond an active Julia environment. Turing.jl pulls its dependencies, including DynamicPPL.jl, through Julia's package manager.

The current stable documentation lives at turinglang.org/Turing.jl/stable, and changes are recorded in HISTORY.md in the repository root. The TuringLang website at turinglang.org also hosts tutorials and a newsletter. For technical questions after installation, the README points to the #turing channel on Julia Slack and the turing tag on Julia Discourse as the primary support channels.

## Samplers, AD Backends, and Inference Methods

Turing.jl supports MCMC, variational inference, maximum likelihood estimation, and MAP estimation. MCMC is the primary inference method: the README lists NUTS (No-U-Turn Sampler) as the standard gradient-based choice. Turing exposes a log-density and gradient interface that allows customized inference beyond the built-in samplers.

For gradient-based algorithms, Turing.jl's preferred automatic differentiation backends are ForwardDiff.jl and Mooncake.jl. Other backends, including Enzyme.jl, are available through DifferentiationInterface.jl. The choice of AD backend affects both performance and compatibility with specific model types, though the README does not benchmark these differences.

The README notes that the project interoperates with Julia's scientific computing ecosystem. This means Turing.jl models can use standard Julia array types, distributions from Distributions.jl, and linear algebra from the standard library without adaptation.

## Where Turing.jl Is the Wrong Choice

Turing.jl prioritizes correctness and stability over broad feature coverage. The README states this directly: new features are typically developed through research projects or collaborations, and reproducible reports of incorrect results or unexpected failures in documented functionality guide further work. Teams expecting fast addition of new samplers, new inference backends, or new model types outside the current scope should plan for slower iteration.

The Julia requirement is also a real constraint. Teams whose production stack is Python-only, or who have existing Bayesian workflows in Stan or PyMC, will incur migration cost. Stan, the most common comparison point, is a separate compiled language with its own DSL that targets MCMC for continuous parameter models. PyMC is a Python-native probabilistic programming framework that uses Aesara or PyTensor as its computational backend. Both have larger user communities and more third-party tutorials than Turing.jl, which is a practical factor for teams hiring or onboarding collaborators.

The project scope also excludes certain inference tasks. The README describes it as Bayesian and likelihood-based inference, but does not document causal inference, online learning, or approximate Bayesian computation (ABC) as supported methods. Teams working outside standard posterior sampling should verify that the required inference type is within scope before committing.

## Turing.jl Versus Stan for MCMC

Stan is a probabilistic programming system that compiles user-written Stan programs to C++ and runs NUTS-based MCMC. Its main strength is speed for continuous-parameter models with few discrete parameters: the compiled C++ backend and Stan's own automatic differentiation are highly optimized for that case.

Turing.jl's advantage is flexibility within Julia. Models can mix continuous and discrete parameters, call arbitrary Julia functions as part of the likelihood, and use any differentiable Julia code as a subcomponent. Stan models are restricted to its DSL and cannot easily call external code. For models that require custom samplers, non-standard likelihoods, or integration with Julia-native scientific tools, Turing.jl is more direct. For straightforward hierarchical regression models where Stan has mature templates, Stan may require less model debugging due to its longer track record in that domain.

The related searches for Turing.jl explicitly include "turing jl vs stan" and "turing jl vs pymc," confirming that these comparisons are common questions. The README does not provide benchmark comparisons with either Stan or PyMC; claims about relative speed or accuracy require independent testing. The related searches also include "turing jl samplers" and "turing jl nuts," indicating that sampler availability is a common evaluation criterion.

## Active Maintenance, Releases, and How to Get Support

The repository received its most recent push on 2026-09-27 and is not archived. Three releases appeared in September 2026 alone: v0.47.4 on 2026-09-02, v0.48.0 on 2026-09-04, and v0.49.0 on 2026-09-13, indicating an active release cycle at this time. The project is MIT licensed.

For technical questions, the README points to the #turing channel on Julia Slack and the turing tag on Julia Discourse. Bug reports and feature discussions go through GitHub issues; maintainers can transfer reports filed in the wrong TuringLang repository. Pull requests for non-breaking changes target the main branch; breaking changes target the breaking branch. The project has been cited in published research: an ACM Transactions on Probabilistic Machine Learning paper (doi 10.1145/3711897, 2025) and a 2018 AISTATS paper describe its design, and the README includes BibTeX entries for both.

## Conclusion

Turing.jl is a strong choice for researchers and data scientists who need Bayesian inference in Julia and want a flexible @model macro with multiple sampler backends. The NUTS sampler is available out of the box, and multiple automatic differentiation backends (ForwardDiff.jl, Mooncake.jl, Enzyme.jl through DifferentiationInterface.jl) are supported. The project explicitly prioritizes correctness and stability over broad feature coverage, and new features are typically developed through research projects or grant-funded collaborations rather than community feature requests. Before committing, review the HISTORY.md changelog for breaking changes: the repository maintains a breaking branch for changes that cannot be made backward-compatible, and v0.49.0 was released on 2026-09-13.

## FAQ

### What is Turing.jl?

Turing.jl is a Julia package for Bayesian and likelihood-based inference using probabilistic programming. Models are written with the @model macro, and inference is run with samplers including NUTS for MCMC, or variational inference and MAP methods. It is part of the TuringLang ecosystem and interoperates with Julia's scientific computing libraries.

### How does Turing.jl compare to Stan for Bayesian modeling?

Stan compiles to C++ and runs NUTS on continuous-parameter models with high efficiency, but restricts models to its own DSL. Turing.jl runs inside Julia and allows models to call arbitrary Julia code as part of the likelihood, supporting both continuous and discrete parameters and custom samplers. The tradeoff is flexibility versus Stan's mature tooling for standard hierarchical models.

### What automatic differentiation backends does Turing.jl support?

The README names ForwardDiff.jl and Mooncake.jl as the preferred AD backends for gradient-based algorithms. Enzyme.jl is available through DifferentiationInterface.jl. The choice of backend affects performance and compatibility with specific model types.

## Sources

- [License: MIT](https://github.com/TuringLang/Turing.jl/blob/main/LICENSE)
- [Project website](https://turinglang.org)
- [README](https://github.com/TuringLang/Turing.jl/blob/main/README.md)
- [Releases](https://github.com/TuringLang/Turing.jl/releases)
- [TuringLang/Turing.jl on GitHub](https://github.com/TuringLang/Turing.jl)

---

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