Today Fizzy was released and the entire source code of its development history is open for anyone to see. DHH announced on X that the full git history is available - a rare opportunity to peek behind the curtain of how a 37signals product comes together.

I cloned down the repository and prompted Claude Code:

“Can you go through the entire git history and write a documentary about the development of this application. What date the first commit was. Any major tweaks, changes and decisions and experiments. You can take multiple passes and use sub-agents to build up a picture. Make sure to cite commits for any interesting things. If there is anything dramatic then make sure to see if you can figure out decision making. Summarize at the end but the story should go into STORY.md”

It responded with:

“This is a fascinating task! Let me create a comprehensive investigation plan and use multiple agents to build up a complete picture of this project’s history.”

Here is the story of Fizzy - as interpreted by Claude - from the trail of git commits. Enjoy!

From “Splats on a Windshield” to Open Source Project Management

A chronicle of 18 months of development at Basecamp, told through 8,152 commits.


Prologue: The Numbers

  • First Commit: June 21, 2024
  • Total Commits: 8,152
  • Contributors: 25+
  • Lines of Code Changed: Hundreds of thousands
  • Name Changes: 4 (Splat → Bubble → Card; Project → Bucket → Collection → Board)
  • Features Removed: At least 4 major ones
  • DHH Commits in April 2025 Alone: 323

Act I: Genesis — “New Rails App”

June 21, 2024: Day Zero

At 1:19 PM on a summer Friday, Kevin McConnell typed the words that would begin an 18-month journey:

commit 564a0f48aebfaa4766e97d2d06eaf9ec51bd4ec3
Author: Kevin McConnell
Date: 2024-06-21

    New Rails app

Within hours, the foundation was laid. The team moved with practiced efficiency:

  • 1:23 PM — Gemfile updated (e16323c)
  • 3:47 PM — Rubocop configured (b9cf8c5)
  • 4:07 PM — Minimal authentication flow (c4fb1bd)
  • 4:29 PM — CSS reset and base styles (b90caf5)
  • 4:46 PM — Brakeman security scanning added (ecae4a3)

By end of day, the skeleton of a Rails application stood ready. But what would it become?


Act II: The Splat Era — A Bug on Your Windshield

July 23, 2024: The Core Concept Emerges

One month after inception, Jason Zimdars introduced the application’s first real identity:

commit 932a83197b74741612d03c7f8606e1b5adefe25a
Author: Jason Zimdars
Date: 2024-07-23

    Add Splat model, controller, and views

A “Splat” — the name evokes something chaotic, impactful, unexpected. Like a bug hitting your windshield on a summer drive. The original data model was simple:

create_table :splats do |t|
  t.string :title
  t.text :body
  t.string :color  # dodgerblue, limegreen, tomato, mediumorchid
  t.timestamps
end

The next day brought the visual metaphor that would define the early application:

commit c2916a42d58d066d09930496eab551f1f6d496e6
Author: Jason Zimdars
Date: 2024-07-24

    Render with Flexbox, add windshield background

The windshield was the canvas. Splats appeared on it like bugs on glass — colorful, slightly chaotic, each one a piece of information demanding attention.

July 24, 2024: Preparing for the Demo

The commits reveal urgency. Something important was coming:

commit e139b5a72b0248fc9abbeae1f5a283b0c135ddd2
Author: Jason Zimdars
Date: 2024-07-24

    Still demo values, but make them stable
commit 75e402bea619a0af2774ede864978ef1904f446c
Author: Jason Zimdars
Date: 2024-08-14

    Handful of tweaks before all-hands

The all-hands demo. Approximately one month after project inception, Fizzy (then still called “Splat”) was shown to the entire company. The pressure to polish was evident in the commit messages.


Act III: “Let’s Try Bubbles”

July 31, 2024: The First Pivot

Seven days after the windshield metaphor was established, Jason Zimdars typed four words that would reshape the application’s identity:

commit 845e4618a57a4d92234732d6daa8da5f903c05a8
Author: Jason Zimdars
Date: 2024-07-31

    Let's try bubbles

The chaotic “splat” gave way to something gentler — bubbles floating on a windshield, like soap suds catching light. The animation changed from aggressive splattering to gentle floating:

@keyframes float-up-left {
  0% { transform: translate(10px, 40px); opacity: 0.1; }
  100% { transform: translate(0, 0); opacity: 1; }
}

August 2, 2024: Organic Evolution

commit 88b99ad1eb074cae09c72f9637a9d98b65b7aeed
Author: Jason Zimdars
Date: 2024-08-02

    Try a more organic bubble style

Perfect circles gave way to hand-drawn blob shapes. The team was discovering what their product was through the act of building it.

August 19-22, 2024: The “Boost” Feature — Foreshadowing the Name

A new interaction pattern emerged:

commit 40dcf9883 - "Add boosts model"
commit f39b58040 - "Display number of boosts on a splat"
commit 73f7ddca3 - "Animate when boosting (puffing up)"

When users “boosted” a bubble, it would puff up and float away — like champagne fizz rising. The animation:

@keyframes bubble-up {
  0% { transform: translate(0, 0); }
  50% { transform: translate(0, -4em); opacity: 0.66; }
  100% { transform: translate(0, -8em); opacity: 0; }
}

The metaphor was crystallizing. Bubbles. Fizzing. Effervescence. The name would come soon.


Act IV: Finding the Name

September 4, 2024: The Great Renaming

In a single day, the application found its final name through two commits:

commit 5aae70298 (September 4, 2024)
Author: Unknown

    Rename Splat to Bubble

42 files changed. The model, controllers, views, tests — everything touched.

Hours later:

commit e0763d4d4 (September 4, 2024)

    Splat -> Fizzy

Fizzy. The name captured everything: the bubbles, the effervescence, the playful energy of the interface. Visual design had driven product naming — the team discovered what they were building through the act of building it.


Act V: The Architecture Takes Shape

September 2024: Introducing Hierarchy

The flat list of bubbles needed structure:

commit c09a02fa9 (September 16, 2024)

    Introduce projects and accesses
commit 355e144dd (September 18, 2024)

    Nest bubbles et al under projects

But “Projects” didn’t feel right. Eight days later:

commit 4e579e5a3 (September 24, 2024)

    Rename Project to Bucket

Then “Bucket” became “Collection.” Eventually, “Collection” would become “Board.”

The terminology dance — Projects → Buckets → Collections → Boards — reveals a team searching for the right mental model. They ultimately landed on the familiar “Board” metaphor, aligning with tools like Trello and Linear.


Act VI: Enter DHH — The Architectural Enforcer

October 17, 2024: First Contact

David Heinemeier Hansson, creator of Ruby on Rails and co-founder of Basecamp, made his first contribution with characteristic pragmatism:

commit 8504e911a
Author: David Heinemeier Hansson
Date: 2024-10-17

    No longer used

He deleted an unused image file. It was a statement of intent.

October 19, 2024: Rails 8 and Caching Blitz

Within two days, DHH’s fingerprints were everywhere:

commit 23d81c07c - "Use Rails 8.0 rc1"
commit 5d06e5449 - "Etag the bubbles#show"
commit cd14fda39 - "Cache bubble partial on itself"
commit 32d1792cb - "Fetch bubbles index with multiget cache"

He upgraded the entire application to Rails 8 release candidate and systematically added HTTP caching throughout.

The War on “Anemic” Code

DHH’s most distinctive contribution was his crusade against what he called “anemic” code — thin wrappers that explain nothing and add needless indirection. He used this term 15 times in commit messages:

commit 7d86aae67 - "Inline anemic method"
commit 0edfc337c - "Inline anemic partials"
commit 9913853cc - "Remove anemic concern"
commit a1543f266 - "Inline anemic helper method with no additional explaining purpose"
commit cacee0feb - "Remove anemic scope"
commit a5df54015 - "Remove anemic and indirect method that explained nothing"

Philosophy: Code should either add explanatory value OR hide implementation complexity. Thin wrappers that do neither are “anemic” and should be eliminated.

April 2025: The Great Refactoring

Then came April 2025. DHH made 323 commits in a single month — 55% of his total contributions compressed into 30 days.

This was a surgical strike. He:

His commit messages tell the story:

commit 966aa51a3 - "Get rid of unnecessary touch jobs"
commit 255435a38 - "No need for a non-standard factory method for something this simple"
commit 393e5fd3d - "Don't want to ship with this wart"
commit e3f7930dc - "Unlikely we are going to need this"

In DHH’s philosophy: deletion is a feature, not a bug.


Act VII: The Final Transformation — Bubbles Become Cards

April 9, 2025: The Kanban Awakening

After 10 months as “Bubbles,” another transformation:

commit 723e6d94f
Date: 2025-04-09

    Rename bubbles => cards

333 files changed. “Pop” (completing a bubble) became “Closure” (closing a card). The playful metaphor gave way to task management vocabulary.

September-November 2025: The Column System

The final architectural piece:

commit cd025447f (September 2025)

    Add basic column models and script to migrate

Fizzy had become a kanban board. Cards lived in columns. Columns could be customized, colored, reordered. The application had evolved from “bugs on a windshield” to a sophisticated project management tool.

commit 2af7a9f40 (November 5, 2025)

    Merge PR #1498: rename-boards

Collections became Boards. The transformation was complete:

Original (July 2024):

  • Splats on a Windshield

Final (November 2025):

  • Cards → Columns → Boards → Accounts

Act VIII: The Features That Didn’t Make It

Fizzy Ask — The AI That Was Removed

commit 9a02716a4 - "Add Fizzy Ask" (PR #857)
commit 1263ca582 - "Give Fizzy Ask context about who it's talking to"
commit fc0fccef1 - "Show only published cards to Fizzy Ask"
commit 24cb5da19 - "Make Fizzy Ask staff-only"
commit 9317a8257 - "Remove Fizzy Ask"

A Claude-powered AI assistant that could answer questions about project content. Born, restricted to staff, then removed entirely. Perhaps replaced by the more ambitious MCP (Model Context Protocol) integration — making Fizzy AI-native at the protocol level rather than bolting on a chatbot.

Reactions — The Feature That Came Back

commit [initial] - Reactions feature added
commit bf44ad973 - "Revert reactions"
commit a9bb534d8 - "Reactions polish" (PR #1734)

Emoji reactions for cards and comments. Added. Removed. Then added again. The git history shows healthy debate — not everything that ships stays shipped, and not everything removed stays gone.

Custom Views — Replaced by Simplicity

commit 86332e3a2 - "Remove custom views UI"
commit e4fb0e831 - "Add static quick filters"

Saved custom views were replaced by ephemeral quick filters. Complexity gave way to simplicity.

Workflows — Too Much Structure

commit 24f1394ca - "Remove workflows code, remove more unused code"
commit c99084c65 - "No workflows, columns will be ad-hoc"

Predefined workflows with stages were removed in favor of ad-hoc column organization. Users would create their own structure.


Act IX: The Experimental Frontier

The MCP Branch — AI-Native by Design

commit fa16de7bb - "Add bubbles list as a tool for MCP clients"
commit fbd9b6302 - "Add an MCP manifest ala PWA manifests"
commit de6f782ca - "Add MCP Identification to all requests"

The MCP (Model Context Protocol) branch represents cutting-edge AI integration — allowing Claude and other AI assistants to interact with Fizzy programmatically. An .mcp.json manifest advertises Fizzy’s capabilities to AI clients.

Status: Removed from main, but the infrastructure remains fascinating. This is one of the earliest explorations of making traditional web applications AI-native.

Mobile Column View — The Unsolved Problem

Branches:
- origin/mobile-column-view-redux
- origin/mobile-column-view-redux+contained-scrolling
- origin/test-swiping-columns-on-mobile
- origin/mobile-app/scoped-stylesheets

Multiple parallel branches exploring different approaches to mobile column navigation. Scroll snapping. Contained scrolling. Swipeable columns. The problem remains unsolved — there’s no “one true way” for mobile kanban navigation.

SQLite Support — Database Flexibility

commit a2333d9a3 - "Add SQLite support"
commit 12de56417 - "Remove MySQL from default local development setup"

Making Fizzy work with SQLite in addition to MySQL. Simpler local development. Better portability. The search index was even sharded into 16 tables (search_records_0 through search_records_15) for scale.


Act X: The Road to Open Source

November 22-28, 2025: The Great Extraction

commit e1e9a01 - "Make open source the default"
commit 8724963 - "Bring vanilla versions for Dockerfile and deploy config"
commit 2c70793 - "Move kamal deploy config to the gem"
commit 0328149 - "Initial github action setup"

The proprietary SAAS features were extracted into a separate gem. What remained was a clean, open-source Rails application.

November 28, 2025: Public Release

commit fa1fe47
Date: 2025-11-28

    Initial README and LICENSE

After 18 months of development, 8,152 commits, and countless pivots, Fizzy became open source.


Epilogue: The Cast of Characters

The Contributors (by commit count)

  1. Jason Zimdars (2,217 commits) — The visual architect. From “Let’s try bubbles” to pixel-perfect polish.

  2. Jorge Manrubia (2,053 commits) — The engineering backbone. Consistent, prolific, essential.

  3. Andy Smith (1,007 commits) — Front-end craftsmanship and UI refinement.

  4. Mike Dalessio (875 commits) — Infrastructure, performance, the recent dashboard work.

  5. David Heinemeier Hansson (586 commits) — The architectural enforcer. Rails modernization and the war on anemic code.

  6. Kevin McConnell (351 commits) — Started it all with “New Rails app.”

  7. Jose Farias (341 commits) — Feature development and testing.

  8. Stanko K.R. (239 + 54 commits) — Security hardening and webhook restrictions.

  9. Jeffrey Hardy (100 commits) — Early infrastructure and modernization.

  10. Jason Fried (7 commits) — The occasional “Small copy adjustment” from the CEO.

The Dramatic Moments

  • July 24, 2024: “Handful of tweaks before all-hands” — Demo day pressure
  • July 31, 2024: “Let’s try bubbles” — The visual pivot
  • September 4, 2024: “Splat -> Fizzy” — Finding the name
  • April 2025: DHH’s 323-commit refactoring blitz
  • October 2025: “Remove Fizzy Ask” — The AI feature that didn’t survive
  • November 28, 2025: “Initial README and LICENSE” — Going public

Technical Appendix: The Architecture Evolution

Data Model Timeline

July 2024 (v0.1):

Splat (title, body, color)
  └── Categories
  └── Boosts
  └── Comments

September 2024 (v0.2):

Project (name)
  └── Bubble (title, body, color)
       └── Tags
       └── Comments
       └── Boosts

November 2025 (v1.0):

Account
  └── Board (name, settings)
       └── Column (name, color, position)
            └── Card (title, status, due_on)
                 ├── Comments
                 ├── Assignments
                 ├── Attachments
                 ├── Tags
                 ├── Steps (checklist)
                 ├── Watches
                 └── Events (audit trail)

Key Technology Decisions

  1. Rails 8.x — Always on the latest, sometimes ahead of stable
  2. Hotwire (Turbo + Stimulus) — No heavy JavaScript framework
  3. Solid Queue & Solid Cache — Rails-native background jobs and caching
  4. SQLite + MySQL support — Database flexibility
  5. Kamal deployment — Modern container orchestration
  6. UUID primary keys — Using UUIDv7 for time-ordering
  7. Multi-tenancy — Account-based data isolation

Conclusion: What Fizzy Teaches Us

The story of Fizzy is the story of discovery through building. The team didn’t know they were building a kanban board when they started with “splats on a windshield.” They found out through iteration.

Key lessons:

  1. Names matter, but they can change. Splat → Bubble → Card. Project → Bucket → Collection → Board. The right name emerges through use.

  2. Deletion is a feature. Boosts, Fizzy Ask, custom views, workflows — removing the wrong features is as important as adding the right ones.

  3. Architecture evolves. The final column-based kanban system looks nothing like the original flat list of splats.

  4. DHH’s philosophy: Remove anemic code. Keep transactions short. Use the latest Rails. Delete more than you add.

  5. Design drives naming. “Fizzy” emerged from the visual metaphor of bubbles puffing up and floating away — the design informed the brand.

  6. Open source takes extraction. 18 months of SAAS development needed careful separation before the core could be shared.

The git history of Fizzy is a masterclass in iterative product development. 8,152 commits. 25+ contributors. 18 months. One application that discovered its identity through the act of creation.


“Let’s try bubbles.” — Jason Zimdars, July 31, 2024


Commit Reference Index

Commit Date Author Message Significance
564a0f48 2024-06-21 Kevin McConnell New Rails app Genesis
932a8319 2024-07-23 Jason Zimdars Add Splat model First feature
c2916a42 2024-07-24 Jason Zimdars Add windshield background Visual metaphor
75e402be 2024-08-14 Jason Zimdars Tweaks before all-hands Demo day
845e4618 2024-07-31 Jason Zimdars Let’s try bubbles Design pivot
e0763d4d 2024-09-04 Splat -> Fizzy The name
5aae7029 2024-09-04 Rename Splat to Bubble Model rename
8504e911 2024-10-17 DHH No longer used DHH arrives
23d81c07 2024-10-19 DHH Use Rails 8.0 rc1 Rails 8
723e6d94 2025-04-09 Rename bubbles => cards Final transformation
760cbb6c 2025-04-12 DHH Drop Boosts Feature removal
9317a825 2025-10-?? Remove Fizzy Ask AI removal
2af7a9f4 2025-11-05 Rename collection to board Final naming
fa1fe47 2025-11-28 Initial README and LICENSE Open source

Documentary compiled December 2, 2025 Based on analysis of the Fizzy git repository