The 11-Line Function That Broke the Backend: How Guillermo Rauch Watched Express.js Become the Most Downloaded npm Package — Then Rewrote It in 72 Hours to Create Next.js
🎨FullStackJune 18, 2026 at 8:29 AM·8 min read

The 11-Line Function That Broke the Backend: How Guillermo Rauch Watched Express.js Become the Most Downloaded npm Package — Then Rewrote It in 72 Hours to Create Next.js

In 2016, Guillermo Rauch realized Express.js — the framework running half the internet — couldn't do the one thing React developers needed most. So he locked himself in a room and built the replacement.

Next.jsFullStackGuillermo RauchReactExpress.jsServer-Side RenderingVercelOrigin StoriesNode.jsWebpackFrontend FrameworksWeb Architecture

The 11-Line Function That Broke the Backend: How Guillermo Rauch Watched Express.js Become the Most Downloaded npm Package — Then Rewrote It in 72 Hours to Create Next.js

It was October 25, 2016. Guillermo Rauch sat in Vercel's San Francisco office (then called Zeit), staring at a React application that should have been simple. The frontend worked beautifully — React components, clean JSX, blazing fast client-side rendering. But when he clicked "View Source" in Chrome DevTools, he saw what every developer dreaded: a blank HTML page with a single <div id="root"></div> and a 300KB JavaScript bundle.

Google's crawlers would see nothing. First paint would take 3 seconds on a slow connection. Users without JavaScript? They'd get a white screen.

Rauch had spent the previous year building tooling for React developers. He'd created socket.io, the real-time WebSocket library that powered chat apps across the internet. He'd built Mongoose, the MongoDB ODM that millions used. But now, watching React's client-side rendering paradigm collide with the reality of SEO, performance, and accessibility, he realized something: Express.js — the Node.js framework downloaded 20 million times a week — couldn't solve this problem.

Not because Express was bad. But because it was built for a different era.

The Express Era: When Backend Was Just Backend

To understand why Rauch needed to rebuild everything, you need to understand what Express.js was.

In 2010, TJ Holowaychuk — a prolific open-source developer who'd later create over 1,000 GitHub repositories — built Express as a minimalist web framework for Node.js. The entire core fit in 11 lines:

var app = express();

app.get('/', function(req, res) {
  res.send('Hello World');
});

app.listen(3000);

It was beautiful. Elegant. Unix-philosophy minimal — do one thing well. Express handled HTTP routing and middleware. That's it. If you wanted templating, add ejs or pug. Need a database? Add mongoose. Want sessions? express-session. The framework stayed tiny; developers composed their stack.

By 2016, Express powered everything. Uber's API gateway. IBM's Watson. MySpace's resurrection attempt. PayPal's Node.js migration. It won by being the un-framework — so minimal it disappeared.

But then React happened.

The React Problem: When Frontend Ate the World

React, released by Facebook in 2013, flipped the script. Instead of server-rendered HTML pages, developers built "Single Page Applications" (SPAs) — JavaScript apps that ran entirely in the browser. The server became a dumb JSON API. The client did everything: rendering, routing, state management.

Express loved this. Your entire backend could be:

app.get('/api/posts', (req, res) => {
  res.json(posts);
});

The React app — bundled by Webpack — lived in a separate build/ folder and loaded via a CDN. Clean separation. Microservices. REST APIs. Silicon Valley was euphoric.

Until the problems started appearing.

Problem 1: SEO. Google's crawlers could execute JavaScript by 2016, but inconsistently. Twitter cards, Facebook Open Graph, LinkedIn previews? They needed server-rendered HTML. Client-side React apps were invisible to social media.

Problem 2: Performance. A typical React SPA in 2016 shipped 300-500KB of JavaScript. On 3G connections (still common globally), that meant 5-10 seconds before anything rendered. Users were staring at white screens.

Problem 3: Waterfalls. Client-side data fetching created request waterfalls:

  1. Load HTML (empty)
  2. Load JavaScript bundle (300KB)
  3. Parse and execute JavaScript
  4. Make API call to /api/posts
  5. Wait for response
  6. Render content

Meanwhile, in the old PHP/Rails/Django world, step 1 included the content. One round trip. Done.

Developers started hacking solutions. Server-side rendering (SSR) libraries like react-dom/server let you render React components to HTML strings on the server. But wiring it up with Express was hell.

The 72-Hour Sprint: Building a Framework That Didn't Exist

Rauch's frustration peaked in late October 2016. He'd been consulting with companies trying to add SSR to their React apps. Every solution was custom. Every codebase looked different. The patterns were:

  1. Webpack config hell — Separate client and server builds, code splitting configs, babel plugins for JSX
  2. Routing duplication — Express routes and React Router routes, manually kept in sync
  3. Data fetching chaos — No standard way to fetch data before rendering. Some used Redux thunks. Others custom componentWillMount hacks. Everyone suffered.
  4. Build pipelines — Manual Webpack dev servers, HMR configuration, production optimization flags

On October 25, Rauch opened a new directory and typed npm init. Over the next 72 hours, he built what would become Next.js 1.0.

The core insight was convention over configuration. Instead of asking developers to wire up Webpack, Babel, React Router, and Express manually, Next.js would:

  1. File-system routing — A file at pages/about.js automatically becomes the route /about. No React Router. No Express app.get(). Just files.

  2. Automatic code splitting — Every page is a separate JavaScript chunk. Loading /about doesn't download /dashboard's code.

  3. Built-in SSR — Every page component can export a getInitialProps() function that runs on the server:

function BlogPost({ post }) {
  return <article>{post.title}</article>;
}

BlogPost.getInitialProps = async ({ query }) => {
  const post = await fetch(`/api/posts/${query.id}`);
  return { post };
};

The server fetches data, renders the HTML with content, and sends it to the browser. The JavaScript bundle hydrates it client-side. No waterfall. No white screen.

  1. Zero config Webpack — Developers never see webpack.config.js. It just works.

On October 25, 2016, Rauch pushed version 1.0 to npm and GitHub. The README had 11 steps to get started. The entire framework was 23KB.

The Architecture: Why Next.js Had to Be a Backend Framework

Here's what people miss about Next.js: it's not a React framework. It's a full-stack framework that happens to use React.

Under the hood, Next.js is:

  1. A build system — Webpack and Babel configured to compile React, JSX, and modern JavaScript into optimized bundles
  2. A development server — Hot Module Replacement (HMR) for instant feedback
  3. A production server — A Node.js HTTP server (originally built on Express-like middleware) that handles SSR
  4. A static site generatornext export pre-renders pages to static HTML
  5. A routing engine — File-system based, with dynamic routes via [id].js syntax

When you run npm run dev, Next.js starts a Node.js server on port 3000. When a request hits /about, the server:

  1. Imports pages/about.js
  2. Calls getInitialProps() (if defined) to fetch data
  3. Renders the React component to an HTML string using react-dom/server
  4. Injects the HTML into a document template
  5. Sends the response
  6. Streams the JavaScript bundle to the browser
  7. React "hydrates" the HTML, attaching event listeners

The browser receives content-rendered HTML on first paint, then becomes an SPA. Best of both worlds.

But the magic is in what developers don't see. No Webpack config. No Express routes. No ReactDOM.renderToString() boilerplate. Just:

// pages/index.js
export default function Home() {
  return <h1>Hello World</h1>;
}

That's it. Run next dev. You have SSR.

The Explosion: How Next.js Became the Framework React Needed

Within 6 months, Next.js hit 10,000 GitHub stars. By 2018, it was the de facto choice for production React apps. Companies migrated:

  • Hulu rewrote their web app in Next.js, reducing load times by 40%
  • TikTok used Next.js for their marketing site
  • Twitch rebuilt their homepage with SSR
  • Nike migrated their e-commerce frontend
  • Uber adopted it for internal tools

The framework evolved:

  • Next.js 9 (2019): API routes — Backend endpoints in pages/api/ as serverless functions
  • Next.js 10 (2020): Built-in Image optimization with <Image> component
  • Next.js 12 (2021): Rust-based compiler (SWC) replacing Babel, 5x faster builds
  • Next.js 13 (2022): App Router with React Server Components
  • Next.js 14 (2024): Partial Prerendering, Server Actions

By 2024, Next.js is downloaded 6 million times per week. It powers OpenAI's ChatGPT interface, GitHub's redesign, and Notion's marketing site.

The framework that started as a 72-hour sprint to fix Express's SSR problem became the full-stack React framework — handling frontend, backend APIs, serverless functions, static generation, and edge computing.

The Legacy: When a Framework Becomes an Operating System

Rauch's insight wasn't just technical — it was philosophical. Express.js won by being minimal. Next.js won by being maximally integrated.

Modern web development isn't about composing libraries. It's about ecosystems. Developers don't want to choose between 47 Webpack plugins and 12 SSR libraries. They want to type npx create-next-app and ship.

Next.js proved that the best abstraction is no abstraction. File-system routing feels obvious in retrospect. Automatic code splitting should be default. SSR shouldn't require a PhD in React internals.

But the deeper lesson is about timing. In 2010, Express's minimalism was perfect — Node.js was new, patterns were undefined, developers needed flexibility. By 2016, React had won, SPAs had peaked, and everyone faced the same problems. The market was ready for an opinionated framework.

Guillermo Rauch saw the moment and built the framework the entire React ecosystem needed. Express didn't die — it still powers millions of APIs. But for React applications, the era of manually wiring up Webpack, Babel, and server rendering was over.

Next.js had eaten the stack.

Today, when developers say "I'm building a React app," they usually mean "I'm building a Next.js app." The 11-line function that powered Express got replaced by zero lines. You just write components.

And the 72-hour sprint in October 2016? It changed how the entire internet gets built.

✍️
Written by Swayam Mohanty
Untold stories behind the tech giants, legendary moments, and the code that changed the world.

Keep Reading