Skip to main content

Using Claude to Clone Trello in 20 Minutes

AI Coding Claude Architecture

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

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. Trello is a solid product, but it is 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.

The Setup

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.

The delivered application includes the following.

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

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 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.

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. This eliminates CORS configuration, Nginx reverse proxying, and a 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 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. Drag-and-drop latency is zero because the client never waits 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. This avoids re-renders, React context, and theme providers. The preference persists to localStorage.

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

Tech Stack

Layer Technology
Frontend React 18, Vite 5, React Router 6, @hello-pangea/dnd, react-markdown, date-fns
Backend Node.js 20, Express 4, node-postgres
Database PostgreSQL 15
Containerization Docker, Docker Compose (multi-stage build)
Testing Playwright (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 properly decomposed React application:

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 complex UI concerns that warrant their line counts.

Database Design

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

Table Purpose
boards Kanban boards with title, description, background color, position
lists Columns within boards, ordered by position
cards Tasks within lists, with markdown descriptions, due dates, completion status
labels Board-level color-coded labels with custom names
card_labels Many-to-many junction table (composite PK; no unnecessary surrogate key)
checklists Checklist groups on cards, ordered by position
checklist_items Individual checklist items with completion tracking
activities Audit 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

Category Lines Files
Backend core (server, db, migration) 193 3
Backend routes 1,010 8
Frontend components 3,284 6
Frontend core (App, api, main) 147 3
CSS / Styles 1,448 1
Backend API tests 369 1
E2E tests 293 1
Config / infrastructure ~50 5
Total ~6,800 28

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. The stylesheet covers a fully themed application with complete light and dark mode support.

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 with zero 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 catch regressions in the drag-and-drop, the modal lifecycle, and the search debouncing, precisely the kinds of bugs that backend-only tests miss.

Feature Completeness

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

Requirement Delivered?
Board CRUD with custom backgrounds Yes
Board archive/restore Yes
Board reordering Yes
List CRUD with inline editing Yes
List drag-and-drop reordering Yes
List archive Yes
Card CRUD Yes
Card drag between lists Yes
Card reorder within lists Yes
Multi-select cards Yes
Card archive/restore Yes
Mark cards as completed Yes
Markdown descriptions with auto-save Yes
Multiple checklists per card with progress Yes
Color-coded labels with custom names Yes
Due dates with overdue/upcoming indicators Yes
Activity log Yes
Global search Yes
Filtering (labels, due dates, completion) Yes
Dark mode Yes
Keyboard shortcuts Yes
Command palette (Cmd+K) Yes
Export/Import (JSON) Yes
File attachments No
Automation / rules engine No
Undo/redo No
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. Everything Claude delivered 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 missing 15% falls squarely in "nice to have" territory. I rarely 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:

Aspect Harvest Clone Trello Clone
Time 18 minutes 19 minutes
Lines of code ~4,700 ~6,800
Backend framework Python/Flask Node.js/Express
Frontend framework React React
Database PostgreSQL PostgreSQL
API endpoints 46 30+
Tests 32 52
Docker Multi-stage + Nginx Multi-stage (single-port)
CSS 594 lines 1,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 maintains a consistent engineering style across projects.

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. This time, Claude wrote the requirements 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" took 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.


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, making this a particularly recursive form of AI-assisted content creation.

Let's Build Something!

I help teams ship cloud infrastructure that actually works at scale. Whether you're modernizing a legacy platform, designing a multi-region architecture from scratch, or figuring out how AI fits into your engineering workflow, I've seen your problem before. Let me help.

Currently taking on select consulting engagements through Vantalect.