On August 7, swyx floated an idea on X: his team was about to pay over $40k a year for an enterprise SaaS they had never used and would never be able to customize, so instead he proposed a competition. Clone the product in a weekend, any coding agent, any model. His team, the actual prospective customer, evaluates the results. Winner gets $10,000 and a writeup, all code gets open sourced. A day later the brief went live: the target was Sessionboard, a speaker and session operations platform for conferences.
I entered. My submission is bodo: CFP forms with conditional logic, a speaker portal, review and scoring, an agenda builder with conflict detection, automated emails with calendar invites, embeddable schedule widgets, and a public API, built in four days across 351 commits. The winner isn’t decided as I write this.

It’s a field guide, because bodo was my second clone this summer. In late June I built warpdrive, a self-hosted replacement for the business-development half of Pipedrive: pipelines, a deal workspace, contacts and organizations, two-way Gmail, notifications, stats. That one took 1,353 commits over 46 days, and about 1,150 of them landed in the first two weeks; the rest was a month of polish, hardening, and honest testing. (Both public repos are squashed mirrors, so the full commit histories live in the private originals.)
Two clones of two different products, same method, same traps. This is the playbook, the sins, and the testing stack that came out of both.
Why clone at all
The case for a custom-built, self-hosted, open source alternative used to lose on one number: engineering cost. A CRM or an event-ops platform is years of accumulated screens, and no small team was going to rebuild that to save a subscription.
Coding agents changed the input costs, and that flips the calculation for a specific tier of SaaS: the high-margin workflow tools that are, underneath the sales motion, forms and tables and pipelines wired to email. When the rebuild is days instead of years, the old tradeoffs invert. Your data sits in your own Postgres instead of behind an export button. The feature you always wanted is a prompt away instead of a roadmap request that dies in a portal. Nobody meters you per seat. When the code is open source, the thing you built compounds: warpdrive runs from a single Docker Compose file on one box, and anyone can stand up the same stack without asking anyone’s permission. Cloning does make you the maintainer, and some upkeep is real, but the same agents that built the thing in days handle patches and small features as they come up, so maintenance in the agent era is a chore rather than a second job.
That’s the praise part of this article, and I mean it. The interesting part is what cloning actually takes, because the naive version, “point an agent at some screenshots and say make me this,” produces a demo, not a replacement. The people who will use your clone do real work in the original every day. Their muscle memory is part of what you’re replacing.
The playbook
1. Capture the reference before writing any code
The decision that most predicts whether a clone lands is made before the first commit: how well you capture the thing you’re cloning.
For bodo, capture ran on several sources at once. Forty screenshots of the real Sessionboard were transcribed into 3,448 lines of control-by-control audits: every label, tab, default, and menu entry, inventoried. The screenshots carried the customer’s own red annotation stickers (“must have”, “NOT NEEDED”), which is priority data sitting inside the pixels. A walkthrough video became a timestamped transcript, and that transcript held requirements no screenshot shows, including the customer complaining three separate times about how slow the incumbent is. Every clarification the customer gave got logged with an “impact here” line, because an offhand answer about calendar invites turned out to define how the whole .ics pipeline had to work.

Then there’s the source I missed at first, and it deserves a confession: the target’s own public surface. The help center, the marketing pages, the API docs, and above all the changelog, whose animated GIFs show panels that static screenshots caught collapsed. Mining those filled in more than layouts. Two help-center articles contradicted the data model my first draft assumed (an event has many portals, and membership is assigned by ordered filters, not by hand), and that’s a schema decision, not a cosmetic one. Check the vendor’s own docs before writing a line of spec.
Warpdrive could go a step further because I had a live account to clone from. The setup was two Chrome instances driven over the debugging protocol, one logged into real Pipedrive, one pointed at the clone, with scripts that dump every visible element’s layout, typography, and color from both and diff them mechanically. That toolchain grew to 21 scripts, and the growth pattern is the lesson: each script exists because the previous approach shipped a visible bug. A style differ missed a card rendering the literal string “Person” instead of a person’s name, so a content-correctness linter got written. A DOM dump only sees the default state, so a probe script that clicks every trigger and diffs what opens got written. The rule that survived all of it: prose is a claim, a diff row is a fact. The one time a field-by-field diff table got hand-summarized into spec prose, the summary was misread and implemented wrong.
Both projects converged on the same discipline from opposite directions. If you captured it, transcribe it exactly. If you didn’t capture it, don’t build it, because there is nothing to compare against, and inventing a checkbox means scoring yourself against your own invention.
2. Write specs with a precedence rule
Capture produces piles of overlapping truth, and agents need to know which pile wins. Bodo’s answer was three documents with explicit, domain-scoped precedence: a product spec controls scope and acceptance, a build spec controls architecture and schema, and the parity audits control presentation (layout, labels, copy, defaults) and beat the build spec on all of it, because they were read off the real product. All three beat the agent’s instincts about how a form builder “should” work. The line in the spec says it plainly: this is a clone, not a reinterpretation.
The precedence rule itself needed a bug fix, which tells you something. The first version said “parity docs always win,” and that was too broad, because the audits mix observed behavior with inference, and a blanket rule let an uncertain reading of a screenshot override the data model. Precedence by domain fixed it.
The other spec lesson: plans lie about code that doesn’t exist yet. Warpdrive was built in five phases, each planned before the previous phase was implemented, and every phase plan confidently referenced APIs that never came to exist in that shape. The fix was mechanical: each phase opened with a pre-flight reconciliation table, “the plan assumes this function, reality is that one,” corrected by hand before any agent got dispatched. Budget for that table. It will never be empty.
3. Install guardrails before features
Both repos run blocking hooks: not advice in a doc, but scripts that reject the agent’s edit and log the event. A 300-line file-size cap fired 581 times in bodo’s four days, and you can watch it doing architecture in the commit history, forcing navigation trees, column definitions, and type modules into separate files at the moment they got too big. Lint rules written as AST selectors ban whole categories of edit outright: hand-rolled buttons and dropdowns, hand-built modal overlays, raw error throws without a registered error ID. A read-before-edit hook stops the agent from patching a file it never opened.
The guardrail that pays for this article is quieter: a mandated implementation-notes file for every spec, appended as decisions happen rather than reconstructed at the end. Every design decision where the spec was ambiguous, every deviation, every open question, written down in the moment. Nearly every war story in this piece exists because that convention forced someone to record it while it was fresh, including the embarrassing ones.
4. Build in parallel lanes
Bodo ran six git worktrees at peak, warpdrive five, each an agent lane merging back into main continuously. The split that worked was by file ownership rather than by feature, because several findings usually share one root cause in one file, and two agents editing that file from different feature briefs will collide.
Parallelism has one failure mode worth naming, because it cost bodo a finding. A defect list doubled as the work queue that parallel agents were dealt from, and one item existed in the prose but not in the table. It was never assigned, and no agent could notice, because no agent reading its own brief can see a gap in someone else’s. When a document is both the record of what was found and the queue of what to do, those two halves can disagree silently.
The sins
Even with capture, specs, precedence, and blocking hooks, agents commit the same sins in every project. I’ve now watched them recur across two clones, which is enough to call them a taxonomy rather than bad luck.
Hand-rolling what’s already installed. Warpdrive’s early phases hand-wrote every UI primitive while the plans imported components from a directory that existed and was empty. The result was three button styles, four dropdown implementations, and inconsistent keyboard and focus behavior that took longer to unpick than installing the component library would have taken. The migration to real primitives happened later, at full price, and then the ban on hand-rolling was written into lint, retroactively. Bodo inherited those bans on day one, and its rules file names the earlier failure as the reason. The lesson generalizes past UI kits: a doc that says “use the installed thing” does not hold, because writing a raw element inline is always faster than checking what’s installed. Only a rule that blocks the edit holds.
The unwired feature. This is the signature agent failure, and it happened three separate times in bodo alone. The calendar invite, a hard requirement, is the purest specimen: the invite builder produced valid calendar content and was unit tested, the attachment logic was tested, both email providers encoded it correctly, and nothing anywhere in the system ever created the record that triggers a send. Every call site passed the literal value false. The field that would carry the calendar UID was read in four places and written in none. The test suite was green throughout, because nothing asserts that a producer exists. Elsewhere, a reminder cron had been sweeping an empty list since the day it shipped because nothing ever created a draft, and a bulk-download feature was about 85% built, streaming ZIP writer and all, with no reachable entry point. Agents build the consumer side, test the consumer side, and report done. The wiring is where they quietly stop.
The dead or lying control. Warpdrive’s deal menu rendered “Delete deal” for every user unconditionally, which cosmetically masked a real permission bug underneath. Bodo’s “Preview email” button was enabled for rows the underlying action refuses, and clicking it took down the whole page with an uncaught error. The product-critic report distilled the general rule: a ticked checklist item is a claim about a control existing, not about what it renders. Essentially every defect the later test passes found sat behind a checklist line that was already ticked.
Silent success. The most dangerous sin, because every signal you’d normally trust reads green. A page that returns 200 with its dynamic half missing looks better than a crash and is worse. A bulk action that guards per-row failures and then toasts success unconditionally makes nine-of-ten look identical to ten-of-ten, which in bodo’s case was a regression in exactly the thing an organizer most needs to know. An email API accepted raw calendar text, returned 200 with a message ID, and delivered an invite that never rendered. Agents optimize for the appearance of done, and most infrastructure will happily co-sign.
Faked parity. When the reference shows a control and the subsystem behind it doesn’t exist, the path of least resistance is rendering something that looks right and does nothing. Bodo’s backlog file carries a comment aimed squarely at future agents: these features are tracked here “so the parity pass doesn’t fake them.” The honest alternatives are an explicit stub page (bodo renders out-of-scope nav entries that land on a page saying so, because muscle memory is part of the product) or a written deferral with a reason. Warpdrive kept a numbered register of exactly these decisions, including one it later reversed, with both the decision and the reversal on the record.
How to test a clone
The testing stack follows from the sins, layer by layer, each catching what the one below structurally cannot. The through-line: a green suite is a claim, not evidence.
Unit tests, with hand-computed expectations. Both repos run thousands of them (5,224 in bodo, 3,813 in warpdrive), concentrated on logic that fails silently: conflict detection, score aggregation, calendar sequence rules, queue selection. Two disciplines make them worth having. Expected values are worked out by hand in a comment next to the assertion, because recomputing the formula inside the test only proves the test and the module share a bug. And every regression test gets validated against the old code by reverting the fix and watching it fail. Necessary, and nowhere near sufficient: warpdrive’s 3,813 tests all passed while a regular user could delete any deal they were allowed to edit, with no delete permission ever checked.
The product-critic pass. Before anyone else touched bodo, a browser agent walked the deployed app as three personas (organizer, reviewer, and a speaker reached through the impersonation feature) with one rule that changes everything: it wrote a predicted result for every interactive element before clicking it, and kept the matches as well as the misses so the coverage map stays honest. The pass found 12 broken things, 12 missing, 20 inconsistent, 4 unwired, and 22 verified working, and its top finding was the kind no code review surfaces: the two “judge this submission” screens, the core loop of the entire product, were read-only. An organizer could open a submission and not decide on it. The report also had a “not tested, and why” section and a log of every mutation it made to shared data, which is what separates a critique you can act on from a vibe.
The QA agent fleet. Warpdrive’s version scaled the same idea: 373 user stories catalogued from the app, then 27 browser-driving agents testing them against the real product for about 3.1 million tokens and four hours of wall clock. That fleet found the permission bug the unit tests missed, by doing the one thing unit tests can’t: signing in as a second, less-privileged user and trying things. It also delivered a meta-lesson at no extra charge: the fleet’s own environment was the flakiest thing in the run. At 10-way concurrency the browser daemon degraded, and one agent spent its budget testing a dev server that was serving a different worktree than intended. Verify the harness before trusting the harness’s findings.
The geometry gate. Warpdrive’s core build took two weeks; chasing visual parity took most of the following month, and it only converged once “looks right” was replaced with a gate. The end state: scripts that extract every visible element’s box geometry, typography, and color from the clone and from live Pipedrive, diff them against approved golden baselines, and exit nonzero on any unwaived difference, with waivers recorded in a file with written reasons. What makes this layer worth writing about is that its blind spots are documented as dated misses, and each one reshaped the tooling. Region-scoped diffs were blind to anything outside every region, which let the clone ship a thread reader missing an entire folder-rail column that the reference keeps; diffing control inventories is not layout parity. Diffs keyed on text couldn’t see a wrapper element that carries none, which let a missing border around the compose editor through. The field set matching said nothing about order, which let a reordered footer ship clean. And for a while nothing re-diffed the built result after changes, so a whole composer redesign drifted for days, which is how “a screenshot pass is not a regression guard, a test is” got written into the docs. Even the screenshots lie: pages that scroll inside an inner container truncate silently in full-page captures, which produced confidently wrong findings like counting two tabs where there were six. Geometry parity is a grind, but it’s a measurable grind, and measurable is what keeps agents from declaring victory early.


Verify at the real boundary. Every email trigger in bodo had been tested up to the send call and no further, because there was no mailbox to test into. So the build got a second email provider whose entire purpose is that an API call creates an inbox and an API call reads it back, and then six flows were driven through the real UI and verified by reading the delivered message, not the outbox row: the magic link actually followed, the calendar invite decoded out of raw MIME, the reschedule confirmed as a sequence bump on the same UID. Two defects surfaced that were unreachable from any unit test, and both were obvious within seconds of looking at a real mailbox. Whatever your product’s real boundary is (an inbox, a webhook receiver, a calendar client), some test has to cross it.
A second model as adversary. Both repos used Codex as a standing adversarial reviewer, wired into plans as an explicit checkpoint; bodo’s history has ten commits titled some variant of “fix N defects found by Codex review.” The clearest win: an impersonation design whose security argument I had reviewed and accepted. The comment reasoned that the impersonation token grants nothing extra because exiting impersonation re-reads memberships. The second model pointed out that re-reading memberships answers “does that user still hold admin,” not “is the bearer of this cookie that user,” so a copied speaker-level cookie could be exchanged for the originating admin’s session. Two independent reviews found different halves of the bug surface, which is the whole argument for having two.
Where the moat actually is
Swyx framed the competition as a search for a boundary: keep doing this with more ambitious targets “until we find the boundary of what saas is still hard to kill in a weekend.” Two clones in, here’s where that boundary looks like it runs.
Everything that is screens over a database fell in days: form builders, pipelines, review workflows, scheduling boards with conflict detection, email automation, embeddable widgets, public APIs. What got consciously deferred, in both projects, was everything whose value lives outside the codebase. Two-way calendar sync is a subsystem with a fleet of external providers, not a feature. A meeting scheduler needs real availability and booking, which is a product in itself. Payments, exhibitor and sponsor management, multi-language, an integrations marketplace: each deferral is written down with a reason, and the reasons rhyme. The hard residue of SaaS is the network around the software: other people’s calendars, other vendors’ APIs, someone contractually on the hook when it breaks.
The other honest boundary is inside the clones themselves. Both repos carry a section for defects found and deliberately not fixed, on the stated principle that an unrecorded known defect is worse than an open one. Warpdrive has an intermittent first-load failure whose root cause was never established, and the handoff note says exactly that, because “the read can no longer take a page down” and “nobody knows why it failed” are different claims and the next person needs to know which one is true. Trust in a weekend clone comes from being able to read its defect ledger, not from the ledger being empty.
So: can you clone pretty much any SaaS? The workflow tier, the one where you’re paying tens of thousands a year for forms, pipelines, and emails you can’t customize, yes, demonstrably, in days. It takes capturing like an archivist, speccing with a precedence rule, blocking the sins with hooks instead of asking nicely, and testing from the outside in until the evidence, not the agent, says done. Both clones are open source, the competition thread has the rest of the entries, and the playbook transfers. The next $40k renewal quote that lands in your inbox is a brief.
And if you have one of those quotes and would rather not walk the playbook alone, I take on these builds. Tell me what you’re paying for and what it would take to kill it: I’m @sawinyh on X and on LinkedIn.