Building with Quantum Entanglement

What entanglement means, where the idea came from, and real projects built on it that you can run and fork.

About the author

Nicolaas Spijker
Nicolaas Spijker
Community manager, Qollab

Nico runs the builder community at Qollab. These concept articles come out of that work: forking the projects people publish and running them. And talking with authors to learn more about their projects.

Entanglement is two or more qubits in one joint state that cannot be split into a separate state for each. For the pair built below, neither qubit has a definite value of its own until it is measured.

Measure both the same way and you know one result from the other straight away, however far apart they are. Nothing travels between them, and nothing can be sent this way: to see the agreement, both people still have to compare results over an ordinary channel, no faster than light.

This is not the same as two matched gloves posted in two boxes. There, each box held a definite glove all along and opening one only revealed it. An entangled pair holds no definite values before the measurement, and the answers still agree. The Bell state below shows how to tell the two apart.

Where entanglement came from

The effect was argued about for thirty years before anyone could test it.

1935Einstein, Podolsky and Rosen argue the effect means quantum theory is incomplete.
1935Schrödinger names it entanglement, the characteristic trait of quantum mechanics.
1964John Bell shows entangled particles correlate too strongly for any local hidden-variable theory.
1972Clauser and Freedman run the first experimental test of Bell's limit.
1982Aspect confirms the violation in tighter experiments.
2022Aspect, Clauser and Zeilinger share the Nobel Prize in Physics.

Einstein called it "spooky action at a distance" and bet the result was carried by some hidden detail the theory had missed.

Bell turned that bet into a number: if the values were fixed in advance and nothing travelled between the particles, the correlations could not exceed a certain limit. Entangled pairs exceed it, and the last loopholes in those experiments were closed in 2015.

Einstein's kind of hidden detail, local and fixed in advance, is ruled out.

The smallest one you can make

You do not need particles and a laboratory to make one. Two qubits are enough: put one into superposition with a Hadamard, then link it to the second with a CNOT. Two gates, and every project below reaches for the same pair or a close relative.

bell_state.py Python · Playground versionOpen in Playground ↗
# 'backend' is pre-created for you in the Qollab Playground.
from qiskit import QuantumCircuit
1qc = QuantumCircuit(2, 2)
2qc.h(0)
3qc.cx(0, 1)
4qc.measure([0, 1], [0, 1])
5job = backend.run(qc, shots=1000)
6counts = job.result().get_counts()
print(counts)
  1. 1A circuit is a list of operations to run in order. This one asks for two qubits and two ordinary bits: the qubits do the quantum work, and the bits are storage for the answers you read out at the end.
  2. 2A gate is one operation applied to a qubit. This is the Hadamard, applied to qubit 0, and it leaves that qubit in superposition: no fixed value, equally likely to read 0 or 1 once you measure it.
  3. 3The line that entangles. CNOT is a two-qubit gate: the first argument is the control, the second is the target, and it flips the target on every branch where the control reads 1. Because qubit 0 has no fixed value yet, both branches survive, and the two qubits end up sharing one state.
  4. 4Measuring is the only way to see a qubit, and it forces each one to a definite 0 or 1. This copies qubit 0 into bit 0 and qubit 1 into bit 1.
  5. 5Send the circuit to a real quantum computer, or to a simulator. One run gives one pair of bits and which pair is random, so you run it 1,000 times to see the pattern. Each run is called a shot.
  6. 6Tally those 1,000 results. {'00': 502, '11': 498} means 502 runs gave both qubits 0, and 498 gave both 1.
Run on QollabBackend

|00⟩ means both qubits came out 0. About half the shots come back 00 and half 11, never 01 or 10. Which one you get is random, but the two always agree. On real hardware a few mismatched shots appear: device noise, not the physics.

Those counts alone do not prove entanglement: two gloves give the same 00 and 11. The difference shows if you ask a different question. A basis is the question you put to a qubit, and "are you 0 or 1" is only one of them.

Fork the Bell state, add qc.h(0) and qc.h(1) just before the measurement, and you are asking another. The pair still agrees every time; gloves measured this way agree only half the time.

The gates in these circuits

Five gates cover every excerpt on this page, and two of them are the ones you just ran. The full projects reach for a few more, mostly other rotations.

h

Hadamard

Takes a qubit sitting at 0 and leaves it with no fixed value: measure it and you get 0 or 1 with equal probability.

The Hadamard is not a coin flip, though, and reversibility is what separates them. Apply a second Hadamard before measuring and the qubit reads 0 every time, which no coin could do.

cx

CNOT

A two-qubit gate. The first qubit you pass is the control and the second is the target, and it flips the target whenever the control reads 1. On plain 0s and 1s that is an if-statement drawn as a circuit.

The CNOT becomes the entangling gate when the control has no fixed value and the target does have one. That is the Bell state: a control in superposition over a target sitting at 0, so both branches survive and the pair ends up sharing one state.

Entangling is not automatic, though. Give it a target already sitting in an even split of its own and the gate can leave the pair exactly as it found it. That is the situation the Market Game runs into below.

ry

A rotation. The angle comes before the qubit and sets how likely a qubit starting at 0 is to read 1.

At 0 it is certain to read 0, at π certain to read 1, and at π/2 it gives the same even split the Hadamard does. Anything in between is a bias you choose.

rzz

Couples two qubits by an angle. Unlike the others it does not change how often either qubit reads 0 or 1 on its own. The counts from a plain measurement look the same whether the coupling is there or not.

The coupling changes the relationship between the two instead, which is why Entangled Body's couplings entangle the state and still leave no trace in its results.

measure

Reads a qubit into an ordinary bit and forces it to a definite 0 or 1. It is the one irreversible step: whatever the qubit held before is gone once you look.

So a single run tells you one outcome and nothing about the odds behind it, which is why the circuits here that measure are run many times over.

The projects below each put an entangling operation to work in a different way: a game, a body, a garden, a grid of sound and a field of butterflies. Each one shows the line where the entangling happens, or where it would if you changed one thing, and all are open to fork.

Two choices that stop being independent

Two traders each pick buy or sell, and the payouts pull against each other: selling while the other buys pays the most, but if both sell they both lose money.

Classically the two decide independently. Quantum Market Game puts each decision on a qubit and lets you entangle the pair before measuring, so the choices can come out correlated instead of independent.

Play both sides, then read who came out ahead. Press play, sound on.

Each trader is a qubit: |0⟩ means sell, |1⟩ means buy. A rotation sets the odds, so a trader can be mostly buy, mostly sell, or anywhere between.

Unless a trader is set all the way to certain, both sit in superposition until the market opens, and measuring the pair is the moment each decision becomes real.

simulator.py Python · excerptOpen in Playground ↗
qc = QuantumCircuit(2, 2)
1qc.ry(angle_1, 0)
qc.ry(angle_2, 1)
2if entanglement:
3    qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
  1. 1The angle sets this trader's odds, and it comes before the qubit. At 0 they are certain to sell, at π certain to buy, at π/2 the even 50/50 the Hadamard makes. In between it is not linear: the chance of buying is sin²(angle/2).
  2. 2Every bit of correlation in the game hangs on one optional line. With the flag off the two qubits stay independent and the round is ordinary game theory played with random draws.
  3. 3The same CNOT as the Bell state, and at the shipped defaults it does essentially nothing: two qubits both at π/2 are one of the inputs a CNOT leaves unchanged, and 1.5707 is π/2 to four places.
Run on QollabBackend

The game shows one basis only, buy or sell, and a table of correlated outcomes can always be reproduced by classical shared randomness, so this is not a Bell test. What you can see is the payoff shifting when the correlation switches on.

Set angle_1 to π/2 and angle_2 to 0, which is where the CNOT does bite, then run with entanglement off and on. Same angles, different payoff table, and with it on the pair is a Bell state you could test in a second basis.

Quantum Market GameQuantum Market GameAadarsh Venkat Ramanan · u/q-aad · Python + QiskitThe project is a twist on a classical game theory scenario: Prisoner's Dilemma.

Neither half has a state of its own

Put each qubit of a maximally entangled pair on its own Bloch sphere and the arrow that normally marks its state shrinks to the centre. A lone qubit points somewhere; each half of a Bell pair points nowhere.

A single qubit has a Bloch vector reaching the sphere surface; after entangling, each qubit of the pair has only a dot at the centre
Bloch spheres of one qubit (left) and of each qubit of a Bell pair (right). The pair's arrows have zero length: there is no local direction left to draw.

A pure two-qubit state is a list of four numbers, easy to write down and hard to picture. Entanglement makes it harder, because the interesting part is exactly what you cannot see by looking at either qubit alone. You can know the pair completely and still know nothing about each half.

Onri Benally's visualiser draws the same pictures for two states, the plain |00⟩ product state and a Bell pair, so you can put them side by side.

The visualiser builds its Bell pair from the same two gates as the Bell state above, then adds a couple of single-qubit turns that leave the entanglement untouched.

Each state goes to a set of plotting functions. The excerpt is the opening of one of them, the steering-ellipsoid plot, which is where the three parts of the state get computed.

plot_steering_ellipsoid() Python · excerptOpen in Playground ↗
1    rho = state.data
    # Calculate Bloch vectors and correlation tensor
2    a = np.array([np.trace(rho @ np.kron(s, np.eye(2))).real for s in pauli_matrices])
3    b = np.array([np.trace(rho @ np.kron(np.eye(2), s)).real for s in pauli_matrices])
4    T = np.array([[np.trace(rho @ np.kron(si, sj)).real for sj in pauli_matrices] for si in pauli_matrices])
  1. 1The density matrix: a 4 by 4 grid of numbers holding everything there is to know about the two qubits together. state is whichever of the two states the visualiser was handed.
  2. 2Qubit A on its own. np.kron pastes two small matrices into one that acts on A and leaves B alone, and the trace against rho turns that into a single number. Three axes, three numbers, and for a Bell pair all three are 0.
  3. 3The same three numbers for qubit B, and also all zeros. Neither qubit points anywhere by itself.
  4. 4Now both qubits at once: nine numbers, one for each pair of axes. On their own they do not prove anything, since a plain |00⟩ has a 1 in there too. What matters is that for the Bell pair they survive while a and b go to zero, so T can no longer be a times b.
Run on QollabBackend

Fork it and print all three for |00⟩, then for the Bell pair. Both have entries in T, so a filled-in T proves nothing by itself.

The difference is what T is made of. For |00⟩ it is exactly a times b, the correlations two qubits that each point somewhere would give you anyway. For the Bell pair a and b are zero and T is not, so no pair of individual directions can account for it.

2-qubit states, visualized 8 waysOnri Jay Benally · u/onri-jay-benally · Python + QiskitOne entangled state, eight ways to see it.

Entangled, and invisible in the counts

Entangled Body is a 3D human figure whose regions are qubits, linked by entangling gates that follow the body's own map: strong between head and chest, absent between distant limbs.

Touch one region and the figure responds around it. Press play.

Fourteen regions map to fourteen qubits. A touch sets each region's rotation by its distance from the touched one. The anatomical links nearest that region then get an Rzz coupling, eight of them on a hover and all seventeen on a click.

The ripple you see when you touch a region comes from those rotations: nearer regions are more likely to light up. The Rzz couplings entangle the state, but the circuit measures straight in the Z basis, and Rzz only changes phases, so the couplings leave no trace in the counts.

entangled_body_demo.py Python · excerptOpen in Playground ↗
1for src, tgt, strength in _ranked_links(distances, interaction):
2    s = max(0.05, min(1.0, strength))
3    ops.append(("rzz", QUBIT_OF[src], QUBIT_OF[tgt], _edge_angle(s, interaction)))
  1. 1Walk the seventeen anatomical links the piece defines, ordered by how close each one sits to the region you touched. A hover takes only the nearest eight; a click or a hold takes all seventeen.
  2. 2Hold that strength inside 0.05 to 1 before it becomes an angle, so the faintest link still couples a little and the strongest is capped.
  3. 3The entangling line. _edge_angle turns the link strength into the Rzz angle, and QUBIT_OF looks up which qubit a body region is. The circuit is collected as a list of operations rather than built by calling gate methods.
Run on QollabBackend

To make the couplings visible, fork it and add a Hadamard on every region before the measurement. The couplings then reach the counts instead of hiding in the phases.

Look for it on the linked pairs a touch actually selected. The region you touched is prepared close to certain, and a network of edges does not respond one edge at a time. It will not light up everywhere at once.

Entangled BodyEntangled BodyChanhyuk Park & Luke Shim · u/lukeshim · Python + QiskitEntangled Body is an interactive 3D artwork that treats the body as a network of 14 quantum nodes, each mapped to a specific body region.

One draw instead of five separate rolls

Quantum Garden grows its plants from real quantum measurements. The circuit below is the one its rarest plants use, and it entangles five qubits so a plant's traits come out correlated rather than as five independent rolls.

The garden also mirrors traits between plants in the same entanglement group, wherever they stand. That link is bookkeeping rather than physics: the groups are stored alongside the results, and no gate in this circuit reaches another plant.

Quantum Garden, a generative garden whose plants come from real quantum hardware
Every plant is grown from a real quantum measurement.

The circuit has six layers. A Hadamard on every qubit opens all thirty-two outcomes, seed-based rotations bias each qubit toward the plant's own tendencies, and a chain of CNOTs ties neighbours together.

Phase rotations add interference, a second set of CNOTs couples qubits across the chain, and a last round of rotations sets the final state before measurement. Five measured bits come out, and every trait the plant shows is read off them.

None of that runs while you watch. The circuit went to IonQ ahead of time and its results sit in a pool of 500. Hovering a plant assigns it one and fixes its traits from then on, group and all.

plant_circuit.py Python · excerptOpen in Playground ↗
# Layer 3: Linear entanglement chain — correlates neighboring qubits
for i in range(4):
1    circuit.cx(i, i + 1)
# Layer 4: Seed-based Rz phases — creates interference patterns
# ...
# Layer 5: Cross-entanglement — non-local correlations across the circuit
circuit.cx(0, 2)
circuit.cx(1, 3)
2circuit.cx(2, 4)
  1. 1Four CNOTs in a row: 0 to 1, 1 to 2, 2 to 3, 3 to 4. Each ties a qubit to its neighbour, so the five bits stop being five independent coin flips.
  2. 2Three more that skip a neighbour. The chain already carried correlation past adjacent pairs, so these add direct long-range couplings rather than creating the first ones.
Run on QollabBackend

Fork the plant circuit and delete the three cross-chain CNOTs. The neighbour chain still entangles the qubits, but the output distribution changes. Run the same seed both ways and compare which pairs of bits still move together, or compute each pair's mutual information to put a number on it.

Quantum GardenQuantum GardenAmber Wang & Justin Pincar · u/AmberPincar · Python + QiskitQuantum Garden is an interactive generative art installation where digital plants exist in quantum superposition until observed.

Entanglement that does not stay in its cell

Quantum Patterns runs a grid of cells and updates every one with the same small circuit. The cells overlap from step to step, so whatever that circuit does to its two qubits does not stay in one cell. Entangle them and the correlation walks across the grid.

A cell circuit applied across the grid, and the grid driving the music. Press play.

The rule is a partitioned quantum cellular automaton. The grid is cut into two-qubit cells. Two tessellations, offset by one qubit, alternate each step, so a cell's right qubit is the next cell's left qubit a step later.

The quickstart's cell circuit is a single CNOT on a grid that starts with one excitation at the left edge. On its own that is a classical, reversible rule: it moves bits around and creates neither superposition nor entanglement. Treat it as the baseline.

Entanglement enters when the cell puts its control qubit into superposition before the CNOT. Superposition alone is not enough: a Hadamard on the target leaves the two qubits as independent as it found them.

pqca_quickstart.py Python · excerptOpen in Playground ↗
# The circuit applied to every cell. Here: a single CX on 2 qubits.
1cell = qiskit.QuantumCircuit(CELL_SIZE)
2cell.cx(0, 1)
# Two offset tessellations make the update couple across cell borders.
3tes = pqca.tessellation.one_dimensional(NUM_QUBITS, CELL_SIZE)
  1. 1The rule: one small circuit, applied to every cell of the grid on every step.
  2. 2A single CNOT. On plain 0s and 1s that only shuffles bits around, which makes this the classical baseline: no superposition, no entanglement. Put a Hadamard in front of it and the same rule starts spreading entanglement instead.
  3. 3How the grid gets cut into cells. Two cuts offset by one qubit take turns, so a cell's right qubit is the next cell's left qubit on the following step, and whatever the rule does travels along the grid.
Run on QollabBackend

Fork it and put cell.h(0) in front of cell.cx(0, 1). One gate is enough to make the rule quantum: each step now creates superposition and the CNOT entangles it across the cell border. Raise STEPS and watch how far the correlation has travelled by the end.

Quantum PatternsQuantum PatternsPeter Thomas & Paulo Itaboraí · u/cephasteom · Python + QiskitQuantum Patterns explores Partitioned Quantum Cellular Automata (PQCA) as the basis for live-coded musical composition.

Information that no longer lives in one qubit

Quantum Butterfly Field scrambles five qubits together with random entangling gates until the state is spread across all of them, then damages one qubit. Running the scramble backwards recovers much of what that qubit held.

Five qubits scramble into one field; a damaged one is repaired from the rest. Press play.

Five butterflies are five qubits. Each layer rotates every qubit by a random angle and then entangles two random pairs, and three layers are enough to dissolve the butterflies' separate identities into one field. Then one butterfly is damaged: an extra qubit is coupled into it, which severs its correlations with the rest.

In a classical chaotic system that damage would be permanent: small damage cascades, the butterfly effect. Once information is scrambled deeply enough across an entangled system, it no longer lives in any single qubit but in the correlations between them.

So running the scramble backwards can pull much of the damaged qubit back out of the field it was spread into.

Partly, not perfectly: on an exact simulation the repaired qubit matches what it started as about 83% of the time. Yan and Sinitsyn showed this in 2020, in a paper on recovering damaged information, and it is known as the quantum anti-butterfly effect.

Xinyi Zhang pairs the physics with lōkahi, the Native Hawaiian idea of wholeness through relationship.

What the project reports is worth reading closely. The score is built from the length of the repaired qubit's Bloch vector, so it measures how sharply defined that qubit ended up.

The score does not measure whether the qubit came back as the state it started in, and a confidently wrong answer scores as well as a right one.

qbf_protocol.py Python · excerptOpen in Playground ↗
# Random disjoint CX pairs: shuffle all qubits, pair them up.
qubits = list(range(n_qubits))
1rng.shuffle(qubits)
2for i in range(0, n_qubits - 1, 2):
3    layer.append(('cx', int(qubits[i]), int(qubits[i + 1])))
  1. 1Shuffle the five qubits into a random order, so each layer draws its own pairing rather than reusing one.
  2. 2Step through them two at a time. Five qubits gives two pairs, with one left out of this layer.
  3. 3One CNOT per pair. Stack the three layers the project ships and no qubit is left holding a state of its own: what the field knows has moved into the correlations between them.
Run on QollabBackend

Fork it and set the layer count to one, then two, then three.

The score does not climb steadily: on an exact simulation it lands near 0.79, 0.67 and 0.79. To ask the sharper question, compare the repaired qubit against the state it was prepared in rather than against its own sharpness.

Quantum Butterfly FieldQuantum Butterfly FieldXinyi Zhang · u/xinyi · Python + QiskitQuantum Butterfly Field is an interactive artwork bridging quantum computing concepts with indigenous epistemologies to explore repair and resilience in an interconnected world.

More than two qubits

Two qubits is the smallest case. With more, they can all share one state, a GHZ state, where every qubit comes out 0 together or 1 together:

ghz_state.py Python · Playground versionOpen in Playground ↗
from qiskit import QuantumCircuit
n = 5
1qc = QuantumCircuit(n, n)
2qc.h(0)
for i in range(n - 1):
3    qc.cx(i, i + 1)
4qc.measure(range(n), range(n))
# All five qubits now share one state: you only ever see |00000⟩ or |11111⟩.
  1. 1Five qubits this time, and five ordinary bits to read them into.
  2. 2Put the first qubit into superposition, exactly as in the Bell state.
  3. 3Then pass it along the line: 0 entangles 1, 1 entangles 2, and so on to the end.
  4. 4Measure all five at once. range(n) is just qubits 0 to 4, read into bits 0 to 4.
Run on QollabBackend

A GHZ state is all-or-nothing: measure any one qubit and the other four are decided with it, and lose one and the rest fall out of the shared state. That fragility is why it is a standard test of a quantum computer, and its correlations are what error correction and precision sensing build on.

Counts show the outcomes, and for a GHZ state they could not be simpler.

You can dig pair correlations out of them by hand, but only in the basis you measured, and reading a whole circuit that way is work. QCFlows draws it directly, as a graph: run a GHZ state through it and every qubit links to every other.

The QCFlows dashboard rendering a circuit as a graph of correlations between qubits
QCFlows draws a circuit's correlations as a live graph. Open the live app.

What survives on real hardware

Every listing above runs in two very different places, and for entanglement the difference is most of the story.

A simulator holds the state as numbers. Ask it for a Bell pair and it hands back the amplitudes, entanglement and all, with nothing left to infer. That is how the 2-qubit visualiser draws what it draws, and it is reading a state, which no quantum computer will ever let you do.

Hardware gives you counts and nothing else, so the Bell state example ends by squeezing what it can out of them.

bell_state.py Python · excerptOpen in Playground ↗
1correlated = counts.get("00", 0) + counts.get("11", 0)
2uncorrelated = counts.get("01", 0) + counts.get("10", 0)
print(f"\nCorrelated (|00⟩+|11⟩): {100*correlated/shots:.1f}%")
print(f"Uncorrelated (|01⟩+|10⟩): {100*uncorrelated/shots:.1f}%")
3if correlated / shots > 0.95:
    print("✓ Strong entanglement confirmed!")
else:
    print("⚠ Noise detected — some uncorrelated outcomes")
  1. 1The two outcomes a Bell state is allowed to produce.
  2. 2The two it is not. On an ideal simulator this comes out zero every single time.
  3. 3A threshold picked by hand. Below it, the device has leaked more shots into the impossible outcomes than this example is willing to call clean.
Run on QollabBackend

Be exact about what that threshold establishes, because the second-basis test above is the tool for checking it. 01 and 10 are impossible for a Bell state. Every shot that lands there came from the device rather than from the circuit, so the percentage is a noise reading and a useful one.

What it cannot establish is entanglement. A pair of gloves clears 95% correlated as comfortably as a Bell pair does. That is the gloves problem from the top of this page, and a single basis cannot separate the two. Confirming entanglement takes the second-basis run, which is another job on the machine.

Which is the honest answer to why you would use hardware at all. A simulator hands you a flawless Bell pair every time. So it can never tell you the one thing you want to know about a real device: how much entanglement is left by the time the circuit ends. A GHZ state across five qubits is a standard benchmark for that reason. Entanglement is the first thing noise takes, which makes it the most sensitive thing on the machine to count.

Why a device hands you a tally and never a state is a subject of its own, and Understanding Quantum Measurement is the article about it.

Start with two qubits

Every project on this page uses the same ingredient: an entangling operation on qubits that then share one state. The game, the body, the garden, the music, the butterflies and the two visualisers each do something different with it. They also differ in how much of it their measurements let you see.

The Bell state is the smallest version, two gates and a measurement, and the second-basis check above is what separates it from a pair of gloves. Each project shows the line where the entangling happens, or the line where one added gate would start it, so you can change it.

Run it, then build on it.

Fork the Bell state, run it, and watch the two qubits agree. Then open any project above and see the same idea doing something else. Everything here is open and yours to build on.

Stay in the loop.

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