From a Blog Post to a SaaS: Building DocsLit Cloud in 24 Hours
I had no code. No plan. Just an idea that arrived at 5AM while reading about how MDN rebuilt their frontend.
It Started With a Blog Post
I was reading MDN’s engineering blog — a deep dive into how they rebuilt their entire frontend away from React, replacing it with native Lit web components.
The line that stopped me was this one:
“We don’t need a complex app powering the majority of the site. We essentially have islands of interactivity, which could easily all be implemented as web components.”
MDN — the definitive reference for web developers — had looked at their React-powered docs platform, decided it was the wrong tool, and replaced it with web standards. No JSX. No bundler. Just custom elements that the browser already knows how to handle.
I closed the article and thought: why does every documentation platform still require React?
Mintlify. Docusaurus. Nextra. Every major docs platform is a React framework with a Markdown plugin. If you use Vue, Svelte, or plain JavaScript, you are still running a React build pipeline just to write documentation.
That felt wrong. And it felt like a problem worth solving.
It was 5AM. The Replit 10 Year Buildathon had just started. I had 24 hours.
I had no existing code. No component library. No database schema. Nothing.
I opened Replit and started typing.
The Idea
DocsLit is a documentation framework built on native Lit web components instead of MDX.
The pitch is simple. In MDX you write this:
import { Button } from '../components/Button'
import { Alert } from '../components/Alert'
<Button variant="primary">Click me</Button>
In DocsLit you write this:
<wc-button variant="primary">Click me</wc-button>
No imports. No JSX. No bundler. Just a tag sitting in your Markdown file, and the browser handles the rest.
This works because Lit web components are native browser custom elements — a W3C standard. They run in React, Vue, Svelte, or a plain HTML file. The docs framework stops being a React application and becomes a build tool that gets out of your way.
The MDN team figured this out for their own site. I wanted to make it a product anyone could use.
Hour 0: Nothing
I want to be clear about the starting point. There was no existing codebase. No component library I was extending. No prior work I was polishing up.
At hour zero I had a blank Replit project and an idea from a blog post.
That is the before state.
Hours 0 to 4: The Foundation
The first decision was database schema. I designed it to support everything the product would eventually need rather than just what the first feature required.
Authentication fields went in immediately alongside billing fields — plan tier, Stripe customer ID, subscription ID, password reset tokens. Designing the schema to hold billing state from the start meant I would never need a painful migration later.
Four authentication endpoints came next:
POST /api/auth/signup— input validation, bcryptjs password hashing, session creationPOST /api/auth/login— credential verification, session establishmentPOST /api/auth/logout— session destructionGET /api/auth/me— protected route returning the current user
Sessions are persisted to PostgreSQL via connect-pg-simple. That one decision is the difference between a demo and a production system — sessions survive server restarts, which means users stay logged in when the server redeploys.
By hour 4: A user could sign up, log in, and stay logged in. The scaffolding for everything that followed was in place.
Hours 4 to 8: Real Payments
Stripe integration is where most hackathon projects cut corners. Placeholder buttons. Hardcoded plan names. Webhook handlers that technically exist but do not actually sync to the database.
I built it properly.
The checkout flow creates a real Stripe checkout session and redirects the user to payment. After payment, Stripe fires a webhook. The webhook handler verifies the signature, processes the event, and writes the subscription ID and plan tier to the database. Users can manage their subscription through the Stripe customer portal — upgrade, downgrade, cancel — entirely self-service.
The part that matters most is that the webhook handler is idempotent. Stripe retries failed webhook deliveries. That means your handler will sometimes process the same event twice. If it is not idempotent, users get double-charged or plans fail to activate. Getting this right is not optional.
Three pricing tiers: Free, Starter, and Pro. All environment variables wired up for production from day one.
By hour 8: Users could pay for a plan and have it immediately reflected in their account.
Hours 8 to 16: 41 Web Components, Made Responsive
This is where I built the actual product.
Starting from nothing meant every component needed to be written from scratch using Replit Agent. Not generated once and accepted — iteratively designed, prompted, refined, and tested.
The component library ended up with 41 Lit web components: WcTable, WcCodeBlock, WcAccordion, WcCard, WcTiles, WcBanner, WcEndpointRequest, WcPanel, WcTree, WcUpdate, WcView, WcExpandable, and more.
Each one needed to work at three viewport sizes: 480px phone, 640px tablet, and full desktop. The MDN article had been explicit about this — the whole point of web components is that they are self-contained islands. Each one needs to handle its own responsive behaviour internally.
The approach I used with Replit Agent here was architectural rather than mechanical. Instead of prompting Agent to fix one component at a time, I asked it to analyse the entire library, identify every responsive pattern that needed changing across all components, and apply coordinated fixes in parallel across all affected files.
The patterns were consistent:
| Property | Desktop | Mobile |
|---|---|---|
| Padding | 16 to 18px | 12 to 14px |
| Font size | 13 to 14px | 12 to 13px |
| Grid columns | 2 to 3 | 1 column |
| Flex direction | row | column with wrapping |
| Code overflow | hidden | scroll |
During this phase I also found a bug that had crept into WcStep — a global counter that never reset between separate step sections, so a document with two <wc-steps> blocks would number the second one starting from wherever the first left off. The fix added support for manual numbering as a bonus.
By hour 16: 41 components, zero layout shifts, perfect rendering across all device sizes.
Hours 16 to 24: Integrations and a CLI
With the core product working, three integrations went in:
Resend for transactional email — welcome messages on signup, password reset flows, invoice notifications.
Cloudflare R2 for file storage — presigned URLs for secure asset uploads, connected via the S3-compatible API so assets go to Cloudflare’s edge rather than the application server.
Then the thing I had not planned but am most proud of: a full CLI tool.
A documentation framework without a CLI is not a framework. It is a website. I used Replit Agent to build the complete developer experience:
docslit init # scaffold a new project
docslit dev # local preview server
docslit build # generate static HTML output
docslit login # authenticate with DocsLit Cloud
docslit publish # deploy to DocsLit Cloud from terminal
The publish command zips the build output, sends it to the DocsLit API with the user’s token, and returns a live URL. The entire flow from terminal to live site takes under ten seconds.
By hour 24: A production SaaS platform was live. Not a demo. Not a prototype.
How Replit Agent Changed What Was Possible
I want to be specific about this because “I used AI” is not a useful description.
Replit Agent was used in four distinct ways during the build.
The obvious one is code generation — scaffolding endpoints, writing middleware, generating TypeScript interfaces. Fast, but not the interesting part.
The genuinely transformative use was pattern recognition across a large codebase. When I needed to make 41 components responsive, I could not hold all of them in working memory simultaneously. Agent could. Asking it to analyse the entire library and produce a coordinated fix plan turned what would have been an eight-hour sequential task into three hours of parallel execution.
After large refactors, Agent ran TypeScript validation passes that caught interface mismatches before they reached production. After the responsive overhaul touched eighteen files simultaneously, those checks caught three type errors that would have appeared as runtime bugs.
The fourth use was environment debugging — getting CORS, session cookies, Stripe webhooks, and R2 presigned URLs working correctly across development and production involves a specific kind of tedious configuration debugging. Agent identified a missing ALLOWED_ORIGINS configuration that was silently blocking cross-origin requests without surfacing an obvious error.
The pattern throughout: I made architectural decisions. Agent handled execution at scale.
The After State
At hour zero: a blank project and an idea from a blog post.
At hour 24:
- Full authentication with bcryptjs hashing and PostgreSQL session persistence
- Stripe billing with checkout, webhooks, and customer portal across three pricing tiers
- 41 Lit web components responsive across 480px, 640px, and desktop
- Resend transactional email pipeline
- Cloudflare R2 file storage with presigned URLs
- A complete CLI with init, dev, build, login, and publish commands
- Deployed to production with CORS, security headers, and rate limiting
Every flow works end to end. There are no placeholder buttons. No broken paths.
Why the Idea Was Right
The MDN engineering team spent months rebuilding their frontend away from React. Their conclusion was that web components are simply the better tool for content-heavy sites where interactivity is the exception rather than the rule.
Documentation sites are exactly that kind of site. Mostly static content. Islands of interactivity. No need for a React application to assemble them.
DocsLit is that insight turned into a product. Write Markdown. Drop in web component tags. Deploy anywhere. No React required.
The framework is open source. Self-hosting is free forever. DocsLit Cloud handles the deployment for teams who want it.
The MDN team rebuilt a website. I built a platform for everyone else to do the same thing.
Get started at docslit.com
Built during the Replit 10 Year Buildathon, May 2026. Inspired by MDN’s frontend deep dive.