Day three. Another SaaS subscription, another Single Serving Application.
I've now replaced Harvest (time tracking) and Trello (project management) with AI-generated clones. Today's target: Confluence -- Atlassian's knowledge management and wiki platform.
Claude Opus 4.6 built a fully functional Confluence clone in 16 minutes, consuming 106,000 tokens. That's the fastest build yet -- down from 18 minutes for Harvest and 19 for Trello. The pattern is holding: requirements in, working application out, no human intervention needed.
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
Same process as the previous clones. I had Claude generate a requirements document and a technical design document, then handed them back with the build prompt. Claude ran in Claude Code, I walked away, and came back to a running application on port 3033.
What It Built
A single-user knowledge base with a rich text editor, hierarchical page organization, version history, full-text search, and a command palette. The core of what makes Confluence useful for personal documentation and note-taking -- without the enterprise overhead.

The screenshot tells the story: a clean, Confluence-inspired layout with a collapsible page tree on the left, breadcrumb navigation at the top, a comprehensive formatting toolbar, and a WYSIWYG editor powered by TipTap (built on ProseMirror). The "Saved" indicator in the top right confirms auto-save is working -- every edit is persisted after 800ms of inactivity.
The Rich Text Editor
This is where the Confluence clone gets interesting. Time tracking and Kanban boards are CRUD-heavy but UI-simple. A knowledge base lives or dies by its editor.
Claude chose TipTap, an open-source rich text framework built on ProseMirror. This is the same engine that powers the editors in Notion, GitBook, and other modern writing tools. The toolbar supports:
- Text formatting: Bold, italic, underline, strikethrough, highlight
- Headings: H1, H2, H3
- Lists: Bullet, ordered, task/checkbox
- Block elements: Blockquotes, code blocks with syntax highlighting, horizontal rules
- Embeds: Images (via URL), links, tables (resizable)
- History: Undo/redo
The editor auto-saves with an 800ms debounce -- every keystroke resets a timer, and when you stop typing for 800 milliseconds, the content is persisted to the API. A status indicator shows "Unsaved changes," "Saving...," or "Saved" so you always know the state. This is the same pattern Confluence uses, and it's the right one for a writing tool.
Hierarchical Pages
The page tree is the defining feature that separates a knowledge base from a note-taking app. Pages can be nested to arbitrary depth -- a "Parent Page" contains a "Child Page" which can contain grandchildren, and so on. The sidebar renders this as a collapsible tree with expand/collapse toggles, and breadcrumb navigation at the top of the editor shows the full ancestor path with clickable links.
What's clever about Claude's implementation is that the API returns a flat list of all pages, and the tree structure is built entirely on the client side. This keeps the API simple (one endpoint, one query, no recursive joins) while giving the frontend full control over rendering the hierarchy. The tree construction runs in O(n) time -- one pass to index pages by ID, one pass to attach children to parents.
When you delete a page, its children become orphans (promoted to root level) rather than being cascade-deleted. This is a deliberate design choice: in a knowledge base, deleting a category shouldn't destroy all the content inside it. Confluence does the same thing with its "move to trash" behavior.
Architecture
Claude went with a notably leaner stack than the previous clones:
┌─────────────────────────────────────────────┐
│ Browser (SPA) │
│ React 18 + Vite + TipTap (ProseMirror) │
└──────────────────┬──────────────────────────┘
│ HTTP (port 3033)
┌──────────────────▼──────────────────────────┐
│ Express Server │
│ Serves React build + REST API (/api/*) │
└──────────────────┬──────────────────────────┘
│ SQL (in-process)
┌──────────────────▼──────────────────────────┐
│ SQLite (better-sqlite3) │
│ 2 tables, WAL mode, file-based persistence │
└─────────────────────────────────────────────┘
The big change from the previous clones: SQLite instead of PostgreSQL. No separate database container. No connection pooling. No TCP connections. The database is a single file on disk, accessed in-process through better-sqlite3's synchronous bindings. For a single-user knowledge base, this is exactly right. The entire data layer collapses to a file.
This means the Docker setup is a single container instead of two:
services:
app:
build: .
ports:
- "3033:3033"
volumes:
- wiki-data:/app/data
restart: unless-stopped
No database health checks, no depends_on, no separate volume for PostgreSQL data. One container, one volume, one command to start.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite 6, TipTap 2 (ProseMirror), lowlight |
| Backend | Node.js 20, Express 4, better-sqlite3 |
| Database | SQLite with WAL mode |
| Containerization | Docker (multi-stage build), Docker Compose |
| Testing | Jest + Supertest (API), Vitest (frontend), Playwright (E2E) |
The Smart Decisions
SQLite with WAL mode. Write-Ahead Logging allows concurrent reads while a write is in progress. For a single-user app with frequent auto-saves, this eliminates any possibility of read contention during saves.
Copy-on-write versioning. Every time a page is updated via the API, the backend automatically snapshots the previous title and content into a page_versions table before applying the update. Version history is free -- no explicit "save version" action needed, no UI complexity. The version history panel lets you browse all prior snapshots and restore with one click.
Debounced auto-save at 800ms. Fast enough that you never lose more than a sentence, slow enough that it's not firing on every keystroke. The status indicator provides continuous feedback without being distracting.
Client-side tree construction. The API returns a flat array. The frontend builds the tree in two passes: index by ID, then attach children. This means the backend never needs recursive queries or nested serialization. Adding, moving, or deleting pages just requires updating parent_id and position fields.
Declarative toolbar. The toolbar buttons are defined as a data array, not hardcoded JSX. Adding a new formatting option means adding an object to an array, not modifying component logic. This is the kind of extensibility pattern that makes the codebase easy to iterate on.
Database Design
Just two tables -- the simplest schema of any clone so far:
| Table | Purpose |
|---|---|
pages | Content storage with hierarchical structure (self-referential parent_id), position ordering, emoji icons, HTML content, timestamps |
page_versions | Append-only version history with title/content snapshots, cascading deletes |
Three indexes cover the hot paths: parent lookups (idx_pages_parent), timeline queries (idx_pages_updated), and version lookups (idx_versions_page).
The pages table uses ON DELETE SET NULL for the parent foreign key -- deleting a parent orphans children rather than cascade-deleting them. The page_versions table uses ON DELETE CASCADE -- deleting a page removes its version history, which is the right behavior (you don't want orphaned versions cluttering the database).
Lines of Code
| Category | Lines | Files |
|---|---|---|
| Backend (server, db, routes) | 257 | 3 |
| Frontend components | 669 | 7 |
| Frontend core (App, api, main) | 182 | 3 |
| CSS / Styles | 715 | 1 |
| Backend tests (Jest) | 84 | 1 |
| Frontend tests (Vitest) | 38 | 1 |
| E2E tests (Playwright) | 122 | 1 |
| Config / infrastructure | 148 | 6 |
| Total | ~2,100 | 23 |
At 2,100 lines, the Confluence clone is the leanest of the three -- roughly a third the size of the Trello clone (6,800 lines) and half the Harvest clone (4,700 lines). This makes sense: a knowledge base is architecturally simpler than time tracking with invoicing or a Kanban board with drag-and-drop. The complexity lives in the TipTap editor, which is a third-party library doing the heavy lifting.
The CSS at 715 lines covers the full layout, editor styling (ProseMirror content rendering, toolbars, menus), sidebar, version history panel, command palette, and responsive behavior. Not as extensive as the Trello clone's 1,448 lines, but comprehensive enough for a clean, usable interface.
Testing
Claude wrote 24 tests across three layers:
Backend API Tests (10 tests, Jest + Supertest)
- Health endpoint, empty page list, page creation with UUID
- Fetch single page, update page (title + content)
- Version history retrieval after updates
- Child page creation with parent_id
- Search (LIKE matching against title and content)
- Page deletion with 404 verification
The backend tests run against an in-memory SQLite database (:memory:), so they're fast and isolated -- no Docker needed.
Frontend Unit Tests (3 tests, Vitest + React Testing Library)
- Sidebar rendering, empty state display, new page button
E2E Tests (11 tests, Playwright)
- App loads with sidebar visible
- Empty state on first launch
- Page creation, title auto-save, child page creation
- Command palette (Cmd+K) with search
- Sidebar filtering
- Page deletion with confirmation dialog
- Toolbar formatting buttons present
- Page navigation
Feature Completeness
| Requirement | Delivered? |
|---|---|
| Rich text editing (WYSIWYG) | Yes |
| Text formatting (bold, italic, underline, etc.) | Yes |
| Headings (H1-H3) | Yes |
| Lists (bullet, ordered, task) | Yes |
| Code blocks with syntax highlighting | Yes |
| Tables | Yes |
| Images and links | Yes |
| Hierarchical page tree | Yes |
| Breadcrumb navigation | Yes |
| Auto-save with status indicator | Yes |
| Version history with restore | Yes |
| Full-text search | Yes |
| Command palette (Cmd+K) | Yes |
| Sidebar filtering | Yes |
| Page reordering | Yes |
| Emoji page icons | Yes |
| Docker deployment | Yes |
| File attachments | No |
| Page templates | No |
| Macro/plugin system | No |
| Advanced search (full-text indexing) | No |
Estimated coverage: ~80% of personal Confluence use. The missing features -- attachments, templates, macros -- are Confluence's enterprise differentiators. For personal knowledge management and documentation, everything I actually use daily is present: the editor, the page hierarchy, search, and version history.
Comparison: All Three Clones
| Aspect | Harvest | Trello | Confluence |
|---|---|---|---|
| Build time | 18 min | 19 min | 16 min |
| Tokens | ~106K | 137K | 106K |
| Lines of code | ~4,700 | ~6,800 | ~2,100 |
| Backend | Python/Flask | Node/Express | Node/Express |
| Database | PostgreSQL | PostgreSQL | SQLite |
| Frontend | React | React | React + TipTap |
| Tests | 32 | 52 | 24 |
| Docker containers | 3 | 2 | 1 |
The Confluence clone is the fastest, smallest, and simplest of the three -- which tracks with the application complexity. A knowledge base is fundamentally a tree of documents with a good editor. Claude recognized this and made appropriately lean choices: SQLite over PostgreSQL, a single container over two, and a 2,100-line codebase that does exactly what's needed without overbuilding.
The trend line is encouraging too: 18 minutes, 19 minutes, 16 minutes. The models are getting faster at this as I refine the process. The requirements documents are getting more precise, and the build prompts are more focused.
The Bottom Line
Three days, three SaaS replacements. Harvest for time tracking, Trello for project management, Confluence for knowledge management. Each built from a requirements document by Claude Opus 4.6, each running in Docker, each covering 80-97% of the features I actually use.
The Confluence clone is particularly satisfying because it demonstrates that AI code generation handles UI-complex applications -- not just CRUD forms and data tables, but a real rich text editor with formatting toolbars, hierarchical navigation, and auto-save. TipTap does the heavy lifting for the editor itself, but Claude made the right library choice, integrated it correctly, and built all the surrounding infrastructure (page tree, version history, search, command palette) from scratch.
The complete source code is available on GitHub. Clone the repo, run docker compose up -d, and start writing.
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 articulate them -- and built the application, which continues to be a pleasantly recursive situation.
