Quantum programming languages and SDKs, compared

The same two-qubit Bell state in Qiskit, Cirq, OpenQASM, Q#, PennyLane and five more toolkits. The ones Qollab runs in your browser come first.

A quantum program is usually written in Python with a software development kit (SDK). An SDK is a library that builds circuits and runs them on a simulator or a quantum computer. Qiskit, Cirq and PennyLane are SDKs. Q# is a language of its own from Microsoft, and OpenQASM is the text format circuits are saved and exchanged in.

If you are starting out, begin with Qiskit: open the Qiskit example below and run it on the free built-in simulator. On Qollab, Qiskit (from Python or JavaScript), OpenQASM and Cirq run in your browser.

Every example on this page builds the same circuit, a Bell state: two qubits prepared in one shared state, then measured 1,000 times. Each repetition is a shot. On a noiseless simulator about half the shots read 00 and the rest read 11. Quantum entanglement explains the state itself; from one example to the next, only the syntax changes.

Languages, SDKs and instruction formats

Quantum toolkits come in three kinds.

  • SDKs are libraries for a general-purpose language, nearly always Python. You build a circuit with function calls and send it to a backend: a simulator or a quantum computer. Eight of the ten toolkits in the table below are SDKs, among them Qiskit, Cirq and PennyLane.
  • Quantum programming languages have their own syntax and compiler. Q# ships with Microsoft's Quantum Development Kit; Silq and Quipper come from research groups.
  • Instruction formats are the text a circuit compiles to, saved and exchanged between tools. OpenQASM is the open one Qiskit reads and writes; Quil is Rigetti's.

Every toolkit in the table below can be driven from Python, so choosing a quantum programming language mostly means choosing an SDK.

How the toolkits compare

ToolkitBuilt forWhere this example runs
Qiskit (IBM SDK)Writing circuits and running them on IBM, IonQ and Amazon Braket hardware through add-on provider packagesQollab, on the backend you pick
OpenQASM (open instruction format)Saving a circuit as text and moving it between toolsQollab, loaded by Qiskit
Cirq (Google Quantum AI SDK)Circuits with explicit control over gate timing and qubit layoutQollab, on Cirq's own simulator
PennyLane (Xanadu SDK)Quantum machine learning: circuits you can differentiate and train with PyTorch or JAXYour machine
Q# (Microsoft language)Algorithms written as typed programs, and estimates of the hardware an algorithm would needYour machine
Amazon Braket SDK (AWS)Projects that send circuits to the quantum computers on Amazon BraketYour machine
pytket (Quantinuum SDK and compiler)Optimizing circuits and retargeting them to different machinesYour machine
pyQuil (Rigetti SDK)Rigetti hardware and the Quil instruction formatYour machine
CUDA-Q (NVIDIA SDK, Python and C++)Simulating circuits on NVIDIA GPUs, and combining quantum code with Python or C++ programsYour machine
Qibo (Qibo team SDK)Fast simulation, and lab control through its Qibolab packageYour machine

Which quantum programming language should you learn first?

If you write Python and want hardware runs soon, start with Qiskit. Provider packages connect it to IBM, IonQ and Amazon Braket hardware. Qollab's playground runs it on every simulator in the Run dialog and on IonQ hardware.

PennyLane fits quantum machine learning, because its circuits plug into PyTorch and JAX training loops. CUDA-Q fits GPU clusters and C++ codebases. Q# fits algorithm work that needs an estimate of the hardware an algorithm would need on future machines.

Gates read almost the same in most SDKs below; the setup code, the measurement and the call that runs the circuit differ.

Run the Bell state on Qollab

Run on Qollab under each of the four examples below opens its project page on Qollab, with the files and package requirements already in place. Press Run on Qollab on that page to open the Run dialog, headed Select QPU. Pick the built-in simulator for a first run and press Run; the counts print in the console. The OpenQASM and Cirq examples print a drawing of the circuit first.

Without an account you get one run; sign in with Google or GitHub to keep running. The playground runs Python through a browser feature called WebAssembly JSPI, found in a recent Chrome, Edge or Opera, or Firefox 153 or later. In a browser without it, Qollab keeps Run disabled; open the example in one of those browsers instead. The first run in a session loads Python and the example's packages, so it takes longer than the runs after it.

Qiskit, in Python

Qiskit is IBM's open-source SDK, and every Qollab project has it installed. backend already exists when your code starts: it is the machine you pick in the Run dialog. That can be the built-in simulator, the AWS Braket local simulator, an IBM or IonQ noise-model simulator, or IonQ's Forte quantum computers, which cost credits. A noise-model simulator copies a real machine's errors, so a few shots read 01 or 10.

main.py Python · QiskitOpen in Playground ↗
# 'backend' is pre-created for you in the Qollab Playground.
from qiskit import QuantumCircuit

qc = QuantumCircuit(2, 2)       # two qubits, two answer bits
qc.h(0)                         # H gate on qubit 0
qc.cx(0, 1)                     # CNOT: qubit 1 follows qubit 0
qc.measure([0, 1], [0, 1])      # read both qubits into the bits

job = backend.run(qc, shots=1000)
counts = job.result().get_counts()
print(counts)                   # e.g. {'00': 502, '11': 498}

{'00': 502, '11': 498} means 502 shots read 00 and 498 read 11.

Qiskit, in JavaScript

A JS project calls the same Qiskit from JavaScript. index.html and main.js at the top level make a project a JS project; main.js imports from qiskit and writes into the page. Constructors are called without new, run() is awaited, and .toJs() turns the Python result into a plain JavaScript object. JS / Qiskit projects lists the conventions.

main.js JavaScript · QiskitOpen in Playground ↗
// 'backend' is pre-created for you in the Qollab Playground.
// index.html holds <pre id="counts"></pre>.
import { QuantumCircuit } from 'qiskit';

const circuit = QuantumCircuit(2, 2);   // no `new`, as in Python
circuit.h(0);
circuit.cx(0, 1);
circuit.measure([0, 1], [0, 1]);

const job = await backend.run(circuit, { shots: 1000 });
const counts = (await job.result()).get_counts().toJs();
const text = JSON.stringify(counts);
console.log(text);
document.getElementById('counts').textContent = text;

OpenQASM

OpenQASM describes a circuit as plain text. Qiskit reads OpenQASM 3 with qasm3.loads, which needs the qiskit-qasm3-import package; the linked project lists it in requirements.txt. For older OpenQASM 2.0 text, qasm2.loads works the same way and needs no extra package. A loaded circuit is an ordinary Qiskit circuit, so it runs on the same backend.

main.py Python · OpenQASMOpen in Playground ↗
# 'backend' is pre-created for you in the Qollab Playground.
from qiskit import qasm3

bell = """
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
c = measure q;
"""

circuit = qasm3.loads(bell)
print(circuit)
counts = backend.run(circuit, shots=1000).result().get_counts()
print(counts)

Cirq

Cirq is Google Quantum AI's Python SDK. On Qollab it installs from the project's requirements.txt, which the linked project already includes (cirq-core==1.7.0), and runs on Cirq's own simulator, inside your browser. Cirq does not use backend, so pick the built-in simulator in the Run dialog; that choice loads no extra provider packages. Cirq's first run loads the most packages of the four examples. The measurement is stored under the key m, and the small bitstring helper labels the totals 00 and 11.

main.py Python · CirqOpen in Playground ↗
# Cirq runs on its own simulator here.
# In the Run dialog, pick the built-in simulator.
import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.H(q0),
    cirq.CNOT(q0, q1),
    cirq.measure(q0, q1, key="m"),
)
print(circuit)

def bitstring(bits):
    return "".join(str(int(b)) for b in bits)

result = cirq.Simulator().run(circuit, repetitions=1000)
print(result.histogram(key="m", fold_func=bitstring))

The Bell state in other toolkits

The toolkits below run on your own machine, each on a local simulator. The snapshot lists each toolkit's version.

Q#

Q# is Microsoft's quantum programming language, part of the Quantum Development Kit (QDK). Install the QDK extension for VS Code to write and run .qs files, or the Python package with pip install qdk. In VS Code, click Histogram above Main and enter 1,000 shots. Microsoft's older qsharp package is now a compatibility layer over qdk, so tutorials that import qsharp still run.

bell.qs Q# · install locally
import Std.Measurement.*;

operation Main() : (Result, Result) {
    use (q0, q1) = (Qubit(), Qubit());
    H(q0);
    CNOT(q0, q1);
    (MResetZ(q0), MResetZ(q1))
}

The program measures both qubits with MResetZ, which also resets them, and returns one pair of results. From Python, qsharp.run repeats it 1,000 times, and Counter tallies the pairs:

run_bell.py Python · QDK
from collections import Counter
from pathlib import Path
from qdk import qsharp

qsharp.eval(Path("bell.qs").read_text())
print(Counter(qsharp.run("Main()", shots=1000)))   # (Zero, Zero) and (One, One)

PennyLane

PennyLane is Xanadu's SDK for differentiable circuits. Install it with pip install pennylane. The device is the simulator and the decorated function builds the circuit. Returning qp.counts() asks for the measured totals, so there is no separate measure line; calling bell() runs the circuit and returns them. set_shots sets the 1,000 shots. PennyLane's docs import the package as qp; older code uses qml.

bell.py Python · PennyLane
import pennylane as qp

dev = qp.device("default.qubit", wires=2)

@qp.set_shots(1000)
@qp.qnode(dev)
def bell():
    qp.Hadamard(wires=0)
    qp.CNOT(wires=[0, 1])
    return qp.counts()

print(bell())

Amazon Braket SDK

The Amazon Braket SDK builds circuits for the quantum computers on Amazon Braket. Install it with pip install amazon-braket-sdk; the local simulator needs no AWS account. The circuit needs no measure line: the result counts both qubits.

bell.py Python · Braket SDK
from braket.circuits import Circuit
from braket.devices import LocalSimulator

bell = Circuit()
bell.h(0)
bell.cnot(0, 1)
result = LocalSimulator().run(bell, shots=1000).result()
print(result.measurement_counts)

pytket

pytket is Quantinuum's SDK and compiler. It has no simulator of its own, so this example runs on Qiskit Aer through the pytket-qiskit extension: pip install "pytket-qiskit[aer]". measure_all() adds the measurement Qiskit writes as a separate line.

bell.py Python · pytket
from pytket import Circuit
from pytket.extensions.qiskit import AerBackend

circuit = Circuit(2)
circuit.H(0)
circuit.CX(0, 1)
circuit.measure_all()        # measures every qubit into its own bit
result = AerBackend().run_circuit(circuit, n_shots=1000)
print(result.get_counts())   # keys are bit tuples: (0, 0) and (1, 1)

pyQuil

pyQuil is Rigetti's SDK; programs compile to Quil, Rigetti's instruction format. Install it with pip install pyquil; version 4.22 installs on Python 3.11 and 3.12. Running locally needs two Rigetti servers: start the quilc compiler with quilc -S and the qvm simulator with qvm -S, each in its own terminal, and leave them running. Rigetti's guide to installing the Quil SDK locally covers installing them. In the code, ro holds the measured answers, qc.compile prepares the program for the simulator, and Counter tallies the rows that come back.

bell.py Python · pyQuil
from collections import Counter
from pyquil import Program, get_qc
from pyquil.gates import CNOT, H, MEASURE
from pyquil.quilbase import Declare

program = Program(
    Declare("ro", "BIT", 2),
    H(0),
    CNOT(0, 1),
    MEASURE(0, ("ro", 0)),
    MEASURE(1, ("ro", 1)),
).wrap_in_numshots_loop(1000)

qc = get_qc("2q-qvm")
bits = qc.run(qc.compile(program)).get_register_map().get("ro")
print(Counter("".join(map(str, row)) for row in bits))

CUDA-Q

CUDA-Q is NVIDIA's SDK for quantum kernels in Python and C++; a kernel is the decorated function that holds the circuit. Inside it, h, x.ctrl and mz are H, CNOT and measurement. Install the Python package with pip install cudaq. It runs on Linux, and on Apple silicon Macs on the CPU. On Linux it uses an NVIDIA GPU by default when one is present.

bell.py Python · CUDA-Q
import cudaq

@cudaq.kernel
def bell():
    qubits = cudaq.qvector(2)
    h(qubits[0])
    x.ctrl(qubits[0], qubits[1])
    mz(qubits)

print(cudaq.sample(bell, shots_count=1000))

Qibo

Qibo is an open-source SDK with several simulation backends; its sibling package Qibolab controls lab hardware. Install it with pip install qibo; the current release supports Python 3.10 to 3.13. gates.M measures, calling the circuit runs it, and frequencies() returns the counts.

bell.py Python · Qibo
from qibo import Circuit, gates

circuit = Circuit(2)
circuit.add(gates.H(0))
circuit.add(gates.CNOT(0, 1))
circuit.add(gates.M(0, 1))
result = circuit(nshots=1000)
print(result.frequencies())

Research languages and specialist tools

  • Qmod is Classiq's high-level modeling language. You describe what a function should do, and Classiq's engine synthesizes the gates.
  • Bloqade is QuEra's Python SDK for its neutral-atom machines.
  • Stim, from Google's quantumlib, simulates stabilizer circuits very fast. Stabilizer circuits are a restricted kind used in quantum error correction research.
  • Quipper is a functional quantum programming language embedded in Haskell.
  • Silq is a typed high-level quantum language from ETH Zurich that cleans up temporary values automatically.

Questions people ask

Is it worth learning quantum programming?

With Python and three ideas (qubits, gates and measurement), you can write a circuit like the Bell state above. You can then run it on a simulator or a quantum computer. The SDK syntax is the smaller part, as the examples on this page show. Programming your first quantum circuits is a free Qollab course that starts from one qubit and runs every step in the Code Playground.

Is C++ used for quantum computing?

Yes. CUDA-Q has a C++ API: kernels marked __qpu__ are compiled with NVIDIA's nvq++ compiler. Q# is a separate language with its own compiler, and its syntax borrows from C# and F#.

Why is most quantum code written in Python?

Python builds the circuit and reads the results; the simulation runs in compiled code or on the quantum computer. Every toolkit in the table above can be driven from Python, including Q# through Microsoft's qdk package.

A snapshot, October 2026

Versions as checked on 13 October 2026. The four Qollab examples ran in Qollab's playground. The others ran on a local simulator, except pyQuil and Qibo, which are shown as their maintainers document them. Check each toolkit's docs before you install.

ToolkitVersionInstallDocs
Qiskit2.5.2in every Qollab project; pip install qiskitQiskit
qiskit-qasm3-import0.6.0requirements.txt on Qollabqiskit-qasm3-import
Cirq1.7.0requirements.txt on Qollab; pip install cirq-coreCirq
Q# (QDK)1.33.1Python: pip install qdk; VS Code: the QDK extensionQ# quickstart
PennyLane0.45.1pip install pennylaneset_shots
Amazon Braket SDK1.127.3.post0pip install amazon-braket-sdkBraket SDK
pytket, pytket-qiskit2.18.5, 0.78.0pip install "pytket-qiskit[aer]"pytket
pyQuil4.22.0pip install pyquil, plus quilc and qvmpyQuil
CUDA-Q0.16.0pip install cudaqCUDA-Q quick start
Qibo0.3.5pip install qiboQibo

Stay in the loop.

Get the latest tutorials, demos, and project showcases straight to your inbox. No noise, just the good stuff.