ProjectQ: a quantum compiler framework where the backend is a plug-in, not a rewrite
ProjectQ: An open source software framework for quantum computing
At a glance
- What is it?
- ProjectQ is an Apache-2.0 Python framework for quantum computing that pairs a lean gate-application syntax with a compiler able to target several hardware providers, a classical simulator, and a resource counter for architecture-aware estimates. The trade-off is that the framework has had no tagged release since v0.8.0 in 2022 even though commits continue.
- Who is it for?
- Adopt ProjectQ when you want one Python program to move between simulation, emulation, resource estimation and several hardware providers without rewriting the circuit, and when you can live with a framework whose last tagged release is v0.8.0 from 2022. Skip it if you need a documented, versioned feature matrix or a maintained answer to provider API changes, because the backends encode provider details that drift.
- 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 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What ProjectQ solves: one program, several execution targets
ProjectQ is an open source software framework for quantum computing. It offers three things that normally come as separate decisions in a quantum project: a compilation framework that can target various types of hardware, a high-performance quantum computer simulator with emulation capabilities, and a set of compiler plug-ins.
The problem behind that design is the fragmentation of quantum hardware. Every provider exposes its own gate sets, its own connectivity constraints, its own queue and its own authentication path, so code written for one device usually cannot run on another without editing. ProjectQ pushes that variation into the back end, where a plug-in and a matching setup module handle it, and leaves the program itself alone.
From one program you can run on the IBM Quantum Experience chip, AQT devices, AWS Braket, Azure Quantum or IonQ provided devices, simulate on classical computers, emulate at a higher level of abstraction, export the program as a circuit using TikZ, and get resource estimates. That last one deserves emphasis, because estimating what a program would cost on a future machine is often more useful than running it on the small devices available today.
The audience is Python developers writing quantum algorithms and circuits who want to keep the algorithm separate from the provider.
The pipe operator turns gates into mathematical notation
ProjectQ's syntax is deliberately close to the notation used in quantum physics. A rotation around the x-axis, written in bra-ket notation, becomes a single line of Python where the operator separates the gate from the qubits it applies to:
Rx(theta) | qubitThe | operator separates the specification of the gate operation on the left from the quantum bits it applies to on the right. There is no separate instruction queue and no explicit index bookkeeping in the usual case.
The first program in the documentation shows the whole cycle. MainEngine creates a default compiler whose back end is a simulator, allocate_qubit returns a single qubit, gates are applied with the pipe operator, and eng.flush() flushes all gates and executes the measurements. Converting a qubit to an int or a bool gives access to the measurement result:
from projectq import MainEngine # import the main compiler engine
from projectq.ops import (
H,
Measure,
) # import the operations we want to perform (Hadamard and measurement)
eng = MainEngine() # create a default compiler (the back-end is a simulator)
qubit = eng.allocate_qubit() # allocate a quantum register with 1 qubit
H | qubit # apply a Hadamard gate
Measure | qubit # measure the qubit
eng.flush() # flush all gates (and execute measurements)
print(f"Measured {int(qubit)}") # converting a qubit to int or bool gives access to the measurement resultThe flush call is the point where the accumulated gates are handed to the back end. Programmers coming from a request-based quantum SDK will recognise the pattern of batching work before sending it, and programmers coming from a circuit-building API will notice that the program reads as a sequence of operations rather than a construction of a circuit object.
ResourceCounter answers what the machine would cost, not what it returns
The resource counter is the most unusual back end in the framework, and the one that changes what a project can do before hardware is available. Instead of simulating a program, you can attach a resource counter as the back end to determine how many operations it would take on a future quantum computer with a given architecture.
The example assumes a linear chain of qubits where the architecture supports any single-qubit gate plus the two-qubit CNOT and Swap operations. The setup module produces the compiler engine list, and the resource counter replaces the simulator:
from projectq import MainEngine
from projectq.backends import ResourceCounter
from projectq.ops import QFT, CNOT, Swap
from projectq.setups import linear
compiler_engines = linear.get_engine_list(num_qubits=16, one_qubit_gates='any', two_qubit_gates=(CNOT, Swap))
resource_counter = ResourceCounter()
eng = MainEngine(backend=resource_counter, engine_list=compiler_engines)
qureg = eng.allocate_qureg(16)
QFT | qureg
eng.flush()
print(resource_counter)The output reports gate class counts, for example AllocateQubitGate : 16, CXGate : 240, HGate : 16, R : 120, Rz : 240 and SwapGate : 262 for that configuration.
The architectural input is the interesting part, not the counts. Because the setup describes the topology and the available gates, changing from a linear chain to a different architecture changes the estimate, since routing has to be added. That makes the estimator a decision tool for algorithm design rather than a benchmark.
One caveat: the estimate is only as good as the architecture description you give it, and the framework has no way to know the real device you will eventually use.
Each provider needs its own backend class and its own setup module
Hardware access follows a consistent pattern in ProjectQ. A back end class sends the program to the provider, and a setup module produces the compiler engine list that matches the device's characteristics. The two are used together.
For IBM Quantum Experience chips, the example imports projectq.setups.ibm and IBMBackend, and passes a token, a device name and use_hardware=True:
import projectq.setups.ibm
from projectq.backends import IBMBackend
token = 'MY_TOKEN'
device = 'ibmq_16_melbourne'
compiler_engines = projectq.setups.ibm.get_engine_list(token=token, device=device)
eng = MainEngine(
IBMBackend(token=token, use_hardware=True, num_runs=1024, verbose=False, device=device),
engine_list=compiler_engines,
)The AQT trapped ion case follows the same shape with AQTBackend and projectq.setups.aqt. The AWS Braket case uses AWSBraketBackend with credentials, an S3 folder and a device name, and the documentation lists the supported devices as Aspen-8 from Rigetti, IonQ, and the state vector simulator SV1. Azure Quantum uses AzureQuantumBackend with a target name, a resource id and a location, and the documentation says it runs on hardware and simulator devices from IonQ and Quantinuum.
The pattern is consistent, which makes switching providers a matter of swapping two lines. The cost is that provider details are baked into the setup modules: device names, credentials shapes and endpoints are recorded in the framework, and those are exactly the things that change when a provider revises its service.
Installing ProjectQ and the extra each provider needs
ProjectQ is published on PyPI as projectq and can be installed from a source checkout or from the package index. The optional provider dependencies are declared as extras in pyproject.toml, so the right install command depends on which service you intend to call.
For AWS Braket, the documentation states that the braket extra requirement is needed, and gives two forms of the command:
python3 -m pip install projectq[braket]cd /path/to/projectq/source/code
python3 -m pip install -ve .[braket]The second form is the editable install from a source checkout, which is what you want if you intend to read or modify the framework itself.
The available extras cover the provider integrations and the development workflow. azure-quantum pulls in the azure-quantum package, braket pulls in boto3, and revkit pins revkit == 3.0a2.dev2 together with dormouse. There are separate extras for tests, with pytest, pytest-cov, pytest-mock, mock and flaky, and for documentation, with sphinx and sphinx_rtd_theme.
The base install is deliberately small. The core dependencies are matplotlib, networkx, numpy, requests and scipy, and the package requires Python 3.8 or newer, with classifiers covering 3.8 through 3.12.
Emulation and circuit export cover the gap between simulation and hardware
Two capabilities sit between running on a simulator and running on hardware, and they are the ones most often left out of comparable frameworks.
Emulation runs a quantum program at a higher level of abstraction rather than compiling it down to low-level gates. The documentation gives the case of mimicking the action of large oracles instead of compiling them, which means you can test an algorithm's logic against a large oracle that would be infeasible to decompose into gates on the hardware you have. The tradeoff is that emulated results are not a prediction of what a device will do.
Circuit export uses TikZ, so a program can be turned into a drawn circuit for a paper, a talk or a design review. That is a small feature with a disproportionate effect on how a result gets communicated.
Resource estimates, as described earlier, complete the set of things you can do without a device.
What is not described is noise modelling or error mitigation in the back ends, nor a mechanism for scheduling against a live queue beyond the parameters each back end accepts, such as num_runs. If your research question is about device noise, this framework's documented surface does not cover it, and the examples directory, which contains scripts for Grover, Shor, teleport, Bell pairs, a half adder and the control tester, is oriented towards algorithm demonstrations rather than noise studies.
Versions, extras and what the licence covers
The maintenance picture needs reading carefully. The repository is not archived and the last push was on 2026-10-19, so work on the framework continues. The tagged releases, though, stop earlier: v0.8.0 on 2022-10-18, v0.7.3 on 2022-04-27 and v0.7.2 on 2022-04-11. The default branch is develop rather than master, and the version is dynamic in the build configuration, with setuptools_scm deriving it from the repository state rather than a hardcoded number.
So there are two ways to adopt it, with different risk profiles. A pip install gives you v0.8.0 from 2022, a coherent snapshot whose provider integrations may no longer match current service APIs. Working from a checkout of the develop branch gives you current code with provider fixes applied but no version guarantee and a moving target.
The licence is Apache License Version 2.0, recorded in the pyproject metadata and shipped as LICENSE with a NOTICE file alongside it. That is a permissive licence with the usual attribution and patent conditions, so a commercial project can use, modify and redistribute it. The setup.py file notes that parts of its code are inspired by or copied from SQLAlchemy, and it carries the MIT licence text and the list of contributing authors, including the ProjectQ contributors, which is the kind of attribution notice the NOTICE file exists to preserve.
For a research group, the practical upgrade cost is not the licence but the provider back ends, since each one encodes a service contract that changes independently of the framework.
Editorial conclusion
Adopt ProjectQ when you want one Python program to move between simulation, emulation, resource estimation and several hardware providers without rewriting the circuit, and when you can live with a framework whose last tagged release is v0.8.0 from 2022. Skip it if you need a documented, versioned feature matrix or a maintained answer to provider API changes, because the backends encode provider details that drift. Before committing, check which optional extra your provider needs, such as braket for AWS or azure-quantum for Azure, and confirm that your Python version sits inside the supported range and that the pinned provider setup still matches the device names you intend to use.
Frequently asked questions
How do I install ProjectQ for quantum computing in Python?
ProjectQ is published on PyPI as projectq and supports Python 3.8 and newer. Provider integrations are optional extras declared in pyproject.toml, for example python3 -m pip install projectq[braket] for AWS Braket, and python3 -m pip install -ve .[braket] for an editable install from a source checkout.
What is the difference between simulating and emulating a quantum program in ProjectQ?
Simulation runs the program on a classical computer through the simulator back end, while emulation works at a higher level of abstraction, for example mimicking the action of large oracles instead of compiling them to low-level gates. Emulation is faster to set up but does not model the gate-level behaviour of a device.
How do I estimate how many operations a quantum algorithm would need?
Attach the ResourceCounter as the back end and describe the target architecture through a setup module, for example linear.get_engine_list with num_qubits, one_qubit_gates and two_qubit_gates. Flushing the engine and printing the counter prints gate class counts for that configuration.
Which quantum hardware providers can ProjectQ run on?
The documentation covers the IBM Quantum Experience chip, AQT devices, AWS Braket, Azure Quantum and IonQ provided devices. Each one uses a backend class together with a matching setup module, and the AWS Braket backend documents support for Aspen-8 from Rigetti, IonQ and the SV1 state vector simulator.
Can ProjectQ export a quantum program as a circuit?
Yes, the framework can export quantum programs as circuits using TikZ. It also supports emulation at a higher level of abstraction and resource estimation, so a program can be analysed before it reaches hardware.
Official sources
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.
[](https://hysenlabs.com/projects/projectq-framework-projectq)Was this useful?