How I Built a Production SaaS in 6 Weeks with Next.js

From zero to live product — the architecture decisions, performance tradeoffs, and deployment pipeline I used to ship SocialBoost serving real users.

Suyog Bhise
Full Stack Developer · Pune, India

The Problem I Was Solving

SocialBoost started as a client request — a digital marketing agency needed a platform where their clients could log in, see analytics, schedule content, and manage subscriptions. Nothing too unusual, but the timeline was aggressive: 6 weeks from kickoff to production.

💡

The biggest constraint wasn't time — it was that I was building it solo, alongside my full-time contract role at IVTREE.

Tech Stack Decisions

I went with Next.js App Router for the frontend, Node.js + Express for the backend API, MongoDB for the database, and Stripe for subscriptions. Here's why:

The Architecture

suyogbhise.online
├── app/
│   ├── (auth)/login, signup
│   ├── (dashboard)/overview, analytics, content
│   ├── api/
│   │   ├── stripe/webhook
│   │   ├── auth/[...nextauth]
│   │   └── content/
└── components/

I kept auth, billing, and content as completely separate concerns. This paid off when the client wanted to add a Google Calendar integration mid-project — I could drop it into the content layer without touching auth or billing.

The Hardest Part: Stripe Webhooks

Stripe webhooks are the source of most SaaS bugs. The order of events matters, idempotency matters, and you need to handle failures gracefully. My approach:

// Always verify the webhook signature first
const event = stripe.webhooks.constructEvent(
  rawBody,
  sig,
  process.env.STRIPE_WEBHOOK_SECRET!
);

// Use a processed-events collection to handle retries
const alreadyProcessed = await db.collection('webhookEvents')
  .findOne({ stripeEventId: event.id });

if (alreadyProcessed) return res.json({ received: true });

// Process and mark as done atomically
await processEvent(event);
await db.collection('webhookEvents')
  .insertOne({ stripeEventId: event.id, processedAt: new Date() });

What Shipped in 6 Weeks

What I'd Do Differently

I'd invest more time upfront in a proper error boundary system and loading state management. When you're moving fast, these feel like extras — but they're what separates a polished product from one that feels rough around the edges.

Moving fast is only worth it if what you ship actually works reliably for users.

Back to all posts