Skip to content

Rob Pike's 5 Programming Rules From Today Still Work

Rob Pike wrote 5 rules of programming in 1989 at Bell Labs. Why they still apply to TypeScript, React, and modern frontend in 2026.

· · 6 min read

Updated: March 30, 2026

Dark screen filled with colorized source code representing timeless programming principles

Quick Take

Rob Pike wrote five programming rules at Bell Labs in 1989: measure before optimizing, don't guess at bottlenecks, write simple algorithms first. They remain the most practical debugging advice in existence and apply unchanged to TypeScript and React in 2026.

Rob Pike typed out five rules of programming sometime around 1989. He was working on Plan 9 at Bell Labs, building operating systems alongside Ken Thompson. The rules showed up in Notes on Programming in C and later spread across Usenet.

That was 37 years ago. I still think about these rules weekly.

Why? Because they address programmer psychology, not technology. Languages change. Frameworks die. But the human urge to write clever code before checking if it's even slow? That's forever.

TL;DR: Pike's 5 rules come down to one principle, don't be clever until the numbers force you to. Measure before optimizing. Keep algorithms simple when N is small (and N is almost always small in web apps). Let your data structures define your code, not the other way around. Every rule applies to TypeScript and React in 2026 exactly as it did to C in 1989.

Rule 1: You Can't Tell Where a Program Spends Its Time

Pike's first rule says bottlenecks happen in surprising places. Don't guess. Measure.

This one hits hard if you've ever spent three hours optimizing a React component that renders twice per page load while a 340KB JSON blob downloads on every route change. I did exactly that on a project last year, rewrote a table component with virtualization, felt great about it, then ran Chrome DevTools and realized the actual bottleneck was an uncompressed API response.

In TypeScript and React apps, the performance problems are almost never where you think. It's not the Array.map() in your JSX. It's the waterfall of useEffect calls, the unoptimized images, or the 14 re-renders triggered by a context provider sitting too high in the tree.

Use React.Profiler. Use performance.mark(). Use Lighthouse. Measure first, then fix what the numbers tell you to fix.

Rule 2: Measure Before Tuning

This extends Rule 1. Don't optimize until you've profiled, and don't even profile until you know there's a problem worth solving.

I've reviewed pull requests where someone replaced a for...of loop with a hand-rolled while loop "for performance." The function ran 6 times total during the entire page lifecycle. Six. The optimization saved maybe 0.002ms and made the code harder to read for every developer after them.

Here's an uncomfortable opinion: most performance work in frontend codebases is theater. People optimize what's visible in the code rather than what's slow in the browser.

Want to actually measure things? Start with npx webpack-bundle-analyzer or your framework's equivalent. When I ran it on a Next.js 14 project, I found moment.js (327KB gzipped) still bundled alongside date-fns (12KB). Removing the duplicate saved more than any code-level optimization could.

A hand holding a digital stopwatch reading zero against a grey background
Photo by Curated Lifestyle on Unsplash

Rule 3: Fancy Algorithms Are Slow When N Is Small

Pike argues that fancy algorithms have big constants. Until your dataset is large, a simple O(n) scan beats a clever O(log n) structure because the overhead of the clever approach dominates.

This rule maps directly to modern frontend work. How many items does your dropdown filter? 50? 200? You don't need a trie or a fuzzy search library weighing 48KB. This is the entire implementation I shipped for a 200-item product filter, and it still runs in under a millisecond on a five-year-old phone:

function filterProducts(products: Product[], query: string): Product[] {
  const q = query.trim().toLowerCase();
  if (!q) return products;
  return products.filter((p) => p.name.toLowerCase().includes(q));
}

No trie, no fuzzy scoring, no dependency. When the dataset stayed under a few hundred rows, that one-liner beat every clever alternative I tried.

The same applies to state management. Do you actually need a full state management library with normalized stores and selectors for an app with three pages? Probably not. useState and useContext carry you further than most people expect.

Most web apps deal with small N, a few hundred DOM nodes, a few dozen API responses, maybe a thousand table rows. At those sizes, readability wins over algorithmic sophistication every time.

Rule 4: Fancy Algorithms Are Buggier Than Simple Ones

Even when N justifies complexity, Pike warns that complicated algorithms are harder to implement correctly. They have more edge cases, more off-by-one errors, more subtle failure modes.

I've watched this play out with TypeScript generics. Someone builds a type-level computation so complex that only they understand it. The TypeScript compiler takes 8 seconds to check the file. A new team member opens it and immediately closes it. Meanwhile, a simpler type with one or two overloads would have covered 95% of the same cases.

The same pattern shows up with CSS Grid layouts. I've debugged grid templates with 6 named areas and minmax() expressions nested three deep that could've been a straightforward flexbox column. Was it worth the 45 minutes the next developer spent trying to add a sidebar? No.

Simple code has a compounding advantage: it's easier to test, review, modify, and delete when requirements change.

Rule 5: Data Dominates

This is my favorite rule. Pike says: "If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident."

Think about how much React code exists just to reshape data that arrived in the wrong format. You get an API response structured one way, your components need it another way, so you write transformers and derived state hooks, all because the data shape was wrong from the start.

When I restructured a dashboard's API to return data already grouped by category instead of as a flat array, I deleted about 180 lines of frontend transformation code. The types got simpler. Two derived state hooks just disappeared. The data was doing the work.

This maps to TypeScript's utility types too. Pick, Omit, Record, these exist because data shape matters. Getting your interfaces right early saves you from writing code that compensates for bad structure later.

Fred Brooks said something similar in The Mythical Man-Month: "Show me your tables, and I won't usually need your flowchart." Pike and Brooks are pointing at the same truth from different decades.

A carefully balanced cairn of smooth stones on a pebble beach
Photo by Jeremy Thomas on Unsplash

Applying Pike's Rules Today

These rules boil down to one meta-principle: fight the urge to be clever. Write the obvious thing. Measure whether it's fast enough. It usually is.

It doesn't mean you should never optimize. It means you should earn complexity through evidence. Profile first. Check your N. Keep your data structures clean.

If you're working in TypeScript 7 or React 19 or whatever comes next, the tools will keep changing. Pike's rules won't. The temptation to prematurely optimize has been constant since at least 1989, and probably since Knuth first warned about it in 1974.

Write boring code. Measure it. Fix what's actually slow. Trust your data structures. That's the whole playbook, and it hasn't needed an update in 37 years.

Frequently Asked Questions

What are Rob Pike's 5 Rules of Programming?
They cover measurement before optimization, avoiding fancy algorithms unless data proves you need them, using simple data structures, letting data shape your code, and writing straightforward programs first before trying to be clever.
Are Rob Pike's rules still relevant for modern languages like TypeScript?
Yes. The rules address human tendencies like premature optimization and over-engineering, which haven't changed since 1989. TypeScript, React, and Go codebases all benefit from the same principles.
How do Rob Pike's rules relate to Donald Knuth's optimization quote?
Pike's Rule 1 and Rule 2 echo Knuth's famous line that premature optimization is the root of all evil. Both argue you should measure before optimizing and keep code simple until profiling tells you otherwise.
Who is Rob Pike and why should programmers listen to him?
Rob Pike co-created Unix, Plan 9, UTF-8, and the Go programming language at Bell Labs and later Google. His decades of systems programming experience shaped these rules.