Engineering Philosophy: Thompson & Ritchie, Do One Thing Well

Ken Thompson (seated) and Dennis Ritchie at a PDP-11 at Bell Labs

Key Takeaways

  • Small, sharp tools. Each program does one thing well and resists doing a second; new needs get a new tool, not another flag.
  • Composition over features. Power comes from joining programs through the universal text interface – pipes – so capability emerges in the seams, not inside any one program. The canonical “do one thing well” statement is Doug McIlroy’s, not Thompson’s or Ritchie’s.
  • Portability through C. Rewriting Unix in C let it move to new hardware by porting a compiler instead of rewriting the system – most of why Unix spread everywhere.
  • Trust nothing you didn’t build. Thompson’s “Reflections on Trusting Trust” shows a backdoor can live in the binary with no trace in any source you inspect – the founding insight of supply-chain security.

The Principle

“Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.” – Doug McIlroy, summarizing the Unix philosophy1

That sentence is not Thompson’s and not Ritchie’s. It was written by Doug McIlroy, their colleague at Bell Labs and the man who invented the Unix pipe, in his foreword to the 1978 special issue of the Bell System Technical Journal.1 But it is the cleanest statement of the thing Thompson and Ritchie actually built, and the reason to lead with it rather than a line of either man’s own is itself the point: the Unix philosophy was never a manifesto authored by a single genius. It was a culture, and the culture was the artifact.

The principle has three moves and they are inseparable. Make each tool small and sharp – one job, done well, with no ambition to do a second. Make the tools composable – the output of one is the input of the next, so capability comes from combination rather than from any program growing large. And make the interface between them universal – plain text, so that any tool can be joined to any other without either knowing the other exists. The power lives in the seams, not the parts. A program that sorts lines knows nothing about web logs; a program that counts duplicates knows nothing about HTTP status codes; joined by a pipe, they answer a question neither was built to answer.

This is the opposite of the instinct that produces most software. The natural pull is to make one program do more – add a flag, add a mode, fold the next requirement into the thing you already have. McIlroy’s first rule names that pull and refuses it: “To do a new job, build afresh rather than complicate old programs by adding new ‘features’.”1 Thompson and Ritchie’s whole system is the case that simplicity is the precondition for everything else, and that composition – not features – is how small things become powerful.

Context

Unix was born out of a failure. Through the mid-1960s, Bell Labs had partnered with MIT and General Electric on Multics, an enormously ambitious time-sharing operating system meant to do nearly everything. By 1969 it had grown so complex and so late that Bell Labs withdrew, and the researchers who had worked on it – Ken Thompson, Dennis Ritchie, Doug McIlroy, Joe Ossanna – were left frustrated, with the loss of a comfortable interactive computing environment and a strong sense of how not to build a system.2

Dennis Ritchie, creator of the C programming language

Ken Thompson, born February 4, 1943, in New Orleans, had joined Bell Labs in 1966 after a BS and MS in electrical engineering and computer sciences at UC Berkeley.3 Dennis Ritchie, born September 9, 1941, in Bronxville, New York, joined the Computing Sciences Research Center in 1967.4 In 1969 Thompson found a cast-off PDP-7 – a small, by-then-obsolete minicomputer – and began building a tiny operating system on it, in part to run a game he had written called Space Travel. Thompson later put the division of labor plainly: “I did the first of two or three versions of UNIX all alone. And Dennis became an evangelist.”3 The first version was written in PDP-7 assembly.

The name came as a joke. Where Multics was “Multiplexed,” the new system was deliberately small, so the group called it “UNICS” – Uniplexed Information and Computing Service – a pun at Multics’s expense. The spelling drifted to “Unix,” and Brian Kernighan, usually credited with the name, later noted that no one can quite remember how the final form emerged.2 The smallness was not an accident or a limitation to be outgrown. It was the design.

The Work

Unix and the File System

The first thing Unix got right was a model of what a computer’s resources are. Earlier systems treated files, devices, and communication channels as different kinds of things, each with its own special interface. Unix collapsed them. It presented a single hierarchical file system – a tree of directories – and then treated nearly everything as a file within it: not just documents but devices, and inter-process communication channels too.2 A program that could read from and write to a file could, without changing, read from a terminal or a tape drive or another program, because to the program they were all just files.

This is the universal interface in its first form. “Everything is a file” means a small tool does not need a different version for every kind of input; it needs one. The cost of composition drops to nearly zero, because every component already speaks the same language. The hierarchical file system and the uniform open/read/write/close interface are why the rest of the philosophy was even possible: you cannot compose tools that each demand a bespoke connector.

C and Portability

The second breakthrough was making the system portable, and that required a language. Ritchie created C between 1969 and 1973, evolving it from Thompson’s B language, which had in turn descended from BCPL.4 B was typeless and interpreted; C added data types and structures and compiled to efficient machine code, close enough to the hardware to write an operating system in, abstract enough to move between machines.

The decisive moment came around 1973, when Version 4 Unix was rewritten in C.2 Until then, an operating system was assembly language, welded permanently to the one machine it was written for. Rewriting Unix in a high-level language was close to heresy – conventional wisdom said system code had to be hand-tuned assembly or it would be too slow. Thompson and Ritchie did it anyway, and the payoff was portability: Unix could now be moved to new hardware by porting a compiler rather than rewriting the entire system. That single decision is most of the reason Unix spread to every corner of computing while its contemporaries stayed bolted to their original iron. In 1978, Ritchie and Kernighan published The C Programming Language – “K&R” – the spare, exact book that taught a generation to write C and remains a model of technical prose.5 Thompson and Ritchie announced the system itself to the wider world in the July 1974 Communications of the ACM paper “The UNIX Time-Sharing System.”6

Pipes and the Composition Model

Ken Thompson, co-creator of Unix

If the file system made tools speak the same language, pipes made them talk to each other. The idea was Doug McIlroy’s: for years he had pushed for a way to connect programs end to end, the output of one flowing directly into the next, like sections of garden hose. Thompson implemented it in 1973 – famously in a single night – adding the pipe() system call and the | operator to the shell.7 McIlroy described what happened next: “The next day saw an unforgettable orgy of one-liners as everybody joined in the excitement of plumbing.”7

That orgy of one-liners is the philosophy in action. Nobody had to write a new program; they discovered that the small programs they already had could be strung together to answer questions none of them had been designed for. A pipeline like grep then cut then sort then uniq -c then sort -rn then head is built from six stages, each ignorant of the others, each doing one thing, composed left to right through a stream of text. The capability is emergent. It lives in the |, not in any single command.

This is the deepest idea in the whole system. Most software grows by accretion: a program absorbs each new requirement until it is a monolith only its authors understand. Unix grows by composition: the system stays a kit of small parts, and new capability comes from new arrangements of old parts. The text stream is the universal interface that makes the arrangement free. It is why a Unix shell, fifty years on, is still one of the most expressive programming environments in existence – not despite being made of tiny single-purpose programs, but because of it.

Trusting Trust and the Later Legacy

In 1983 Thompson and Ritchie shared the ACM Turing Award. The citation reads “for their development of generic operating systems theory and specifically for the implementation of the UNIX operating system,” and the committee’s statement names the principle exactly: “The success of the UNIX system stems from its tasteful selection of a few key ideas and their elegant implementation.”8 Tasteful selection of a few key ideas – the award was, in effect, given for restraint.

Thompson’s own Turing lecture, published in 1984 as “Reflections on Trusting Trust,” turned the same minimalist rigor on security. He demonstrated that a compiler could be taught to insert a backdoor into the login program, and to insert the backdoor-insertion into any future compiler it compiled – so the malicious code lived only in the binary, with no trace left in any source you could inspect. His conclusion is one of the most-cited sentences in computing: “You can’t trust code that you did not totally create yourself… No amount of source-level verification or scrutiny will protect you from using untrusted code.”9 It is the founding text of supply-chain security thinking – the recognition that the thing you trust is not the source but the entire toolchain that produced the binary.

The pair’s later careers extended the same instincts. Thompson stayed restless: at Bell Labs he built the Plan 9 operating system (pushing “everything is a file” even further, across a network), the ed editor, and the practical theory of regular expressions and grep. In 1992 he and Rob Pike designed UTF-8 – the variable-width text encoding that now carries nearly all the world’s text – on a single evening, famously sketched on a placemat.3 And in 2007, at Google, Thompson co-designed the Go programming language with Robert Griesemer and Rob Pike, publicly announced in 2009: a deliberately small, fast-compiling, composable language that reads like a conscious return to Unix values.10 Ritchie, who died on October 12, 2011, left a quieter but more pervasive mark; as the historian Paul Ceruzzi put it, “if you had a microscope and could look in a computer, you’d see his work everywhere inside.”4

The Method

The method is consistent across forty years and two men who rarely needed to explain it.

Build small, sharp tools. Each program does one job. The discipline is refusal: when a new need appears, the answer is a new tool, not a new flag bolted onto an old one. “Build afresh rather than complicate old programs.”1

Compose rather than accrete. Capability is meant to emerge from combination. A system stays comprehensible when it is a kit of small parts and grows by rearrangement, not by any part swelling into a monolith.

Standardize the interface, not the tools. The unifying move – “everything is a file,” plain text streams between programs – is to make the connection universal so the components can stay ignorant of one another. Cheap seams are what make small parts powerful.

Choose a few key ideas, tastefully. The Turing committee’s phrase was not flattery; it was the method. Unix is famous for what it left out. Portability via C, the file abstraction, the pipe – a handful of decisions, each carrying enormous weight, with the clutter deliberately absent.

Distrust what you cannot inspect. “Trusting Trust” is the method aimed inward: simplicity and legibility are not only aesthetic virtues but the only real basis for trust, because complexity is where the things you cannot see can hide.

Influence Chain

Who Shaped Them

Multics, by counterexample. The single most formative influence was a system they helped build and then walked away from. Multics taught Thompson and Ritchie, in the most expensive way possible, what overambition costs – and Unix is in large part a disciplined reaction against it. (Formative influence)

Doug McIlroy. Head of the Computing Sciences Research Center, McIlroy invented the pipe, articulated the “do one thing well” philosophy in writing, and acted as the group’s relentless taste critic. The composition model is as much his as anyone’s, and he is the correct attribution for the philosophy’s canonical statement. (Direct influence)

The Bell Labs research culture. A small group of peers, given freedom and good machines, optimizing for elegance among themselves rather than for a product roadmap. Unix was not specified by management; it accreted from a culture that valued the tasteful and ridiculed the bloated. (Formative influence)

Who They Shaped

Every Unix descendant. Linux, the BSDs, and macOS are direct lineal heirs; the system Thompson and Ritchie wrote on a cast-off PDP-7 now runs most of the servers, phones, and embedded devices on Earth.

Every shell and command line. The pipe and the composition model are the daily working environment of essentially every programmer and system administrator, fifty years on – unchanged in their essentials because the essentials were right.

C and its children. C became the lingua franca of systems programming, and its syntax and semantics echo through C++, Java, Go, Rust, and most of what is written today. K&R remains the template for how to document a language.

The Unix philosophy itself. “Do one thing well” outgrew Unix to become a general design principle – for microservices, for command-line tools, for the no-build, small-pieces approach to the web, and for how to keep AI systems small enough to remain safe and legible.

The Throughline

Thompson and Ritchie are the systems-level expression of the same conviction that runs through this series. Edsger Dijkstra argued that simplicity is the prerequisite for reliability; Unix is that argument compiled and shipped – a kernel of a few key ideas, kept small enough to trust. Linus Torvalds’ “good taste,” the rewrite where the special case disappears, is “do one thing well” inside a single function instead of across a pipeline; and Torvalds built Linux and Git directly on the foundation these two laid. John Carmack’s fast, simple core is the same subtraction aimed at the hardware ceiling. And Yukihiro Matsumoto’s design of Ruby for human happiness is the Unix instinct – composable, expressive small pieces – carried up into a high-level language. The throughline is one sentence: power should come from composing small, comprehensible parts through a universal interface, not from any single part growing large. (Series bridge)

What I Take From This

The lesson I keep is that the interface is the architecture. When I design anything now – an agent, a tool loop, a pipeline of scripts – the temptation is always to make one component smarter, to fold the next requirement into the thing I already have until it becomes a monolith only I understand. The Unix move is the opposite: keep each piece small enough to fully understand, and put the intelligence into how the pieces connect. A clean, universal seam between dumb parts beats a clever part with no clean seams, every time. That is the same standard as quality being the only variable – the question is never “can this one program do more?” but “is this system still made of pieces I can reason about?”

In the world I build in now – AI agents wired together with tools and text – Thompson and Ritchie’s design is more relevant than it has any right to be at fifty-odd years old. An agent is a small program; a tool is a small program; the thing that makes them powerful is a clean, universal interface between them, which today is mostly structured text. That is the pipe, rebuilt. And “Trusting Trust” is the warning I take most seriously: when a system generates code faster than anyone can read it, the only durable basis for trust is keeping the parts small and the seams legible, because complexity is exactly where the things you cannot see go to hide. That conviction – that taste is a technical system and that small, composable, inspectable pieces are not a nicety but the whole game – runs straight from a 1969 PDP-7 to a 2026 agent harness.

FAQ

What is the Unix philosophy?

The Unix philosophy is a design approach built on small, single-purpose tools that compose through a universal interface. Its canonical statement, by Doug McIlroy in 1978, is: “Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.” The first principle is to build a new tool rather than add features to an existing one, and the system’s power comes from combining small parts – via pipes and plain text – rather than from any single program growing large.1

Did Ken Thompson say “do one thing well”?

No. The “do one thing well” maxim and the broader Unix philosophy were articulated in writing by Doug McIlroy, head of the Bell Labs Computing Sciences Research Center, in his foreword to the 1978 Bell System Technical Journal special issue on Unix.1 Thompson and Ritchie built the system that embodies the philosophy, and McIlroy – who also invented the Unix pipe – was its clearest articulator and the group’s resident taste critic. Attributing the maxim to Thompson is a common but incorrect shortcut.

What did Thompson and Ritchie actually create?

Ken Thompson built the first versions of the Unix operating system on a PDP-7 starting in 1969, and later created the B language, the ed editor, practical regular-expression search (grep), the Plan 9 system, UTF-8 (with Rob Pike), and co-designed Go at Google.3 Dennis Ritchie created the C programming language (1969–1973), used it to rewrite Unix in 1973 to make it portable, and co-authored The C Programming Language with Brian Kernighan in 1978.45 They shared the 1983 ACM Turing Award for Unix.8

What is “Reflections on Trusting Trust”?

It is Ken Thompson’s 1984 ACM Turing Award lecture, published in Communications of the ACM. He showed that a compiler could be made to insert a hidden backdoor into a program, and to reproduce that backdoor whenever it compiled a new version of itself – so the malicious code existed only in the binary and left no trace in any source you could read. His conclusion: “You can’t trust code that you did not totally create yourself… No amount of source-level verification or scrutiny will protect you from using untrusted code.” It is a foundational text of software supply-chain security.9


Sources


  1. M. Douglas McIlroy, foreword to “UNIX Time-Sharing System,” The Bell System Technical Journal, Vol. 57, No. 6, Part 2 (July–August 1978). The four-point summary (“Make each program do one thing well… build afresh rather than complicate old programs by adding new ‘features’”) and the concise later form: “Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.” See also “Unix philosophy,” Wikipedia. 

  2. “Unix,” Wikipedia. Multics abandoned by Bell Labs in 1969; PDP-7 origin; “Unics”/”Unix” naming (Brian Kernighan); Version 4 Unix rewritten in C in 1973 for portability; the hierarchical file system and treatment of devices and IPC as files (“everything is a file”); pipes; the 1974 CACM paper. 

  3. “Kenneth Lane Thompson,” Wikipedia. Born February 4, 1943, New Orleans; UC Berkeley BS/MS; Bell Labs (1966); first versions of Unix (“I did the first of two or three versions of UNIX all alone. And Dennis became an evangelist.”); B language; ed, regular expressions, grep; Plan 9; UTF-8 with Rob Pike (1992); Go at Google (2007–). 

  4. “Dennis Ritchie,” Wikipedia. Born September 9, 1941, Bronxville, NY; died October 12, 2011; Bell Labs Computing Sciences Research Center (1967); created C (evolving from B and BCPL) and used it to rewrite Unix for portability; Paul Ceruzzi quote (“if you had a microscope and could look in a computer, you’d see his work everywhere inside”). 

  5. “The C Programming Language,” Wikipedia. Brian Kernighan and Dennis Ritchie, first published February 22, 1978 (Prentice Hall); known as “K&R”; the first widely available book on C. 

  6. D. M. Ritchie and K. Thompson, “The UNIX Time-Sharing System,” Communications of the ACM, Vol. 17, No. 7 (July 1974), pp. 365–375. The paper that announced Unix to the broader computing community. 

  7. “Pipeline (Unix),” Wikipedia. Pipe concept conceived by Doug McIlroy; implemented by Ken Thompson in 1973 (the pipe() system call and the | operator). McIlroy: “The next day saw an unforgettable orgy of one-liners as everybody joined in the excitement of plumbing.” 

  8. “Dennis M. Ritchie – A.M. Turing Award Laureate,” ACM (mirror). The 1983 citation: “for their development of generic operating systems theory and specifically for the implementation of the UNIX operating system”; committee statement: “The success of the UNIX system stems from its tasteful selection of a few key ideas and their elegant implementation.” 

  9. Ken Thompson, “Reflections on Trusting Trust,” 1984 ACM Turing Award lecture, Communications of the ACM, Vol. 27, No. 8 (August 1984), pp. 761–763. The MORAL section: “You can’t trust code that you did not totally create yourself. (Especially code from companies that employ people like me.) No amount of source-level verification or scrutiny will protect you from using untrusted code.” 

  10. “Go (programming language),” Wikipedia. “It was designed at Google in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson, and publicly announced in November 2009.” 

Artigos relacionados

Engineering Philosophy: John Carmack, Performance as Moral Craft

John Carmack treats performance as a moral question. Strip to the fast, simple core, understand the problem to its found…

15 min de leitura

Engineering Philosophy: Leslie Lamport, Think Before You Code

Leslie Lamport made distributed systems a science: time is not global, causality is what is real, and you specify the de…

19 min de leitura

AI Agent Safety Starts With Small Software

AI agent safety starts with small software: smaller tools, plain files, narrow permissions, and faster tests give coding…

14 min de leitura