The Anti-Complexity Manifesto

Building and deploying a web application can require a toolchain as complex as the product. Each tool may solve a real problem. Together they can become the larger one.

The first day

Consider the toolchain required to build and deploy a conventional web application.

A runtime. A package manager. A build tool, bundler, and transpiler. A linter, formatter, type checker, test runner, and coverage tool. Containers, CI, infrastructure files, secrets, environments, and configuration for the configuration.

This can be the toolchain for one service. More services and languages repeat parts of it. A monorepo adds tooling to coordinate the whole.

The new engineer may spend the first day installing tools rather than learning the product. A broken package cache, container daemon, state lock, or virtual environment delays the first useful build.

We find this unacceptable.

How it accretes

Each tool exists because it solves a real problem. Linters catch bugs. Formatters keep style consistent. Type checkers prevent errors. Bundlers reduce load time. Containers make environments repeatable. CI automates delivery. Individually, each choice is defensible.

Collectively, their interactions create complexity no single tool author designed. The linter fights the formatter. The bundler assumes a layout another tool changes. A plugin expects a different compiler version. CI caches a dependency the local package manager has moved past.

Fred Brooks separated the difficulty inherent in a problem from the accidental work of expressing it in “No Silver Bullet”. A toolchain cannot remove the product's essential complexity. It can add a lot of work around it.

Onboarding becomes installing tools. Attention moves from the product to build failures and migration guides. A build can fail inside a plugin nobody on the team wrote. Local and automated builds disagree because their tools differ.

One command

We use one clear build entry point. It compiles and links the source into the artifact we deploy. Compilation, tests, and formatting live in the language toolchain rather than in a chain of unrelated programs.

Product policy stays in source by default. The build therefore needs fewer configuration files and fewer versioned interactions among tools.

This does not make the application simple inside. Real product capability still requires real code. A new engineer should still be able to read, build, test, and run the same source the team ships.

Web development still needs type safety, formatting, testing, and repeatable delivery. It does not need each of those to come from a separate program. A tool earns its place when it removes more work than it creates. Popularity is not enough.

We compile from source. There is one command.

PreviousAnti-Slop Manifesto NextAnti-Abstraction Manifesto