Yao.jl: A Julia Framework Where Quantum Circuits Are Just Composable Functions
Extensible, Efficient Quantum Algorithm Design for Humans.
At a glance
- What is it?
- Yao.jl builds quantum circuits out of Julia functions instead of a fixed gate DSL, and the README's own three-line QFT is the clearest statement of what that buys you. It is a research and teaching tool for people already comfortable in Julia, not a hardware submission stack.
- Who is it for?
- Adopt Yao.jl if you write quantum algorithms or teach them and you are already working in Julia; skip it if you need a vendor SDK that targets specific hardware or a language-agnostic circuit format.
- 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 7 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 Yao.jl Solves: Circuits as First-Class Julia Values
Most quantum SDKs hand you a fixed instruction set and a circuit object you fill in. Yao.jl takes the opposite route. The README describes the project as an open source framework aimed at empowering quantum information research with software tools, built around three goals: quantum algorithm design, what it calls quantum software 2.0, and quantum computation education. The second goal is the telling one. Software 2.0, in the linked framing, means programs that are learned or composed rather than hand-written line by line, and that shapes the API.
The audience follows from that. This is for a researcher who wants to define a new gate, a new noise model, or a new variational ansatz as ordinary Julia code and then compose it with everything else. It is for a lecturer who wants students to read a QFT definition and see the recursion rather than a table of gate indices. It is not aimed at someone whose end goal is transpiling a circuit for a specific superconducting device. Nothing in the README mentions hardware backends, job submission, or provider credentials.
Blocks, Chains and Controls: How a Circuit Is Actually Built
The mechanism is visible in the README's QFT example, which is worth reading closely because it encodes the whole design:
A(i, j) = control(i, j=>shift(2π/(1<<(i-j+1)))) B(n, k) = chain(n, j==k ? put(k=>H) : A(j, k) for j in k:n) qft(n) = chain(B(n, k) for k in 1:n)
Three primitives carry the weight. put places a gate on a specific wire. control turns a gate into a controlled version, with the control and target positions given as arguments. chain composes a sequence of sub-blocks into a larger block over n wires. The README calls these Quantum Blocks and links to a dedicated documentation page for them.
What matters is that A, B and qft are plain Julia functions. The generator expressions inside chain are ordinary Julia syntax, the ternary in B is ordinary Julia syntax, and the shift amount 2π/(1<<(i-j+1)) is computed by Julia's own arithmetic. There is no circuit-builder object accumulating state, and no separate compile step described in the README. A circuit is a value you can pass around, nest inside another chain, or return from a function. That is the extensibility claim made concrete: adding a new construct means writing a function, not patching a gate registry.
Installing Yao.jl and the Two Documentation Tracks
Installation goes through Julia's package mode. The README instructs you to open the Julia REPL, press the ] key to enter package mode, and then run pkg> add Yao for the stable release or pkg> add Yao#master for the current master branch. That is the entire install procedure given. If it fails, the README points you at the GitHub issue tracker.
Two optional paths are named rather than bundled. CUDA support lives in a separate package, CuYao.jl, and tensor-network-based simulation lives in YaoToEinsum.jl. Neither is pulled in by the base install, so a GPU or tensor-network workflow means adding a second dependency and reading its documentation separately.
The documentation is split across two published builds, one labelled STABLE for the most recently tagged version and one labelled LATEST for the in-development version. A tutorial site sits at yaoquantum.org/tutorials, and worked algorithms are collected in a companion repository, QuAlgorithmZoo.jl. The practical consequence of the split is that a snippet you copy from the tutorial may not match the tag you installed. Pin the version first, then read the matching docs build.
The Beta Warning and the Version Numbering Problem
The README states plainly: we are in an early-release beta, expect some adventures and rough edges. That sentence is doing real work, and it is the single most important thing to internalise before adopting Yao.jl for anything long-lived.
The repository metadata sharpens the point. The recent releases list shows v0.9.3 and v0.2.1 both tagged on 2026-03-01, roughly an hour apart, with v0.9.2 preceding them in July 2025. Two version lines being tagged on the same day is not a normal release cadence, and nothing in the supplied material explains what the 0.2.x line is. It could be a backport branch, a subpackage, or a historical tag being re-cut. I cannot confirm which from the README alone, and anyone depending on Yao.jl should resolve that question before pinning a version in a manifest.
The licence field adds a second ambiguity. The repository metadata reports the licence as NOASSERTION, while the README states that Yao is released under the Apache 2 license. Those two statements are not the same, and the discrepancy usually means the licence file does not match a standard template that automated tooling recognises. For a permissive-licence dependency this is normally a formality, but it is the kind of formality that a legal or procurement review will flag. Check the actual LICENSE file in the repository rather than trusting either the metadata field or the README sentence.
Where Yao.jl Is the Wrong Tool
Yao.jl is a simulator and a circuit-construction library. The README names CuYao.jl for CUDA and YaoToEinsum.jl for tensor networks, which tells you that the base package's default execution path is state-vector simulation on the CPU. Nothing in the material describes a connection to physical quantum hardware, a transpiler targeting a specific device topology, or a job queue. If your requirement is running circuits on a real machine, this is not the layer that does it, and you would be assembling that path yourself.
The second mismatch is language. Every example, every documentation link, and the entire extension model are Julia. If your team writes Python, the cost of adoption is not learning the block API, which is small, but running a second language runtime alongside the rest of your stack and maintaining the boundary between them. The README offers a Julia Slack channel and a Julia discourse forum for support, which is consistent with a project whose community lives inside one ecosystem.
The third is stability. A project that describes itself as an early-release beta with rough edges is a poor foundation for a production service with an uptime expectation. It is a good foundation for a paper, a thesis, or a course.
Qiskit and Cirq: Different Answers to the Same Question
The obvious comparison is with Qiskit or Cirq, and the difference is not feature count. It is where the abstraction boundary sits.
Qiskit and Cirq both centre on a circuit object with a defined instruction set, plus a transpiler that rewrites your circuit to satisfy a target device's connectivity and native gates. That transpiler is the product. It exists because the destination is hardware, and hardware has constraints the user should not have to think about. The gate set is closed by design, and extending it means going through the provider's extension points.
Yao.jl inverts this. There is no transpiler in the README, no device model, and no closed gate set. A gate is a Julia value, composition is function composition, and the README's own framing of the project is algorithm design and education rather than execution. The cost of that inversion is exactly what the other tools provide: you do not get a path to hardware, and you do not get a device-aware optimiser. The benefit is that a new ansatz or a new noise channel is a function you write in an afternoon, not a plugin you register against someone else's interface.
If your work is variational algorithms, custom channels, or teaching, the Yao.jl boundary is in the right place. If your work ends with a job submitted to a provider, it is in the wrong place.
Maintenance Cost and What to Verify Before You Commit
The repository shows a push as recent as 2026-09-09 and a release tagged in March 2026, so the project is not dormant. The README names two maintainers, Xiu-Zhe (Roger) Luo and Jin-Guo Liu, with contributions from the community, and points to a contributors graph for the full list. Two named maintainers is a concentration risk worth noting for a dependency you plan to build on for years. The project also runs a monthly community call, with sign-up via a direct message to Roger-luo on the Julia Slack or via the project's Twitter account, and it accepts talk proposals through a public spreadsheet. A monthly call is a real maintenance signal, but it is also a coordination channel rather than a support contract.
On upgrades, the material gives you one concrete lever and one concrete hazard. The lever is the choice between pkg> add Yao and pkg> add Yao#master at install time: take the tagged release unless you specifically need unreleased behaviour. The hazard is the documentation split between STABLE and LATEST, which means an upgrade can move the API you are reading about before it moves the API you have installed. Read the STABLE build for the tag in your manifest.
On licensing, the README says Apache 2 and the repository metadata says NOASSERTION. Resolve that by reading the LICENSE file directly. This is not legal advice, and if Yao.jl is going into anything commercially distributed, the licence file is the document that matters, not the README sentence and not the metadata field.
Editorial conclusion
Adopt Yao.jl if you write quantum algorithms or teach them and you are already working in Julia; skip it if you need a vendor SDK that targets specific hardware or a language-agnostic circuit format. Before committing, pin the version you install (the README distinguishes pkg> add Yao from pkg> add Yao#master, and the repository shows both v0.9.3 and v0.2.1 tagged on the same day), and confirm which of the two documentation builds matches that tag, because the stable and dev docs are published separately and the README itself warns that the project is in an early-release beta with rough edges.
Community notes