# Million.js — Make React 70% Faster with a Compiler-Driven Virtual DOM
> Million.js compiles React components into an optimized block-based virtual DOM. By analyzing your JSX at build time, it avoids unnecessary diffs and delivers up to 70% faster renders on list-heavy UIs — with zero changes to most components.
## Install
Save in your project root:
# Million.js — Faster React via Compiler-Driven VDOM
## Quick Use
```bash
npm install million
npx million@latest # auto-install config for Vite/Next/etc.
```
```tsx
import { block } from "million/react";
const Row = block(function Row({ user }) {
return
| {user.name} | {user.email} |
;
});
export default function Table({ users }) {
return ;
}
```
## Introduction
React's virtual DOM does a lot of work you don't always need. Million.js tackles this with a compiler that replaces hot paths with "blocks" — pre-analyzed VDOM fragments where only dynamic slots are diffed. The result is measurably faster rendering on large lists and tables, with the same React component model.
With over 18,000 GitHub stars, Million.js is used by Wyze, Cal.com, and hundreds of React apps where DOM-heavy UI has become the bottleneck. The `block()` HOC opts individual components into the faster path.
## What Million.js Does
Million.js provides a Babel/SWC/Vite plugin that statically analyzes JSX. Components wrapped in `block()` are compiled to a `Block` representation that bypasses most reconciliation — static nodes are hoisted, dynamic slots are tracked individually. Runtime diffing becomes a fast, focused operation.
## Architecture Overview
```
JSX source
|
[Million Compiler plugin] (Babel/SWC/Vite)
|
Classifies components:
+-- wrapped in block(): compiled to Block VDOM
+-- unwrapped: regular React
|
Runtime: Million "virtual DOM in a virtual DOM"
- Static parts skipped
- Dynamic slots indexed for fast diff
- Minimizes reconciler work for list items
|
React commits with much less effort
```
## Self-Hosting & Configuration
```ts
// vite.config.ts
import { defineConfig } from "vite";
import million from "million/compiler";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
million.vite({ auto: { threshold: 0.05 } }), // auto-block heuristically
react(),
],
});
// next.config.js
const million = require("million/compiler");
module.exports = million.next({ auto: true })({ /* your next config */ });
```
## Key Features
- **block() HOC** — mark hot components for block compilation
- **auto mode** — compiler detects list-like components automatically
- **Drop-in** — works with existing React codebases
- **Vite/Next/Webpack** — plugins for every major bundler
- **For loop** — `` component for optimized list rendering
- **Selective adoption** — opt-in per component, fallback to React elsewhere
- **TypeScript-first** — full types, no @ts-ignore needed
- **Devtools** — warnings when blocks can't be optimized
## Comparison with Similar Tools
| Feature | Million.js | React Compiler | Preact | Inferno | Solid |
|---|---|---|---|---|---|
| React compatible | Yes | Yes (React 19) | Mostly | Mostly | No (different model) |
| Adoption cost | block() per component | Zero (in React 19) | Aliased react | Similar rewrites | Full rewrite |
| Speed gain | 30–70% list-heavy | Varies | Minor | Large | Largest |
| Bundler plugin | Required | Built-in React 19 | None | None | None |
| Best For | Perf-critical React apps | New React codebases | Bundle-size reduction | Niche | New greenfield |
## FAQ
**Q: Is Million.js still relevant with the React Compiler?**
A: React Compiler (shipping in React 19) focuses on automatic memoization. Million.js targets VDOM reconciliation overhead — different problem. For very large list rendering, Million still offers unique wins.
**Q: Will block() break my existing React code?**
A: Usually not. There are some constraints: no conditional hooks inside blocks, no dynamic element types in hot paths. The compiler warns if a component can't be blockified.
**Q: Do I need to wrap every component?**
A: No — use `auto: true` to let the compiler pick list components heuristically. Start there and only wrap specific leaf components manually if you need more.
**Q: What frameworks does Million.js support?**
A: React today; a Million core exists for non-React use but the ecosystem is React-focused.
## Sources
- GitHub: https://github.com/aidenybai/million
- Docs: https://million.dev
- Author: Aiden Bai
- License: MIT
---
Source: https://tokrepo.com/en/workflows/dc83ee9f-37be-11f1-9bc6-00163e2b0d79
Author: AI Open Source