Most "I built X in Y weeks" posts are some combination of hype, vague stack lists, and a "subscribe to my newsletter" CTA. Few of them tell you what actually broke, what cost money, or what the founder would do differently with the benefit of hindsight.
This one is the honest version. The product is Plug Your Build, a permanent directory for indie makers: SaaS, newsletters, courses, Gumroad assets, Discord servers, side projects, all in categorized browse pages with click analytics on a dashboard. It took eight weeks of evenings and weekends to go from idea to a working v1 with auth, multi-tenancy, billing, moderation, and a published blog.
Here's the stack, the cost, the hard parts, and what I'd change.
The decision
The first question wasn't "what should I build" but "what shape does indie-product visibility actually need." Most indie products have great launches and then quiet four-week dead zones. Twitter has an 18-minute half-life. Product Hunt is a 24-hour sprint. Reddit threads decay in days. Directories were the obvious untapped channel: persistent, search-qualified, compounding over time.
So the bet was a directory site rather than another launch platform. Per-listing subscriptions instead of one-time fees. SFW-only across every category, not just SaaS. Browse and search built first, dashboard second, newsletter third.
The competing options I considered:
- Yet another Product Hunt clone. Saturated, hard to differentiate.
- A SaaS-only directory like SaaSHub. Narrower audience.
- A creator marketplace. Different operational shape (transactions, disputes).
- Open-source listings with ad monetization. No way to fund moderation.
A categorized directory with permanent paid listings at $3.99 a month was the cleanest bet for a solo operator.
The stack
Eight services. Most on free tiers. What each does and why it beat its alternatives.
Next.js 15 (App Router) plus React 19. Default for any new SaaS in 2026. The App Router and Server Actions remove most of the API-layer boilerplate older SaaS stacks needed. React 19's async server component improvements save real time. Vercel hosting is the natural pairing.
Drizzle ORM plus Postgres on Supabase. Drizzle over Prisma because the query builder is more honest about what runs on the database, the type inference is better for Postgres-native features, and the migration tooling is smaller. Supabase for Postgres because the free tier handles up to 500MB and the upgrade path to a paid Postgres-only plan is cheap. I'm not using Supabase Auth or RLS for the application layer (Clerk handles auth, I wrote RLS policies separately), but the underlying database is fast and stable.
Clerk for auth. The Organizations primitive is enabled. The original plan was Supabase Auth, but Clerk's Organizations primitive saved me from rolling tenant membership myself, which is the kind of feature that's easy to underestimate. Free up to 10k MAU, well past the breakeven point on per-tenant pricing.
Stripe for billing. Per-listing subscriptions. The Customer Portal for self-service cancellation. Webhooks for syncing subscription state into the database. Standard stuff, but no part of it is one-day work. The hardest piece was making the moderation-to-first-invoice flow atomic (more on that below).
Resend plus React Email for transactional mail. Resend for delivery, React Email for templates. The combination is dramatically better than the legacy SendGrid plus handlebars setup I'd used before. Templates are React components, previewable in dev, and the deliverability has been solid.
Cloudflare R2 for listing images. Zero egress fees. Presigned URL uploads from the browser. About a tenth the cost of S3 for the access patterns of a directory site.
Trigger.dev for background jobs. The Sunday newsletter generation, the hourly click aggregation, and the daily moderation digest run there. Cron plus retry semantics that just work. Free up to 5k runs per month, well beyond what the current scale needs.
Anthropic's Claude Haiku for AI moderation. Every submission gets a classification pass before the human moderator sees it. Costs about $0.0003 per submission at current Haiku pricing. The classifier checks for NSFW content, scam patterns, category misfit, and obvious low-effort signals. The human is still the final call; the AI just sorts the inbox.
Plus the smaller pieces: PostHog for product analytics, Sentry for errors, Vitest for unit tests, Playwright for end-to-end, Tailwind for styling, and a custom design system built around a forest-teal and mint palette.
The hard parts
Three things took longer than budgeted. Each is the kind of thing that doesn't show up in "I built X in Y weeks" posts because it's unglamorous.
Multi-tenant row-level security, with real defense in depth. The pattern is well-known in theory and full of foot-guns in practice. Every tenant-scoped table carries organization_id with an index. App-level queries filter by organization_id as a required argument. RLS policies on the database enforce the same filter as a second layer. The query path for public browse pages bypasses RLS (uses a service role) but is constrained at the helper level to status = 'approved' AND subscription_status IN ('active', 'trialing').
Testing the isolation is the part that almost always gets cut. I wrote one Playwright spec that runs as user-from-org-A and tries to read org-B data through every public-facing surface. That single test caught two bugs during development.
OG image generation that actually looks like the site. Next.js has next/og (Satori) for dynamic OG images. Powerful, fast, edge-runtime friendly. The trap: Satori's CSS support is intentionally limited. Several brand effects (radial gradients, blur, custom fonts) needed to be rebuilt with the supported subset rather than imported from the existing design system. I ended up writing a category OG template and a listing OG template, each as separate branches in the same /api/og route. Took about a day longer than expected, and the result is dynamic OG images for every listing, category, and blog post, generated on demand and cached at the edge.
AI moderation thresholds. Sounds simple. Build a classifier prompt, set a threshold, route flagged submissions to manual review. In practice, the calibration takes a week of running synthetic submissions and tweaking. False positives (legitimate listings flagged as spam) frustrate makers. False negatives (NSFW or scam submissions getting through) destroy the directory's brand. The current setup uses three thresholds (auto-approve, manual review, auto-reject) and routes the middle band to a moderator queue with the model's confidence score and flagged terms surfaced inline. The middle band is small enough that one person can clear it in fifteen minutes a day.
The unexpected easy parts
Three things were faster than budgeted.
Tailwind plus a custom design system. Once the palette and the glass, glow, and button primitives were defined, every new component took an order of magnitude less time than the first few. The design system docs live at docs/BRAND.md and docs/DESIGN-SYSTEM.md and read like a small style guide. Every PR's visual decisions get referenced against those two files.
Drizzle's type inference into Server Actions. The db.query.listings.findMany() calls return fully typed rows. Server Actions accept Zod-validated input and pass it directly to Drizzle. The whole edit flow from form to database is type-safe end to end without code-generation steps. Maybe a third the boilerplate of an equivalent Prisma plus REST setup.
Stripe Customer Portal. Self-service cancellation, plan changes, invoice downloads, payment method updates. All free, all hosted by Stripe. The one custom piece was the moderation-approval-to-first-invoice synchronization, which is a webhook handler that flips the listing's status based on invoice.paid. About a day of work.
The cost
Under $30 a month for the first eight weeks. Mostly $0 across free tiers. Specific monthly costs at the current scale:
- Vercel: $0 (Hobby tier; will upgrade to Pro at $20 when needed)
- Supabase: $0 (free tier)
- Clerk: $0 (well under 10k MAU)
- Resend: $0 (under 3k emails)
- Cloudflare R2: $0 (under the free tier's storage threshold)
- Trigger.dev: $0 (under 5k runs)
- PostHog: $0 (under 1M events)
- Sentry: $0 (under 5k errors)
- Anthropic API: ~$2 per month at current submission volume
- Domain (plugyourbuild.com): $12 a year, amortized to $1 a month
Total: $3 a month while building, before the inevitable upgrades hit. Most future cost will come from Vercel Pro and Supabase Pro once traffic justifies them.
What I'd do differently
Three changes with the benefit of hindsight.
Ship the dashboard last instead of in parallel with the public browse. The dashboard is the surface that retains makers, but it depends on having real data to show. Building it on placeholder data ate two weeks that would have been better spent on the moderation queue.
Skip Sentry for v1. The errors that matter at this scale show up in Vercel's logs and the PostHog session replay. Sentry adds a second monitoring surface that's redundant for solo-operator stage. I'd add it back at 1,000-plus daily users.
Write the integration tests for the Stripe webhook handler before the handler itself. The order I ended up doing it in (write the handler, ship it, then write tests when a duplicate-webhook bug surfaced) was strictly worse. Stripe's webhook semantics around retries and ordering are the kind of thing that test-first catches and test-after rediscovers.
What's next
The directory is live at plugyourbuild.com. Standard listings are $3.99 a month, Featured listings are $14.99 a month, and the categories span SaaS, newsletters, courses, Gumroad assets, Discord servers, side projects, and a handful more.
The next two surfaces in the roadmap are an embeddable "listed on Plug Your Build" badge that creators can drop on their own sites (a small SEO benefit for both sides, plus a credibility signal), and an open API for partners who want to pull category data into their own tools.
Build logs continue on the blog at plugyourbuild.com/blog. The architecture decisions in this post each get their own deeper write-up there over the next few weeks.
Plug Your Build is a permanent directory for indie makers across SaaS, newsletters, courses, Gumroad assets, Discord servers, and more. Standard listings start at $3.99/month and stay live indefinitely. Submit yours here.