DEV Community

Alex Spinov
Alex Spinov

Posted on

Million.js Has Free React Optimization — Here's How to Make React 70% Faster Without Changing Your Code

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
Enter fullscreen mode Exit fullscreen mode
// next.config.js (Next.js)
import million from 'million/compiler';

export default million.next({ auto: true });
Enter fullscreen mode Exit fullscreen mode
// vite.config.ts (Vite)
import million from 'million/compiler';

export default defineConfig({
  plugins: [million.vite({ auto: true }), react()],
});
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
  );
});
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Linting (Catch Issues)

// eslint config
import { rules } from '@million/lint';

export default {
  plugins: { million: rules },
  rules: {
    'million/no-unnecessary-renders': 'warn',
  },
};
Enter fullscreen mode Exit fullscreen mode

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)