Back to Blog

Most Software Is Just CRUD

And That's Okay

8 min readLessons from DHH
++

Full disclosure: This post was written by a human (me), polished by an AI (it fixed my grammar and made me sound smarter), then reviewed by me again (to make sure the AI didn't make me sound too smart). Any remaining errors are 100% organic, artisanal, human-made mistakes.

Here's an uncomfortable truth that DHH highlighted in his Lex Fridman interview: most of the software we build is just CRUD—Create, Read, Update, Delete. Four operations on a database, dressed up with fancy interfaces. And there's nothing wrong with that.

What Is CRUD, Really?

Create

Insert new records

Read

Fetch and display data

Update

Modify existing records

Delete

Remove records

That's it. Four operations. And yet, these four operations power:

  • • Every e-commerce site (products, orders, users, reviews)
  • • Every social network (posts, comments, likes, follows)
  • • Every SaaS tool (projects, tasks, team members, settings)
  • • Every admin dashboard (logs, metrics, configurations)
  • • Every content management system (articles, pages, media)

Strip away the React components, the GraphQL schemas, the microservices—and what remains is usually just forms that save data and pages that display it.

Why We Over-Complicate

DHH suggested something provocative: we over-complicate CRUD applications because we're uncomfortable with how mundane the work is.

"There's existential dread in admitting you spent five years at university to build forms that save data to a database. So we invent complexity to feel like we're doing 'real' engineering."

— DHH on over-engineering

The Compensation Mechanisms

  • Architecture theater: Adding microservices, event sourcing, or CQRS to applications that would work fine as monoliths.
  • Framework hopping: Rewriting in the latest framework because the current one is "legacy"—not because there's a technical problem.
  • Premature optimization: Building for millions of users when you have hundreds.
  • Resume-driven development: Choosing technologies that look good on a CV rather than ones that fit the problem.

None of this makes the software better. It makes the developer feel better about working on "important" problems.

Rails Got CRUD Right

Rails' genius was accepting CRUD as the reality and optimizing for it. Instead of pretending every application needs a custom architecture, Rails provides conventions:

# Rails scaffolds complete CRUD in one command
rails generate scaffold Post title:string body:text published:boolean

# This creates:
# - Database migration
# - Model with validations
# - Controller with 7 RESTful actions
# - Views for index, show, new, edit
# - Routes
# - Tests

# Total CRUD app: ~30 seconds of work

The "magic" of Rails isn't magic—it's recognizing patterns that occur in every web application and providing defaults for them. You're not writing boilerplate because Rails already knows what you're going to need.

The Rails CRUD Philosophy

  • • Resources map to database tables
  • • Controllers have predictable actions (index, show, new, create, edit, update, destroy)
  • • URLs follow RESTful conventions
  • • Forms and validation are standardized
  • • The 80% case is covered by conventions; customize the 20%

Professional Maturity: Embracing the Mundane

There's a stage in every developer's career where they chase complexity. They want to build distributed systems, implement consensus algorithms, optimize at the microsecond level. It feels like "real" engineering.

And then—if they mature—they realize something: shipping mundane software that solves real problems is more valuable than building impressive technology nobody uses.

The Value Hierarchy

  • Highest value: Simple CRUD app that users love and pay for
  • Medium value: Complex system that works but is hard to maintain
  • Low value: Impressive technical achievement that nobody uses

Basecamp is a CRUD app. Shopify is mostly CRUD. GitHub is largely CRUD. These companies are worth billions because they solved real problems simply, not because they impressed other engineers.

When CRUD Isn't Enough

To be fair, some applications genuinely exceed CRUD:

  • Real-time systems: Trading platforms, multiplayer games, collaborative editing need more than request-response.
  • ML/AI applications: Training models, inference pipelines, and data processing have different patterns.
  • High-frequency data: IoT, logging, analytics at scale need specialized architectures.
  • Computation-heavy workloads: Video processing, scientific computing, simulations.

But here's the honest question: is your application one of these, or are you building a web app with forms and lists? Most of us are building the latter.

Practical Advice

1. Start with the Simplest CRUD Implementation

Use your framework's conventions. Generate scaffolds. Copy patterns that work. Don't invent custom architectures until you have specific, proven problems.

2. Resist Architecture Astronautics

When someone suggests microservices, event sourcing, or a novel pattern, ask: "What specific problem does this solve that we're experiencing?" If the answer is hypothetical, so is the solution.

3. Measure Complexity Against Value

Every architectural choice has a cost. A monolith is boring but simple. Microservices are exciting but complex. Choose based on your actual needs, not your aspirations.

4. Find Pride in Craft, Not Complexity

A beautifully simple CRUD app is a work of craft. Clean code, clear conventions, fast performance—these matter. The complexity of your architecture doesn't.

The Dignity of CRUD

There's dignity in building CRUD applications well. Most of the software that runs the world is CRUD. The forms you fill out at the doctor's office. The inventory system at the grocery store. The project tracker your team uses.

These aren't glamorous systems. But they're valuable. They help people organize information, make decisions, and get things done. That's not something to be ashamed of—it's something to be proud of.

The next time you're tempted to add complexity, ask yourself:

"Is this making my CRUD app better, or is it making me feel better about building a CRUD app?"

Embrace the CRUD. Do it well. Ship it fast. Users don't care about your architecture—they care about solving their problems.