The No-Math AI: Deconstructing chenglou/mnist

How a React pioneer built a digit classifier without neural networks, backpropagation, or a single machine learning dependency.

6 min read · chenglou/mnist

A massive mechanical brain hooked to cables beside a small hand-cranked wooden sorting box. This illustrates the contrast between complex modern machine learning and the simple, minimalist approach of the chenglou/mnist project.
Modern machine learning relies on massive scale, while this project treats classification as a simple, hand-cranked sorting problem.

Got MNIST training in ReasonML! It's actually surprisingly fast. It was a fun weekend project to see how ergonomic it would be to write neural networks in Reason.

Cheng Lou, Creator · Cheng Lou's X/Twitter Post
Key Takeaways

The Illusion of Intelligence

Modern machine learning is dominated by massive tensor operations, gigabytes of dependencies, and black-box neural networks. The standard approach to the MNIST digit classification problem involves PyTorch, CUDA, and complex backpropagation algorithms. In contrast, Cheng Lou built a digit classifier using nothing but vanilla TypeScript and bitwise comparisons. The repository contains just six files and zero machine learning libraries. It establishes a radical premise. Recognition at its lowest level is just a linear search problem.

Cheng Lou, creator of the project.

Pattern Matching Without the Math

The core classification engine abandons neural networks entirely. Instead of calculating weights and biases through gradient descent, the system uses a simple reward and penalty mechanism. It compares a noisy input grid against hardcoded perfect examples of digits zero through nine. If a pixel matches the reference (both on or both off), it adds a point. If it does not match, it subtracts a point. This pseudo-Hamming distance algorithm turns visual recognition into basic accounting.

function scoresForGuess(guess: number[]): number[] {
  // ...
  if (number[i] === guess[i]) {
    scoreSoFar++
  } else {
    scoreSoFar--
  }
}

The classification engine relies on a simple +1/-1 running tally instead of complex neural network weights.

Deterministic Chaos in the DOM

To test the classifier, the system needs noisy data. Instead of using standard randomized functions, the project employs a custom hash function commonly found in graphics and shader programming. This ensures that the generated visual noise is perfectly deterministic. Every time you refresh the page, the exact same pattern of randomness appears. This approach guarantees that visual debugging remains consistent across test runs.

A close-up of a magnifying glass hovering over a grid of black and white square tiles, with a vintage accountant's ledger book nearby. This represents the precise, accounting-like nature of the deterministic scoring algorithm.
Pattern matching is reduced to basic accounting, tallying matches and mismatches pixel by pixel.

The Zero-Dependency Canvas

Despite the author's pedigree in React architecture, the user interface is built entirely with vanilla document object model manipulation. There are no frontend frameworks. Elements are created manually, and CSS grid styling is applied directly via TypeScript. Running on Bun for maximum performance, the repository stands as a masterclass in minimalism. It proves that fundamental computer science concepts can be demonstrated powerfully without standing on the shoulders of massive software ecosystems.

FeatureMainstream MLchenglou/mnist
Core LogicBackpropagation & WeightsHamming Distance (+1/-1)
Input Data28x28 Grayscale Tensors10x10 Binary Arrays
RandomnessNon-deterministicDeterministic shader hash
DependenciesPyTorch, CUDA, NumPyZero dependencies