Skip to content

fast-balanceExact chemical equation balancer

Integer/rational arithmetic, redox, charges, hydrates, isotopes and nuclear mode — with no floating-point error.

fast-balance

Exact, never approximate

Conservation systems are solved with BigInt rational arithmetic, so coefficients are always the smallest exact integers.

Real chemical notation

Nested ()/[], ionic charges, hydrates, unicode sub/superscripts, isotope and nuclear notation, functional groups.

Honest about ambiguity

Spectator species are handled, genuinely underdetermined systems report every independent balance, and unknown symbols are rejected with a clear code.

Linear-time core

The element set is validated and bounded, so balancing is O(n) in the number of species. Zero runtime dependencies.

Why fast-balance ​

Most balancers compute a nullspace in floating point and round the result. That fails quietly on large or stiff systems. fast-balance solves the conservation system over exact BigInt rationals and re-verifies conservation before it returns anything.

fast-balanceTypical balancer
ArithmeticExact BigInt rationalsFloating point
Large systemsExact at any sizeSilent rounding errors
Duplicate / spectator speciesBalancedOften rejected
Underdetermined systemsMinimal solution + balanceAllArbitrary or error
Unknown symbolsTyped UNKNOWN_ELEMENT errorSilent misparse
ComplexityO(n) in speciesO(n³)-ish dense Gauss–Jordan

Design guarantees ​

  • Every returned equation is re-checked for element and charge conservation.
  • Coefficients are primitive positive integers (divided by their GCD).
  • No silent guessing — ambiguous or unsupported notation raises a typed error with a stable .code.
  • Deterministic — the same input always returns the same result.

A note on the palette ​

The site uses one flat color drawn from verdigris — the green-teal patina that forms on weathered copper (basic copper carbonate and copper acetate). It is tuned separately for light and dark mode, with no gradients, glass or glow.

Quick examples ​

javascript
import { balance, balanceAll, isBalanced, audit } from "fast-balance";

balance("H2 + O2 -> H2O").equation;
// "2 H2 + 1 O2 -> 2 H2O"

// spectator species are handled, not rejected
balance("C3H8 + O2 + N2 -> CO2 + H2O + N2").equation;
// "1 C3H8 + 5 O2 + 1 N2 -> 3 CO2 + 4 H2O + 1 N2"

// underdetermined systems return the minimal balance and are flagged
balance("C + O2 -> CO + CO2");
// { underdetermined: true, equation: "3 C + 2 O2 -> 2 CO + 1 CO2" }

balanceAll("C + O2 -> CO + CO2").map((r) => r.equation);
// ["3 C + 2 O2 -> 2 CO + 1 CO2", "4 C + 3 O2 -> 2 CO + 2 CO2"]

// unicode input works
balance("H₂ + O₂ -> H₂O").equation;

// diagnostic helpers
isBalanced("H2 + O2 -> H2O"); // true
audit("H2 + O2 -> H2O"); // element/charge totals per side

Installation ​

bash
npm install fast-balance

Modern runtimes import from the package root. Pre-ES2020 / ES3 engines use fast-balance/legacy (same API, same results) — see Installation for details.

Behavior is pinned by 11 459 hand-written test cases covering every element, the combustion and oxidation ladders, notation and parsing, the solver internals, the error contract, nuclear mode, and field-by-field parity between the native and ES3 backends.

Explore ​

Released under the MIT License.