The World of Pyrotechnics

I have spent the past year working through the chemistry of fireworks, starting with a Royal Institution lecture on colored flames. That turned into a browser-based fireworks simulator with 108 named effects, built from canvas and JavaScript. This post covers where fireworks came from, why they burn in specific colors, and the method the simulator uses to decide what fires next.


History

Gunpowder was discovered by accident. Sometime around the 9th century, during China's Tang Dynasty, Taoist alchemists were trying to make an elixir of immortality. Instead they made a mixture of charcoal, sulfur, and potassium nitrate that burned violently (Needham, 1986). The first use was simple noise. People packed the powder into bamboo tubes and threw them into a fire. The bang was loud enough, they believed, to scare away evil spirits.

By the Song Dynasty (960 to 1279), the technology had developed into aerial shells and early military use. What it had not developed yet was color. Early fireworks glowed orange, gold, and white, just from the heat of the burning powder. It is the same reason a sparkler glows, no matter what metal is inside it. The reds, greens, and blues we now connect with fireworks came later, from Italy in the 1830s, when pyrotechnists started to use potassium chlorate instead of potassium nitrate as the oxidizer. Chlorate burns cooler. This let the light from the metal salts come through, instead of being buried under the glow of the burning powder.

China still produces most of the world's fireworks, commonly put at around 90% of global output. Most of that comes from Liuyang, a city in Hunan province. Liuyang has been making fireworks for well over 1,000 years, sometimes the number given is 1,400, and on its own it makes something like 60% of the world total.

Share of global fireworks production
China (total)
~90%
Liuyang alone
~60%
Rest of world
~10%

Two records give a sense of the range the industry covers today. The largest single aerial shell ever fired weighed 2,797 pounds. It was launched in Steamboat Springs, Colorado, in February 2020 (Guinness World Records, 2020). Dubai's 2014 New Year display, at the other end, fired 479,651 shells in six minutes. This is still the record for the fastest rate ever achieved (Guinness World Records, 2014).


The physics and chemistry of color

Color in fireworks comes from atomic emission. Heat from the burning shell excites electrons in a metal atom to a higher energy level. As each electron falls back down, it releases the extra energy as a photon at a wavelength specific to that element's structure. Different metal, different wavelength, different color.

This is a separate mechanism from the orange-yellow glow of an ordinary wood fire. That glow comes from incandescence. It is just tiny carbon particles in the flame, glowing the way any object glows once it gets hot enough, no matter what it is made of.

Each firework shell contains stars. These are small pressed pellets made of a metal salt, fuel, and oxidizer. The metals used each have their own narrow, well-documented emission range.

  • Sodium gives yellow. It is a doublet centered at 589 nm, precise enough that this line works as a calibration reference in spectroscopy.
  • Strontium gives red, roughly 600 to 690 nm.
  • Barium gives green, roughly 505 to 535 nm.
  • Copper gives blue, roughly 420 to 460 nm, from copper(I) chloride. This is one of the only practical ways to get a true blue flame, so blue is the hardest firework color to make well.
  • Potassium gives a faint violet. Its main emission line sits close to 760 nm, near the edge of visible light, so the color is weak and easy to hide under a little sodium.

Purple isn't a single-element color. It comes from combining strontium and copper stars in the same shell. What is visible is just the sum of two separate emission sources, not one compound. The color that comes out of a shell is fixed by which stars went into it (Conkling & Mocella, 2010).


Weighted random sampling

The simulator has 108 named effects. Picking one at random with equal probability would make an elaborate, rare effect show up exactly as often as a common one, which is not how a real display looks and reads as wrong.

Instead, each effect carries a weight. The chance that any one effect fires is its weight divided by the sum of all 108 weights.

To make the actual choice, the simulator draws one random number between 0 and the total weight. Then it works down the list of effects, taking away each one's weight from that number until it drops to zero or below. Whichever effect it lands on is the one that fires. This is a standard way to sample from a weighted, or categorical, distribution. In computer science this is sometimes called roulette-wheel selection. It needs exactly one random draw, no matter how many effects are on the list.

The same technique sits underneath two different systems. One is a recommendation system, choosing which item to show next from a set of weighted candidates. The other is a language model, choosing its next word by sampling from a probability distribution over its vocabulary, usually after adjusting that distribution with a temperature parameter. The weights come from different places in each case, but the sampling step is the same piece of math.


Building the simulator

The simulator is a browser-based particle system built with canvas and JavaScript. Clicking anywhere fires a single shell. Holding the mouse down switches to sustained-fire mode, launching a new shell roughly every 160 milliseconds (150 on touch devices), with the horizontal position jittered slightly around the hold point.

A firework icon opens a searchable list of all 108 effects, for picking one directly instead of leaving it to the weighted draw. Typing text into the input field launches each character as its own shell, spelling the word out across the sky one letter at a time.

There is also a day/night toggle. It changes the lighting, the background, and which effects are eligible to fire. A handful of effects were made for the day mode. All of the sound is made right in the browser with the Web Audio API. It uses oscillators, gain envelopes, and filters, not recorded audio files. Click the canvas to launch. Hold for sustained fire.

I spent more time on this than I expected, which is what tends to happen when the reading starts being more interesting and influences me to make a project. I also added some I just experiemented with, and looked cool... not sure if they even exist in the real life, but they exist here. I am still reading more about pyrotechnics here and there, and plan to add more unique ones to the project.


References

  • Needham, J., with Ho Ping-Yü, Lu Gwei-Djen, and Wang Ling. (1986). Science and Civilisation in China, Vol. 5: Chemistry and Chemical Technology, Part 7: Military Technology: The Gunpowder Epic. Cambridge University Press.
  • Conkling, J. A., & Mocella, C. (2010). Chemistry of Pyrotechnics: Basic Principles and Theory (2nd ed.). CRC Press.
  • Guinness World Records. (2020). Largest aerial firework shell.
  • Guinness World Records. (2014). Largest fireworks display.
  • Production and export figures on China and Liuyang per Xinhua News Agency / Global Times reporting (2025) and the Liuyang Fireworks Association.