Qiskit: a Python SDK for circuits, operators and primitives
Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
At a glance
- What is it?
- Qiskit is the core SDK for building quantum circuits, operators and primitive calls in Python, with a C API over a Rust data model. It is production-stable and still pushed to, but the README is thin on what happens when a circuit leaves the simulator.
- Who is it for?
- Adopt Qiskit if you write Python and need circuits, operators and the Sampler/Estimator primitives behind one interface, and if you can accept that the local statevector primitives are a starting point rather than a scaling path. Do not adopt it expecting a hardware-independent abstraction: the README is explicit that real hardware forces a rewrite to the device's basis gates and connectivity, and the transpiler is the tool that does it.
- 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 received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Qiskit is for, and who actually needs it
Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives. That sentence from the README is unusually precise, and it is worth reading literally. The library is not a full stack. It is the core component that supplies the building blocks: circuit construction, an operator toolbox, a transpiler, and two primitive functions, Sampler and Estimator.
The audience follows from that scope. If you are writing Python and your work involves describing a quantum state as a sequence of gates, then measuring it or estimating an expectation value, Qiskit is aimed at you. Researchers assembling operator algebra, engineers wiring a circuit into a job submission path, and students following a course all fall inside the same boundary. The package classifiers list Scientific/Engineering :: Quantum Computing and Development Status :: 5 - Production/Stable, so the project presents itself as stable rather than experimental.
What it is not is a hardware product. The README's own example uses `qiskit.primitives.StatevectorSampler` and `StatevectorEstimator`, then warns that these "will not take you very far" because the power of quantum computing cannot be simulated on classical computers. Everything above the simulator line, meaning real devices and their constraints, is deliberately outside this repository.
Circuits, operators and primitives: the three-part data flow
The README reduces a quantum program to three steps, and the ordering matters. First you define and build a quantum circuit that represents the quantum state. Then you define the classical output, either by measurements or by a set of observable operators. Then you pick a primitive based on which of those two you chose.
That split is the actual architecture. A circuit is a description of state preparation. Measurement and observable definition are separate concerns, and they determine whether you reach for Sampler or Estimator. The README makes the constraint concrete: the Estimator requires a circuit without measurements, so the same circuit object cannot be handed to both primitives without modification. In the example, `measure_all(inplace=False)` returns a copy rather than mutating the original, which is why the unmeasured `qc` is still available for the estimator call.
Underneath the Python API sits a second public interface. Qiskit provides a Python API and a C API, and the C API is designed to give direct access to Qiskit's internal data model, which is written in Rust. The repository layout supports this: there is a `crates/` directory, a workspace `Cargo.toml` pinning a Rust version of 1.89, and a `capi_slots.txt` file at the top level. The C API can be consumed as a shared library, `libqiskit.so`, or from its embedding inside the `qiskit` Python package for writing Python extension modules. The Python API remains the primary interface and was the only public one before Qiskit 2.0.
Installing Qiskit and running a first circuit
The README recommends pip for Python, and states that pip handles all dependencies automatically so you always install the latest tested version. The project requires Python 3.10 or newer according to `pyproject.toml`, and the runtime dependencies listed in `requirements.txt` are numpy, scipy, rustworkx, dill, stevedore and typing-extensions.
pip install qiskitAfter that, the README's first program builds a three-qubit circuit that prepares the state (|000> + i|111>)/sqrt(2), a GHZ state with a phase. It uses the Hadamard gate, the phase gate and two CNOT gates.
import numpy as np
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.p(np.pi / 2, 0)
qc.cx(0, 1)
qc.cx(0, 2)To sample outcomes, you add measurements and pass the measured copy to `StatevectorSampler`. The README uses 1000 shots and prints the counts dictionary. The expected shape of the output is roughly half `000` and half `111`, with statistical fluctuation.
qc_measured = qc.measure_all(inplace=False)
from qiskit.primitives import StatevectorSampler
sampler = StatevectorSampler()
job = sampler.run([qc_measured], shots=1000)
result = job.result()
print(f" > Counts: {result[0].data['meas'].get_counts()}")For expectation values, define the observable with `SparsePauliOp` and pass a tuple of circuit and operator to `StatevectorEstimator`, using the unmeasured circuit. The README's operator is XXY + XYX + YXX - YYY, and the documented outcome is 4. Note the `precision=1e-3` argument in the README's call; that is the estimator's convergence target, not a shot count.
The transpiler is where the simulator stops being enough
The README is blunt about the ceiling on local simulation, and it names the tool that sits between a circuit and hardware: the transpiler. Qiskit includes transpiler passes for synthesis, optimization, mapping and scheduling, plus a default compiler that the README says works very well in most examples.
The reason a transpiler is needed at all is that hardware does not accept an arbitrary gate list. Running a circuit on hardware requires rewriting it to the basis gates and the connectivity of that device. The README's example maps the GHZ circuit onto `basis_gates = ["cz", "sx", "rz"]` and a bidirectional linear chain of qubits. That is a real constraint expressed in the documentation, not a theoretical one: a two-qubit gate between qubits that are not physically adjacent has to be routed, and routing inserts operations.
This is the part of Qiskit that most repays reading the documentation rather than the README. The README names the transpiler and gives one basis-gate example, but the pass pipeline, the coupling map handling and the scheduling options are all downstream of that link. If you only ever run `StatevectorSampler`, you never touch the transpiler, and you never learn where the cost of real execution lives.
Building the standalone C library from source
The Python path is a one-line install. The C path is not. The README states that the only current option for a standalone C library is to build Qiskit from source, which requires the Rust compiler, and recommends GNU Make to simplify the build.
make cThat target compiles the C library and places a `dist/c` directory in the root of the repository containing the shared library and the C headers. The README points to separate documentation for installing and using the C API. Two things are worth flagging. First, `pyproject.toml` pins `setuptools-rust>=1.13.0` as a build requirement, and `Cargo.toml` sets `rust-version = "1.89"`, so the toolchain floor is explicit. Second, `setup.py` exists specifically so that `python setup.py build_rust --inplace --release` can produce optimized Rust components for editable installs, and it reads a `QISKIT_BUILD_PROFILE` environment variable accepting `debug` or `release`, with a warning for unknown values.
If you are consuming the C API from another language, this is the section that decides your build pipeline. There is no pip equivalent for the standalone library.
Where Qiskit is the wrong choice
The clearest limitation is stated by the project itself: the bundled statevector primitives do not scale. They are exact classical simulations, and the README says plainly that the power of quantum computing cannot be simulated on classical computers. If your goal is to run circuits beyond what a simulator can hold, Qiskit alone does not get you there. You need a backend, and the rewrite to that backend's gates and connectivity is mandatory, not optional.
A second boundary is language. The Python API is primary, and the C API is lower-level by design, giving direct access to the Rust data model rather than a friendly abstraction. If your team works in a language with neither a Python nor a C binding path, this repository is not the integration point.
There is also a versioning cost. The README notes that the Python API was the only public API before Qiskit 2.0, which means code written against older releases may assume a world without the C surface. The repository carries a `DEPRECATION.md` and a `releasenotes/` directory, so removals are tracked, but tracking is not the same as avoiding them. Pinning a version is the ordinary answer, and the project's own release cadence, three patch and minor releases between July and August 2026, means pins age.
Finally, consider the C build. If you cannot run a Rust toolchain in your build environment, the standalone library is out of reach, and you are limited to the Python package.
Qiskit compared with a circuit-level framework like Cirq
The honest comparison is not about which one is better but about what each treats as the unit of work. Cirq, from Google, is built around circuits and moments for a specific hardware family, and its abstractions are close to the device. Qiskit's README describes something broader: circuits, yes, but also operators through the quantum information toolbox and the primitive functions Sampler and Estimator as first-class entry points.
The practical difference shows up in the third step of the README's program. In Qiskit you choose a primitive based on whether your classical output is a set of bitstrings or a set of expectation values, and the Estimator takes a circuit paired with a `SparsePauliOp`. That is an operator-centric view of execution. A circuit-centric framework asks you to express the same computation as a circuit plus a measurement strategy and leaves the aggregation to you.
Neither approach is wrong. If your work is expectation values of Pauli operators, Qiskit's pairing of circuit and observable in a single `run()` call is a direct fit. If your work is pulse-level control of a specific device, you are closer to the metal than this SDK's stated scope, and the README's own framing of transpilation as a required rewrite tells you that the device layer is somewhere else.
Maintenance, licence and what a version bump costs
The repository is not archived, and the last push was on 2026-09-21. Releases are frequent: 2.5.0 on 2026-07-02, 2.5.1 on 2026-07-23, and 2.5.2 on 2026-08-13. The workspace version in `Cargo.toml` reads 2.6.0-dev, so development is ahead of the latest published release.
The licence is Apache-2.0, declared in `pyproject.toml` with `license-files = ["LICENSE.txt"]`, and the same identifier appears in the Cargo workspace. Apache-2.0 is permissive and includes an explicit patent grant, which matters for a project whose Rust crates and C API may end up embedded in other software. The source files carry a notice requiring that modifications retain the copyright notice and indicate that files were altered. That is a compliance obligation on redistributors, not a restriction on use. This is a description of what the files say, not legal advice; if you are redistributing a modified build, read `LICENSE.txt` yourself.
Upgrade cost concentrates in two places. The Python dependency floor is `requires-python = ">=3.10"`, so dropping older interpreters is a routine event. And the Rust side pins `rust-version = "1.89"` in both `Cargo.toml` and, per the README's comment, `rust-toolchain.toml`. Anyone building the C library or an editable install with optimized Rust components has to keep that toolchain current. For pure `pip install qiskit` users, neither constraint surfaces.
Editorial conclusion
Adopt Qiskit if you write Python and need circuits, operators and the Sampler/Estimator primitives behind one interface, and if you can accept that the local statevector primitives are a starting point rather than a scaling path. Do not adopt it expecting a hardware-independent abstraction: the README is explicit that real hardware forces a rewrite to the device's basis gates and connectivity, and the transpiler is the tool that does it. Before committing, verify which primitives your target backend exposes, whether your Python version meets the requires-python floor of 3.10, and whether you need the standalone C library, which the README says must be built from source rather than installed from a package.
Frequently asked questions
Is Qiskit a coding language?
No. Qiskit is an SDK, and the README describes it as an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives. It provides a Python API and a C API rather than defining a language of its own.
Is Qiskit like Python?
Qiskit is not a variant of Python; it is a library you import from Python, and the README states that the Python API is the primary interface. Its package metadata lists Python 3 only and requires Python 3.10 or newer.
How do I install Qiskit?
The README recommends installing Qiskit via pip with `pip install qiskit`, and states that pip handles all dependencies automatically so you always install the latest tested version. Installing the standalone C library is different: the README says the only current option is to build from source with the Rust compiler installed.
How do I use Qiskit in Python?
The README's program has three steps: build a circuit with `QuantumCircuit`, define the classical output by measurements or by observable operators, then run it with the Sampler or Estimator primitive. The Estimator requires a circuit without measurements, so the README uses `measure_all(inplace=False)` to keep a measured copy separate from the original.
How do I use the Qiskit Aer simulator?
The README does not document Aer. The primitives it demonstrates are `qiskit.primitives.StatevectorSampler` and `qiskit.primitives.StatevectorEstimator`, and the README warns that these will not take you very far because quantum computing cannot be simulated on classical computers.
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/qiskit-qiskit)