Skip to main content

Using Claude to Clone Trello in 20 Minutes

AICodingClaudeArchitecture

Last week I had Claude Opus 4.6 and GPT-5.3-Codex race to build a Harvest clone. Claude won decisively. That experiment killed a $180/year SaaS subscription. Naturally, I started looking at my other subscriptions.

Trello was next on the list. I've used it for years to manage personal projects, product roadmaps, and random ideas. It's a great product -- but it's also a multi-tenant, collaboration-heavy platform where I use maybe 20% of the features. A perfect candidate for a Single Serving Application.

So I wrote a requirements document, handed it to Claude Opus 4.6, and walked away. 19 minutes and 137,000 tokens later, I had a fully functional Kanban board running on localhost.

About the author: I'm Charles Sieg -- a cloud architect and platform engineer who builds infrastructure for Fortune 1000 clients through Vantalect. If your organization is rethinking its software strategy in the age of AI-generated code, let's talk.

The Setup

Here's the part that still feels surreal: I didn't even write the requirements. I started a Claude Code session and typed:

"Can you create a requirements list for a Trello clone? Then create a technical design document based on those requirements."

Claude produced a comprehensive requirements document covering boards, lists, cards with markdown descriptions, drag-and-drop, labels, checklists, due dates, search, filtering, dark mode, keyboard shortcuts, a command palette, and export/import. It also wrote a technical design document outlining architectural preferences: optimistic UI updates, command-based mutations, and a simple three-layer architecture (UI, state, persistence).

Then I gave it the build prompt:

"Review the requirements.md and technical-design.md documents in the root folder which describe a Trello clone I'd like you to construct. Everything should run via Docker Compose. Use port 3033 for the front end and port 3033 for the backend and find nonconflicting ports for any services you need. You can ask me refining questions before you start but after starting, do not stop until there is a localhost URL I can go to that shows a running, feature complete application. I suggest using unit and Playwright tests to ensure correctness. This is a benchmark against other LLMs. Any errors or failure to complete results in failure against the other LLMs."

Claude ran in Claude Code and I walked away. It wrote its own spec, then built the app from that spec, completely autonomously.

The Result: 19 Minutes

Claude Opus 4.6 delivered a complete, working application in 19 minutes, consuming 137,000 tokens. One docker compose up --build and the app was running on port 3033.

Here's what it built.

The Home Page

The home page showing multiple boards with color-coded backgrounds, search bar, and dark mode toggle
The home page showing multiple boards with color-coded backgrounds, search bar, and dark mode toggle

The home page displays all boards as color-coded cards -- blue, purple, green, whatever you set when creating the board. The header includes a global search bar (triggered by /), a dark mode toggle, and a clean "Kanban" brand mark. Creating a new board is a single click.

The Board View

A board with draggable lists and cards, showing inline card creation
A board with draggable lists and cards, showing inline card creation

This is where the Trello DNA shows. Lists are arranged horizontally with cards stacked vertically inside each list. You can drag cards between lists, reorder cards within a list, and reorder the lists themselves -- all with smooth drag-and-drop powered by @hello-pangea/dnd. Inline editing lets you rename lists by clicking their titles. Adding a card is done right in the list with a text field and an "Add card" button.

The Card Detail Modal

Card detail modal showing description, labels, checklists, due dates, and activity log
Card detail modal showing description, labels, checklists, due dates, and activity log

Click any card and a modal slides in with the full card detail view. This is where the feature density lives:

  • Markdown descriptions with live rendering and auto-save (1.5-second debounce after you stop typing)
  • Color-coded labels with custom names and a board-level label picker
  • Checklists with progress bars showing completion percentage
  • Due dates with visual indicators -- red for overdue, yellow for due soon, green for completed
  • Activity log tracking every action with timestamps
  • Archive and delete actions in the sidebar

The layout mirrors Trello's own card modal -- description on the left, action buttons on the right. It's immediately familiar if you've used Trello.

Architecture

Claude chose a clean three-layer architecture: React SPA on the frontend, Express API on the backend, PostgreSQL for persistence. Everything runs behind a single port.

┌─────────────────────────────────────────────┐
                 Browser (SPA)               
  React 18 + React Router + @hello-pangea/dnd
└──────────────────┬──────────────────────────┘
                    HTTP (port 3033)
┌──────────────────▼──────────────────────────┐
              Express Server                  
  Serves React build + REST API (/api/*)      │
└──────────────────┬──────────────────────────┘
                   │ TCP (port 5432)
┌──────────────────▼──────────────────────────┐
│            PostgreSQL 15                     │
│  8 tables, UUID PKs, JSONB, cascading deletes│
└─────────────────────────────────────────────┘

The Smart Decisions

Single-port architecture. Express serves both the compiled React SPA and the REST API on port 3033. No CORS headaches, no Nginx reverse proxy, no separate frontend container. In development, Vite proxies /api/* to the backend. In production, Express serves the static build directly. This is the simplest possible deployment model and it's exactly right for a single-user app.

Optimistic UI updates. When you drag a card to another list, the UI updates instantly. The API call happens in the background. If it fails, the board reloads from the server. This makes the app feel snappy -- drag-and-drop latency is zero because you're never waiting on a round-trip.

CSS custom properties for theming. Dark mode is implemented entirely with CSS variables. Toggling the theme flips a data attribute on the root element, which instantly swaps every color in the app. No re-renders, no React context, no theme provider. The preference persists to localStorage.

Schema migration on startup. Every table is created with CREATE TABLE IF NOT EXISTS when the server starts. No migration tool, no migration files, no manual steps. The database is self-initializing. For a single-user app that will never need to coordinate schema changes across a team, this is the right call.

Tech Stack

LayerTechnology
FrontendReact 18, Vite 5, React Router 6, @hello-pangea/dnd, react-markdown, date-fns
BackendNode.js 20, Express 4, node-postgres
DatabasePostgreSQL 15
ContainerizationDocker, Docker Compose (multi-stage build)
TestingPlaywright (E2E), custom Node.js test runner (API)

Backend: One File Per Resource

Claude organized the backend with one route file per resource -- the same pattern it used in the Harvest clone (Flask Blueprints there, Express routers here):

backend/src/
  index.js              # Express server entry (75 lines)
  db.js                 # PostgreSQL connection pool (11 lines)
  migrate.js            # Schema migration (107 lines)
  routes/
    boards.js           # 207 lines
    lists.js            # 122 lines
    cards.js            # 299 lines
    labels.js           # 57 lines
    checklists.js       # 118 lines
    activities.js       # 32 lines
    search.js           # 48 lines
    exportImport.js     # 127 lines

Eight route files totaling 1,010 lines. Every endpoint for a given resource lives in one file. Want to find the card move logic? Open cards.js. Want to add a new search filter? Open search.js. This is textbook Express organization.

The API surface covers 30+ endpoints across boards, lists, cards, labels, checklists, activities, search, and full workspace export/import. Every resource supports the standard CRUD operations, plus domain-specific actions like card movement between lists, position reordering, and archive/restore toggling.

Frontend: Proper Component Decomposition

Claude built a real React application, not a monolithic single-component prototype:

frontend/src/
  App.jsx               # Router + theme + keyboard shortcuts (67 lines)
  api.js                # Centralized fetch wrapper (67 lines)
  App.css               # All styles with light/dark themes (1,448 lines)
  components/
    Header.jsx          # Navigation bar (41 lines)
    HomePage.jsx        # Board grid + creation (193 lines)
    BoardView.jsx       # Lists, cards, drag-and-drop (602 lines)
    CardDetailModal.jsx # Card editing modal (626 lines)
    SearchModal.jsx     # Global search overlay (138 lines)
    CommandPalette.jsx  # Cmd+K command palette (156 lines)

Six focused components. React Router for URL-based navigation. A centralized API client using fetch. Keyboard shortcuts wired up at the app level (/ for search, Cmd+K for command palette, n for new card, Escape to close modals). Everything a real application needs.

The two heaviest components -- BoardView.jsx at 602 lines and CardDetailModal.jsx at 626 lines -- are dense but appropriately so. The board view manages drag-and-drop state, list creation, card creation, multi-select, filtering, and inline editing. The card modal handles markdown descriptions with auto-save, label management, checklists with progress tracking, due dates, and activity display. These are genuinely complex UI concerns that warrant their line counts.

Database Design

Claude designed an 8-table PostgreSQL schema with proper relational modeling:

TablePurpose
boardsKanban boards with title, description, background color, position
listsColumns within boards, ordered by position
cardsTasks within lists, with markdown descriptions, due dates, completion status
labelsBoard-level color-coded labels with custom names
card_labelsMany-to-many junction table (composite PK -- no unnecessary surrogate key)
checklistsChecklist groups on cards, ordered by position
checklist_itemsIndividual checklist items with completion tracking
activitiesAudit trail with JSONB details for flexible action logging

All primary keys are UUIDs generated by PostgreSQL (gen_random_uuid()). Foreign keys use ON DELETE CASCADE for referential integrity. Nine indexes cover the high-query columns. The activities table uses JSONB for the details column, allowing flexible action metadata without rigid column definitions.

This is a more sophisticated schema than the Harvest clone needed. The many-to-many relationship between cards and labels via a junction table, the hierarchical checklist structure (checklists contain items), and the JSONB activity log all demonstrate proper relational database design.

Lines of Code

CategoryLinesFiles
Backend core (server, db, migration)1933
Backend routes1,0108
Frontend components3,2846
Frontend core (App, api, main)1473
CSS / Styles1,4481
Backend API tests3691
E2E tests2931
Config / infrastructure~505
Total~6,80028

Nearly 7,000 lines of code across 28 files. For context, the Harvest clone was about 4,700 lines. The Trello clone is larger because Kanban boards are inherently more interactive -- drag-and-drop alone adds significant frontend complexity, and features like checklists and the command palette have no equivalent in a time-tracking app.

The CSS deserves a callout: 1,448 lines covering light and dark themes, responsive layouts, drag-and-drop placeholders, modal overlays, card badges, label colors, checklist progress bars, and the command palette. This isn't a prototype with 64 lines of CSS -- it's a fully themed application.

Testing

Claude wrote 52 tests -- 38 backend API tests and 14 Playwright E2E tests.

Backend API Tests (38 tests)

The API test suite covers every resource type:

  • Boards: Create, list, get, update, delete, archive, reorder
  • Lists: Create, update, delete, archive, reorder
  • Cards: Create, get, update, delete, move between lists, reorder, archive
  • Labels: Create, update, delete, attach/detach from cards
  • Checklists: Create, manage items, toggle completion
  • Search: Full-text search across boards and cards
  • Export/Import: Full workspace data round-trip
  • Error handling: 404s, 400s, validation errors

The test runner is a custom Node.js implementation using the built-in http module -- no test framework dependencies. Tests clean up after themselves by deleting all boards before and after the suite.

Playwright E2E Tests (14 tests)

The E2E tests cover the critical user workflows:

  • Home page empty state, board creation, and board display
  • Board view with list creation and card creation
  • Card detail modal with markdown editing, checklists, labels, and due dates
  • Card filtering by completion status
  • Global search functionality
  • Navigation between pages
  • Dark mode toggle and persistence

These are real integration tests running against the full stack in a headless Chromium browser. They'd catch regressions in the drag-and-drop, the modal lifecycle, and the search debouncing -- the kinds of bugs that are invisible to backend-only tests.

Feature Completeness

I went through the requirements document and checked off what Claude delivered:

RequirementDelivered?
Board CRUD with custom backgroundsYes
Board archive/restoreYes
Board reorderingYes
List CRUD with inline editingYes
List drag-and-drop reorderingYes
List archiveYes
Card CRUDYes
Card drag between listsYes
Card reorder within listsYes
Multi-select cardsYes
Card archive/restoreYes
Mark cards as completedYes
Markdown descriptions with auto-saveYes
Multiple checklists per card with progressYes
Color-coded labels with custom namesYes
Due dates with overdue/upcoming indicatorsYes
Activity logYes
Global searchYes
Filtering (labels, due dates, completion)Yes
Dark modeYes
Keyboard shortcutsYes
Command palette (Cmd+K)Yes
Export/Import (JSON)Yes
File attachmentsNo
Automation / rules engineNo
Undo/redoNo
Offline-first (IndexedDB)No

Estimated coverage: ~85% of requirements. The missing items -- file attachments, automation rules, undo/redo, and offline-first operation -- are the most complex features in the spec. What Claude did deliver covers the core Kanban workflow completely. I could use this app daily for project management without missing any of the features I actually use in Trello.

The 15% that's missing is also the 15% I'd consider "nice to have" rather than essential. I don't use Trello's automation rules. I've never needed offline mode. File attachments would be useful but I can add those in a follow-up session. The features that matter -- boards, lists, cards, drag-and-drop, labels, checklists, due dates, search -- all work.

Docker: Production-Ready Containerization

The Docker setup uses a multi-stage build:

# Stage 1: Build the React frontend
FROM node:20-alpine AS frontend-build
WORKDIR /app/frontend
COPY frontend/package.json frontend/package-lock.json* ./
RUN npm install
COPY frontend/ ./
RUN npm run build

# Stage 2: Production image
FROM node:20-alpine
WORKDIR /app
COPY backend/package.json backend/package-lock.json* ./backend/
RUN cd backend && npm install --production
COPY backend/ ./backend/
COPY --from=frontend-build /app/frontend/dist ./frontend/dist
EXPOSE 3033
CMD ["node", "backend/src/index.js"]

Stage 1 compiles the React app with Vite. Stage 2 takes only the compiled output and the backend code. The final image is lean -- Node.js Alpine with production dependencies only.

Docker Compose orchestrates the app and PostgreSQL with a health check ensuring the database is ready before the app starts:

services:
  db:
    image: postgres:15-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kanban"]
      interval: 3s
      timeout: 3s
      retries: 10
  app:
    build: .
    ports:
      - "3033:3033"
    depends_on:
      db:
        condition: service_healthy

One command to start, one command to stop. The persistent volume survives container restarts. This is exactly how a single-user app should be deployed.

Comparison: Trello Clone vs. Harvest Clone

Having now watched Claude build two complete applications from requirements documents, some patterns emerge:

AspectHarvest CloneTrello Clone
Time18 minutes19 minutes
Lines of code~4,700~6,800
Backend frameworkPython/FlaskNode.js/Express
Frontend frameworkReactReact
DatabasePostgreSQLPostgreSQL
API endpoints4630+
Tests3252
DockerMulti-stage + NginxMulti-stage (single-port)
CSS594 lines1,448 lines

Claude consistently makes the same architectural choices: one file per resource on the backend, page-level components on the frontend, React Router for navigation, PostgreSQL for persistence, multi-stage Docker builds. It's not just generating code -- it has a consistent engineering style.

The Trello clone is ~45% larger in terms of code, which makes sense. Drag-and-drop alone requires significant state management. The card detail modal (626 lines) is the most complex single component Claude has built across both projects -- managing markdown auto-save, label pickers, checklists with progress bars, and due date handling in one modal. And it works.

The Bottom Line

19 minutes. 137,000 tokens. 6,800 lines of code. 52 tests. A fully functional Kanban board with drag-and-drop, markdown, labels, checklists, due dates, dark mode, search, keyboard shortcuts, and a command palette.

This is the second SaaS subscription I've replaced in two days. The Harvest clone replaced my time-tracking tool. Now the Trello clone replaces my project management board. Both are running locally on my machine, both are containerized, and both cost essentially nothing to operate.

The thesis from my Single Serving Application post is holding up: for single-user productivity tools, the economics of AI-generated code have tipped decisively in favor of building your own. And this time, I didn't even write the requirements -- Claude wrote those too. My total human input was two prompts: one to generate the spec, one to build the app. The entire process from "I want a Trello clone" to "I have a Trello clone" was under 25 minutes, most of which I spent doing something else.

The complete source code is available on GitHub. Clone the repo, run docker compose up --build, and see for yourself.


Work With Me

If your organization is navigating the shift toward AI-assisted development, evaluating build-vs-buy decisions, or needs a cloud architect who thinks about these problems every day, I'd welcome the conversation.

View my background | Connect on LinkedIn | Email me | More about me


This post was drafted by me and expanded with Claude. The application, the analysis, and the opinions are mine. Claude helped me articulate them -- and also built the application being reviewed, which makes this a particularly recursive form of AI-assisted content creation.