3,704 Commits Later: From create-next-app to Production as a Solo Dev
The Commit That Started Everything
On March 11, 2025, I ran create-next-app and pushed the result. The commit message was exactly what you’d expect: “Initial commit from Create Next App.” The second commit added CDK. The third added ElectroDB. Three commits in, and the skeleton of what would become a multi-portal utility marketplace was already taking shape - even if I didn’t fully know it yet.
Fourteen months later, on May 4, 2026, the platform went live. Between those two dates: 3,704 commits, 99% of them mine. The other 1% split between a Cursor agent (13 commits), an OpenCode assistant (6), some Nx Cloud bot noise, and a Tessl bot. This is the story of what that journey actually looked like.
The Shape of the Thing
The product is a marketplace that connects companies needing utility infrastructure work with accredited contractors who can deliver it. Think of it as the connective tissue between “we need gas pipes installed” and “we’re certified to install gas pipes.” The platform handles project submissions, contractor matching, quoting, contract signing, job tracking, and payment reconciliation.
That translates to five distinct web portals: an admin portal for internal staff, a developer portal for companies submitting work, a partner portal for contractors, an ops portal for operational tooling, and a marketing hub. Each has its own auth flows, its own data model concerns, and its own user expectations. It’s not one app. It’s five apps sharing a backend.
The Monthly Heartbeat
The commit history tells its own story:
| Period | Commits | What was happening |
|---|---|---|
| Mar-Jun 2025 | 47 | Exploring. Next.js, CDK, basic data models. Slow, deliberate. |
| Jul 2025 | 15 | The auth provider roundtrip. Cognito to WorkOS, back to Cognito. |
| Aug 2025 | 109 | Explosion. Monorepo tooling (Turbo then Nx, same day). Cursor AI enters. |
| Sep-Nov 2025 | 474 | Sustained build. Cycled through AI tools. Core features taking shape. |
| Dec 2025 | 163 | Backend hardening. DynamoDB patterns solidifying. |
| Jan 2026 | 458 | Something clicked. Velocity doubled. |
| Feb 2026 | 309 | Self-hosted runners. Infrastructure maturing. |
| Mar 2026 | 742 | Rust lambdas written and torn out. The sprint begins. |
| Apr 2026 | 1,145 | The final push. 38 commits per day average. |
| May 1-6 | 242 | Launch and immediate post-launch. |
That April number is insane. 1,145 commits in 30 days. I was averaging 38 commits a day, and that’s not gaming the count with atomic commits for vanity metrics. That’s real work - features, fixes, infrastructure, CI pipeline fixes, more CI pipeline fixes, and the occasional “why did I break this” revert.
The Architecture That Survived
The stack at launch looks nothing like what I started with. Almost every major technical decision was revisited at least once:
Frontend: Started with Next.js, ended with React + Vite across all five portals with Mantine UI. The SSR story for Next.js didn’t justify its complexity for what are essentially authenticated SPAs behind login walls.
Auth: Cognito, then WorkOS, then back to Cognito. The WorkOS detour taught me what I actually needed from an auth provider, which turned out to be “less than I thought.” I’ll write that story up properly - it’s a good lesson in over-engineering.
Monorepo: pnpm workspaces, then briefly Turbo, then Nx (on the same day as the Turbo attempt), then back to Turborepo eight months later. Nx is powerful but the configuration surface area was enormous. Turbo’s simplicity won out, especially once I got the remote cache working and sorted out the BODE pattern.
Backend: AWS CDK from day two. Lambda functions on Node.js 22, DynamoDB single-table design, EventBridge for async workflows. This is the part that barely changed. CDK had its sharp edges - the CloudFormation export lock incident cost me a day - but the core bet on serverless was correct for a solo developer. No servers to manage means no 3am pages.
The Rust detour: In March 2026, we wrote six Lambda functions in Rust. I decided they were solving a problem I didn’t have, and we rewrote them all in TypeScript within three weeks. Classic premature optimisation dressed up as “doing it right.”
CI/CD: From manual deploys to fully automated continuous delivery, including self-hosted GitHub runners on AWS. The runner infrastructure alone was a significant sub-project. Spot instances, auto-scaling groups, AMI pre-baking, OIDC authentication across 8 AWS accounts managed by org-formation. The CI story is really three stories: making it work, making it fast, and making it reliable.
The ops surprise: The most unexpected piece was the AI-powered ops portal. An agent with persistent memory backed by Bedrock (Claude Haiku) and LanceDB for vector search, connected to WorkMail for email handling. It started as an experiment and became genuinely useful for operational tasks. Event-driven audit logging feeds it a stream of everything happening in the system.
The AI Tools Question
I’ve used AI coding tools for the entire build. Cursor from August 2025. Then a parade of alternatives - Kiro, OpenSpec, OpenCode, BMAD - each promising something slightly different, each falling short in its own way. I’ll write the full comparison separately. Where I landed: Claude Code with a carefully curated set of workflow skills and Tessl for library management.
Here’s what I’ve learned about AI-assisted development over 14 months:
It doesn’t replace thinking. Every time I let the AI drive without clear direction, I got code that looked right and was subtly wrong. The auth provider roundtrip? Partly caused by trusting an AI recommendation without interrogating the reasoning. The Rust detour? Same pattern. “This is a Lambda function, you should write it in Rust for performance” sounds smart until you realise your Lambda processes 12 requests per minute and the CI penalty of compiling Rust on every build costs more than the execution time you save.
It’s transformative for the boring middle. The gap between “I know exactly what this should do” and “it’s done and tested” is where AI shines. Boilerplate. Migrations. Test scaffolding. CRUD endpoints where the pattern is established and you’re just varying the entity. I could not have maintained this velocity alone. 3,667 commits from one person in 14 months is not normal human output.
The workflow matters more than the model. The jump from “use AI to autocomplete code” to “use AI agents in worktrees with structured task management” was bigger than any model upgrade. Having agents that understand your codebase conventions, that check their own work against acceptance criteria, that operate in isolated git worktrees so they can’t corrupt your main branch - that’s the real multiplier. The model is table stakes. The workflow around it is the edge.
Trust is earned through automation, not vigilance. Early on, I reviewed every line before committing. That doesn’t scale. What scales is investing in automated testing and CI/CD that catches problems before they reach production. Once you have a pipeline you trust, you can let the AI move faster and focus your review time on the things that matter: architecture decisions, security boundaries, and the occasional “why does this exist?” moment. The goal isn’t to read every diff. It’s to build a system where you don’t have to.
The False Starts
Honesty time. Not everything was a clean arc from problem to solution:
- WorkOS (Jul 2025): Migrated to it. Migrated back within a month. Cost: ~2 weeks of total effort.
- Nx (Aug 2025 - Apr 2026): Eight months. It worked, but the configuration complexity was a constant tax. Every new package meant 15 minutes of boilerplate.
- Rust Lambdas (Mar 2026): Three weeks to build, three weeks to replace. Net value: I learned some Rust.
- eSignatures.io (launched with it, replaced Apr 30): The contract signing service worked until it didn’t. Replaced with an in-house signing ceremony four days before launch. That was a fun weekend.
- Three different AI workflow tools (Sep-Nov 2025): Kiro, OpenSpec, BMAD. Each installed, evaluated, and discarded. The pattern that worked was building custom skills on top of a capable base model, not adopting someone else’s opinionated framework.
Each of these felt like wasted time in the moment. In retrospect, they were all necessary for understanding what the right solution actually looked like. You can’t evaluate alternatives you haven’t tried.
The Final Sprint
April 2026 was a different kind of month. 1,145 commits. The commit messages tell the story: feature flags going in, smoke tests being written, CD pipelines being hardened, edge cases being found and fixed, that CloudFormation export lock that blocked a deploy for a day. The last two weeks before launch were the most focused engineering work I’ve ever done.
The thing that made it possible was the accumulated infrastructure. By April, the monorepo was clean. CI was fast. Deploys were automated. Feature flags via GrowthBook meant I could ship incomplete work without risking the live system. The investment in infrastructure wasn’t paying dividends before - it was paying them now, all at once, when velocity mattered most.
On May 4, production went live. The deploy was unremarkable. Merge to main, staging auto-deploy, smoke tests pass, production promote. Exactly like the hundreds of deploys before it, except this time real users would see it.
What I’d Tell Someone Starting This
If you’re considering building a multi-tenant SaaS as a solo developer:
Invest in CI/CD early. I wish I’d built the CD pipeline in month 3 instead of month 12. Every month of manual deploys was a month of accumulated friction and deployment anxiety. Automated deploys aren’t a luxury - they’re what let you ship 38 commits a day without losing your mind.
Single-table DynamoDB is worth the learning curve. The access pattern thinking it forces on you pays off enormously. No migrations. No connection pool management. Predictable costs. It’s not right for everything, but for a multi-tenant SaaS with well-defined access patterns, it’s ideal.
Feature flags from day one. I added GrowthBook late. Every feature shipped before flags was a feature shipped with a prayer. Now nothing user-facing goes out without a flag. The peace of mind is worth more than the implementation cost.
Don’t optimize prematurely, in any dimension. Not performance (Rust lambdas). Not abstraction (Nx’s project graph for 8 packages). Not auth features (WorkOS’s enterprise SSO for a product with zero enterprise customers). Solve the problem you have today with the simplest thing that works.
AI tools are a force multiplier, not a replacement. They multiplied my output by maybe 3-5x on good days. They also introduced bugs I wouldn’t have written myself. The net is strongly positive, but only because I maintained the discipline to review everything and understand the system deeply enough to catch the subtle mistakes.
3,704 Commits Later
The platform is live. Real companies are submitting real projects. Real contractors are quoting on real work. The system I built processes actual transactions in a regulated industry.
It’s not done. Software is never done. But the gap between “Initial commit from Create Next App” and “production system handling real business operations” has been closed. Fourteen months, one developer, a lot of AI assistance, and more wrong turns than right ones.
The next post in this series will be about the auth provider roundtrip - the full story of why I moved to WorkOS, what I learned there, and why I moved back to Cognito. It’s a good case study in how “better” isn’t always better when you factor in integration complexity and actual requirements.
For now, I’m going to enjoy the quiet satisfaction of a production deploy that just works.
3,704 Commits Later: What a Year of Solo SaaS Development Actually Looks Like
The Commit That Started Everything
On March 11, 2025, I created a new project from a template and pushed the result. The commit message was exactly what you’d expect: “Initial commit from Create Next App.” The second commit added the infrastructure code. The third added the database library. Three commits in, and the skeleton of what would eventually become a live marketplace was taking shape, even if I didn’t fully know what it was yet.
Fourteen months later, on May 4, 2026, the platform went live. Between those two dates: 3,704 commits, 99% of them mine.
What We Actually Built
The product is a marketplace connecting companies that need utility infrastructure work with accredited contractors who can deliver it. The platform handles the full lifecycle: project submissions, contractor matching, quoting, contract signing, job tracking, and payment reconciliation.
That translates to five separate web portals: one for internal staff, one for companies submitting work, one for contractors, one for operational tooling, and a marketing site. Each has its own login flows, its own data concerns, and its own user expectations. It’s not one app. It’s five apps sharing a backend.
The Monthly Heartbeat
The commit history tells its own story about how the work actually went:
| Period | Commits | What was happening |
|---|---|---|
| Mar-Jun 2025 | 47 | Exploring slowly. Data models, basic structure. |
| Jul 2025 | 15 | Auth provider detour (switching back and forth). |
| Aug 2025 | 109 | Things accelerated. AI coding tools entered the picture. |
| Sep-Nov 2025 | 474 | Sustained build. Core features taking shape. |
| Dec 2025 | 163 | Backend solidifying. |
| Jan 2026 | 458 | Something clicked. Velocity doubled. |
| Feb 2026 | 309 | CI infrastructure. |
| Mar 2026 | 742 | Wrote and then deleted a bunch of Rust code. The real sprint begins. |
| Apr 2026 | 1,145 | The final push. 38 commits per day average. |
| May 1-6 | 242 | Launch and immediate post-launch. |
That April number is absurd. 1,145 commits in 30 days averages to 38 per day. And these weren’t trivial commits inflated for vanity metrics. That was real work: features, fixes, infrastructure, CI pipeline fixes, more CI pipeline fixes, and the occasional “why did I break this” revert.
The Architecture That Survived
The stack at launch looks almost nothing like what I started with. Nearly every major technical decision got revisited at least once.
The frontend started with Next.js and ended with a simpler setup using React and Vite across all five portals. The more complex approach wasn’t justified for apps that are essentially just behind-login tools.
Authentication went from AWS Cognito, to a third-party service called WorkOS, and back to Cognito. The detour taught me what I actually needed from an authentication provider, which turned out to be considerably less than I thought. Classic over-engineering.
Monorepo tooling bounced between three different tools. Started with one, switched to another on the same afternoon (yes, really), used that for eight months, then switched back to the first one. Simplicity eventually won.
The backend was the one part that barely changed. AWS serverless infrastructure from day two. Database on DynamoDB. Events flowing through AWS EventBridge. The bet on serverless was correct for a solo developer: no servers to manage means no middle-of-the-night emergency pages.
The Rust detour deserves its own mention. In March 2026, we built six backend functions in Rust. I decided three weeks later that they were solving a performance problem that didn’t exist, and we rewrote them all in TypeScript. Classic premature optimisation with extra steps.
CI/CD went from me manually deploying things to fully automated continuous delivery, including custom CI infrastructure on AWS. The CI story alone is three separate sub-stories: getting it working, making it fast, and making it reliable.
The unexpected highlight was the AI-powered operations portal. An AI assistant with persistent memory, connected to our email system, able to search through historical emails and answer questions. It started as an experiment and became genuinely useful.
The AI Tools Question
I’ve used AI coding tools for the entire build. Starting in August 2025, I cycled through Cursor and then a parade of alternatives, each promising something different and each falling short in its own way. I’ll write the full comparison separately. The short version: I settled on Claude Code with a set of custom workflow skills.
Here’s what I’ve actually learned over 14 months:
It doesn’t replace thinking. Every time I let the AI drive without clear direction, I got code that looked right and was subtly wrong. The auth provider roundtrip? Partly caused by trusting an AI recommendation without interrogating the reasoning. The Rust detour? Same pattern. “This is a serverless function, you should use Rust for performance” sounds plausible until you realise your function runs 12 times a minute and the slower startup time costs more in CI pain than it saves in execution time.
It’s transformative for the boring middle. The gap between “I know exactly what this should do” and “it’s done and tested” is where AI genuinely shines. Boilerplate. Database migrations. Standard API endpoints where the pattern is established and you’re just varying the details. I could not have maintained this velocity alone. 3,704 commits from one person in 14 months is not normal human output.
The workflow matters more than the tool. The shift from “use AI to complete code” to “use AI agents working in isolated branches with structured task management” was bigger than any individual tool upgrade. Having agents that understand your codebase conventions, check their own work against requirements, and can’t accidentally corrupt your main branch, that’s the real multiplier. The specific AI model is almost a commodity now. The workflow around it is where the edge is.
Trust is earned through automation, not vigilance. Early on, I reviewed every line before committing. That doesn’t scale. What scales is investing in automated testing and CI/CD that catches problems before they reach production. Once you have a pipeline you trust, you can let AI move faster and focus your attention on architecture decisions, security, and the occasional “why does this exist?” review.
The False Starts
Honesty time. Not everything was a clean journey from problem to solution:
- Auth provider switching (July 2025): Migrated to a third-party service. Migrated back within a month. About two weeks of wasted effort total.
- Nx (August 2025 to April 2026): Eight months. It worked, but every new package meant 15 minutes of configuration overhead.
- Rust serverless functions (March 2026): Three weeks to build, three weeks to replace. Net learning: I now know some Rust.
- Third-party contract signing service: Launched with it. Replaced it with an in-house solution four days before the launch date. That was a fun weekend.
- Three different AI workflow tools (September to November 2025): Each installed, evaluated, and discarded.
Each of these felt like wasted time in the moment. Looking back, they were all necessary steps toward understanding what the right solution actually looked like. You can’t evaluate alternatives you haven’t tried.
The Final Sprint
April 2026 was a different kind of month. The commit messages tell the story: feature flags going in, smoke tests being written, deployment pipelines being hardened, edge cases being discovered and fixed. The last two weeks before launch were the most focused engineering work I’ve ever done.
What made it possible was the accumulated infrastructure. By April, the monorepo was clean. CI was fast. Deployments were automated. Feature flags meant I could ship unfinished work without risking the live system. All that infrastructure investment from earlier months was paying dividends now, all at once, precisely when velocity mattered most.
On May 4, the deployment was unremarkable. Merge to main, automatic staging deployment, smoke tests pass, promote to production. Exactly like the hundreds of deployments before it, except this time real users would see it.
What I’d Tell Someone Starting This
Invest in automated deployment early. I wish I’d built the full CD pipeline in month 3 instead of month 12. Every month of manual deployments was a month of accumulated friction and low-grade anxiety. Automated deployments aren’t a luxury. They’re what let you ship 38 commits a day without losing your mind.
Don’t optimise prematurely, in any dimension. Not performance (the Rust detour). Not abstraction (complex monorepo tooling for eight packages). Not features (enterprise authentication features for a product with zero enterprise customers). Solve the problem you have today with the simplest thing that works.
Feature flags from day one. I added them late. Every feature shipped before I had flags was shipped with a prayer. Nothing user-facing goes out without a flag now. The peace of mind is worth more than the implementation cost.
AI tools are a force multiplier, not a replacement. They multiplied my output by maybe three to five times on good days. They also introduced bugs I wouldn’t have written myself. The net is strongly positive, but only because I stayed close enough to the system to catch the subtle mistakes.
3,704 Commits Later
The platform is live. Real companies are submitting real projects. Real contractors are quoting on real work. The system processes actual transactions in a regulated industry.
It’s not done. Software is never done. But the gap between “blank project” and “production system handling real business operations” has been closed. Fourteen months, one developer, a lot of AI assistance, and more wrong turns than right ones.
I’m going to enjoy the quiet satisfaction of a production deploy that just works.
← Back to posts