React's virtual DOM is slow for large lists. Million.js replaces it with a faster one — without changing your components.
What is Million.js?
Million.js is a drop-in virtual DOM replacement for React that makes rendering up to 70% faster. It works by using a compiler to optimize your components.
Quick Start
bun add million
bun add -d @million/lint
// next.config.js (Next.js)
import million from 'million/compiler';
export default million.next({ auto: true });
// vite.config.ts (Vite)
import million from 'million/compiler';
export default defineConfig({
plugins: [million.vite({ auto: true }), react()],
});
That is it. With auto: true, Million.js automatically optimizes your components.
How It Works
React's virtual DOM diffs the entire tree on every render. Million.js uses static analysis to skip the diff for parts that cannot change.
React: Render → Full vDOM diff → DOM update
Million.js: Render → Skip static parts → Targeted DOM update
Manual Optimization with block()
import { block } from 'million/react';
const UserCard = block(({ name, email, avatar }: UserCardProps) => {
return (
<div className="card">
<img src={avatar} alt={name} />
<h3>{name}</h3>
<p>{email}</p>
</div>
);
});
For Large Lists (where it shines)
import { For } from 'million/react';
function UserList({ users }: { users: User[] }) {
return (
<For each={users}>
{(user) => (
<div key={user.id} className="user-row">
<span>{user.name}</span>
<span>{user.email}</span>
<span>{user.role}</span>
</div>
)}
</For>
);
}
The <For> component uses a faster list diffing algorithm optimized for common operations (append, prepend, swap, remove).
Performance Benchmarks
Rendering 10,000 rows:
React: 2,100ms
Million.js: 630ms (70% faster)
Updating 1,000 rows:
React: 450ms
Million.js: 135ms (70% faster)
Swapping rows:
React: 180ms
Million.js: 54ms (70% faster)
Linting (Catch Issues)
// eslint config
import { rules } from '@million/lint';
export default {
plugins: { million: rules },
rules: {
'million/no-unnecessary-renders': 'warn',
},
};
When to Use Million.js
- Large lists and tables (100+ rows)
- Data-heavy dashboards
- Real-time updating UIs
- Any React app where rendering is the bottleneck
When NOT to Use
- Simple apps (React is fast enough)
- Components with complex state logic
- Components that use refs heavily
Million.js vs Alternatives
| Approach | Effort | Speedup |
|---|---|---|
| Million.js | Drop-in | Up to 70% |
| React.memo | Manual per component | 10-30% |
| useMemo/useCallback | Manual per value | 5-20% |
| Virtualization | Architectural change | 90%+ for lists |
Building data-heavy React dashboards? Check out my Apify actors — fast data extraction for fast UIs. For custom solutions, email spinov001@gmail.com.
Top comments (0)