DEV Community

Jay WedPlanner
Jay WedPlanner

Posted on

How I Built a Wedding Planning Suite with Supabase in 3 Months

How I Built a Wedding Planning Suite with Supabase in 3 Months

Quick Answer: I built a full wedding planning platform in 90 days using Supabase as the backend (PostgreSQL database, real-time subscriptions, Row Level Security, and OAuth auth), Next.js 14 for the frontend, and a few carefully chosen npm packages for specific features like QR code scanning. The key was leveraging Supabase's managed services to avoid building auth, websockets, and file storage from scratch.

Introduction

Three months ago, I had an idea: what if couples could plan their entire wedding through one cohesive platform? Not a static checklist app, but a living, breathing system where vendors, guests, budgets, and timelines all talked to each other in real time.

I'm a solo developer with a day job. I didn't have a team of backend engineers to build authentication, real-time sync, or file storage infrastructure. I needed a stack that would let me ship fast without shipping broken.

Enter Supabase. I'd heard the "Firebase alternative" pitch before, but what I discovered was something far more powerful for developers who actually want to own their data and their SQL.

This is the story of how I built WedPlanner—a full wedding planning suite—with Supabase, Next.js, and a few other tools. No VC funding. No offshore team. Just me, a tight deadline, and a PostgreSQL database that never let me down.

Why Supabase? The Architecture Decision That Made Everything Possible

When you're building alone, every architectural decision compounds. Pick the wrong database, and you'll spend weeks fighting migrations. Pick the wrong auth solution, and you'll ship with security holes you don't even know about.

I evaluated Firebase, PlanetScale, Clerk, and rolling my own PostgreSQL on RDS. Here's why Supabase won:

PostgreSQL, not a proprietary document store. Wedding data is relational. A guest belongs to a wedding. A vendor has multiple bookings. A budget category has many line items. Trying to model this in Firestore's document model felt like forcing a square peg into a round hole. Supabase gave me the database I actually wanted—PostgreSQL 15—with a managed layer on top.

Built-in auth that doesn't fight you. Supabase Auth supports OAuth (Google, Apple, etc.), email/password with confirmation flows, and Row Level Security (RLS) policies that live in your database. This meant I could enforce "users can only see their own wedding data" at the database level, not just hoping my frontend checks were comprehensive enough.

Real-time subscriptions without WebSocket headaches. One of WedPlanner's killer features is the shared planning dashboard. When the bride updates the seating chart, the groom sees it instantly. Supabase's real-time feature is built on PostgreSQL's LISTEN/NOTIFY mechanism, which means I didn't have to maintain a separate WebSocket server or worry about reconnection logic.

Storage that makes sense. Wedding photos, vendor contracts, scanned receipts—I needed file storage with proper access controls. Supabase Storage integrates with RLS, so I could write policies like "only the wedding owner can view contract PDFs."

The total cost during development? Zero. Supabase's free tier handled everything until I had real users.

The Tech Stack Deep-Dive

Database Design: Weddings Are More Relational Than You Think

My initial schema seemed simple: users, weddings, guests, vendors. Then reality hit. A guest can have dietary restrictions. A vendor might serve multiple weddings. A budget line item might link to a specific vendor. A task in the timeline might depend on another task being completed first.

Here's the core schema I landed on:

I used Supabase's table editor for rapid prototyping, then migrated to managing schema through SQL migrations with the Supabase CLI. This gave me version control for my database structure—critical when you're iterating quickly and need to roll back.

One pattern that saved me: I created a weddings table as the central entity, then used foreign keys to link everything else. RLS policies then enforced that SELECT, INSERT, and UPDATE operations on any table required the user's ID to match the wedding's owner or collaborator list.

Authentication and Authorization: Trust the Database

I've seen too many apps where authorization is a frontend concern. Someone forgets a check, and suddenly users can see each other's data. With Supabase, I flipped this: the database is the source of truth for who can access what.

Here's an RLS policy example from my guests table:

This means even if a malicious actor crafted a raw HTTP request to my Supabase endpoint, they'd only ever see guests linked to weddings they own or collaborate on. The frontend is just a view layer; security lives in PostgreSQL.

For OAuth, I enabled Google and Apple sign-in through Supabase's dashboard. The redirect handling and token refresh were managed automatically. Total setup time: about 20 minutes.

Real-Time Features: When Everyone Needs to See the Same Thing

Wedding planning is collaborative. The couple, their parents, the wedding planner—everyone needs to stay in sync. I implemented real-time updates for:

  • Guest list changes (RSVP status updates)
  • Budget modifications
  • Timeline task completions
  • Vendor communication notes Supabase's real-time subscriptions use PostgreSQL's logical replication under the hood. On the frontend, it looks like this with the JavaScript client:

The subscription automatically handles reconnections, which was critical for mobile users who might switch between WiFi and cellular. I didn't write a single line of WebSocket management code.

Next.js 14: The Frontend That Keeps Up

I chose Next.js 14 with the App Router for several reasons:

Server Components by default. Most of WedPlanner's pages don't need client-side JavaScript to render. The guest list, budget dashboard, and vendor directory all render on the server, fetching data directly from Supabase using service role keys. This means faster initial page loads and better SEO for public-facing pages.

Client Components where needed. Interactive features—the real-time dashboard, drag-and-drop seating charts, image uploads—use client components with Supabase's browser client. The boundary is explicit and manageable.

API Routes for edge cases. While Supabase handles most CRUD operations directly from the frontend, I used Next.js API routes for complex operations like generating PDF exports of the seating chart or sending bulk SMS reminders to guests. These run server-side with access to server-only secrets.

QR Codes and Mobile-First Features

One feature I didn't expect to be so important: QR codes for check-ins. Each guest gets a unique QR code in their invitation email. On the wedding day, the venue staff scans codes with tablets to mark guests as arrived.

I used the qrcode package (82 million monthly downloads on npm) for generating codes server-side, and html5-qrcode (5 million monthly downloads) for the scanning interface. The integration was surprisingly smooth—the html5-qrcode library handles camera permissions, device selection, and error correction automatically.

Real-world lesson: always test QR scanning in low-light conditions. I had to bump error correction from 'M' to 'H' level because venue lighting was unpredictable.

What Went Right (and What Didn't)

The Wins

Rapid prototyping with the table editor. I built the first working version of the guest list in a weekend. Being able to create tables, add RLS policies, and test queries in the Supabase dashboard before writing a line of frontend code was a massive accelerator.

Type safety with generated types. Supabase's CLI can generate TypeScript types from your database schema. This meant my frontend code knew exactly what shape every query returned. No more any types or runtime surprises.

Edge functions for heavy lifting. When I needed to generate PDF seating charts or process image uploads (resize, compress, add watermarks), Supabase Edge Functions—Deno-based serverless functions—handled it without me provisioning a separate backend.

The Challenges

RLS debugging. When a query returns no rows, is it because there are no matching rows, or because RLS is filtering them out? Supabase's query logs help, but early on I spent hours chasing "bugs" that were actually policy misconfigurations. My fix: create a dedicated "admin" role for development that bypasses RLS, so I can quickly verify data exists.

Real-time subscription limits. Supabase's free tier has limits on concurrent real-time connections. For the wedding day itself—when potentially dozens of staff members might be scanning QR codes simultaneously—I had to implement connection pooling and ensure subscriptions were only active when the user was actually viewing a real-time dashboard.

File storage organization. Supabase Storage uses buckets, and I initially created too many granular buckets. Consolidating into a wedding-assets bucket with path-based organization ({wedding_id}/contracts/, {wedding_id}/photos/) simplified both code and RLS policies.

Performance and Scalability: Lessons from Real Usage

After launching with a beta group of 50 couples, I learned some hard truths about performance:

Database indexes matter. My initial guest list query was scanning thousands of rows because I hadn't indexed the wedding_id foreign key. Adding the right indexes dropped query time from 800ms to 12ms. Supabase's query performance advisor helped identify the culprits.

Connection pooling with Supavisor. Serverless functions (like Next.js API routes) can exhaust PostgreSQL connections quickly. Supabase's Supavisor connection pooler is essential for production. Without it, I'd hit connection limits during peak usage.

Selective real-time subscriptions. Early on, I subscribed to broad table changes. This meant every guest list update triggered a re-render for everyone viewing any wedding. Filtering subscriptions to specific wedding IDs cut network traffic by 90%.

Key Takeaways

  • Supabase's PostgreSQL foundation makes it ideal for relational data models like wedding planning, where entities have complex relationships
  • Row Level Security policies in the database are more reliable than frontend authorization checks
  • Real-time subscriptions work out of the box but need filtering to avoid broadcast storms
  • Next.js 14 Server Components reduce client-side JavaScript while maintaining interactivity where needed
  • Database indexes are not optional—measure query performance early and often
  • Supabase's free tier is genuinely sufficient for prototyping and small beta launches
  • Type generation from your actual database schema eliminates an entire class of frontend bugs
  • Connection pooling (Supavisor) is essential before going to production with serverless functions

Frequently Asked Questions

Is Supabase really free for small projects?

Yes. Supabase's free tier includes a full PostgreSQL database, authentication for unlimited users, 1GB of file storage, and real-time subscriptions. I never paid a cent during the entire 3-month development period.

How does Supabase compare to Firebase for relational data?

Firebase's Firestore is a document database, which makes complex relationships awkward. Supabase uses PostgreSQL, which handles foreign keys, joins, and complex queries naturally. If your data is relational, Supabase is the clearer choice.

Can Supabase handle real-time updates for multiple users?

Yes. Supabase uses PostgreSQL's logical replication to broadcast changes to subscribed clients. For WedPlanner, multiple users viewing the same wedding dashboard see updates within milliseconds of each other.

What is Row Level Security (RLS) in Supabase?

RLS is a PostgreSQL feature that Supabase exposes through its dashboard and API. It lets you define policies that control which rows a user can access based on their authentication state or user ID, enforced at the database level.

How did you handle file uploads for wedding photos?

I used Supabase Storage with RLS policies restricting access by wedding ID. Client-side uploads go directly to Supabase with a signed URL, and Edge Functions handle image resizing and compression.

Is Next.js 14 necessary, or would plain React work?

Plain React would work, but Next.js 14's Server Components let me fetch data on the server without exposing Supabase service keys to the browser. This improves both performance and security.

How many users can the free tier realistically support?

My beta had 50 couples (roughly 100 active users) with no issues. The free tier's main limits are on database size (500MB), file storage (1GB), and concurrent real-time connections. For a wedding app with seasonal usage patterns, this goes surprisingly far.

What was the biggest technical challenge?

Debugging RLS policies when queries returned empty results. The fix was creating an admin role for development and using Supabase's query logs to understand what was being filtered and why.

Did you use any paid services beyond Supabase?

Not during development. I used Vercel's free tier for Next.js hosting. The only potential paid service would be a transactional email provider for invitations, though Supabase's built-in auth emails handle the basics for free.

Would you choose this stack again?

Absolutely. The combination of PostgreSQL's power with Supabase's managed services and Next.js's rendering flexibility is hard to beat for solo developers shipping real products.

Conclusion

Three months ago, WedPlanner was a sketch in a notebook. Today, it's a production platform handling real weddings. The Supabase, Next.js, and PostgreSQL stack didn't just let me build fast—it let me build correctly.

If you're a solo developer or small team building something with complex data relationships, don't default to the document databases and third-party auth services that everyone tweets about. PostgreSQL has been production-ready for decades. Supabase just makes it accessible without a DevOps team.

The wedding industry doesn't need another "good enough" tool. It needs software built by people who understand that relationships—both database and human—deserve something robust.

Want to see WedPlanner in action? Visit our homepage to explore features, or check out our full feature guide and planning resources for couples getting started.

Have questions about the implementation? Drop a comment—I'm building in public, after all.

Top comments (1)

Collapse
 
crdtcto profile image
Kane Lim

Really interesting build. What stands out to me is that Supabase wasn’t simply used as a convenient backend; it was used in a way that maps naturally to the domain model.

The decision to keep authorization at the PostgreSQL/RLS layer is particularly important for an application handling highly private wedding data. One area I’d be interested in exploring as the product grows is collaborator permissions—potentially separating owner, planner, vendor, family, and temporary event-day roles rather than treating access simply as “belongs to the wedding.”

The real-time architecture is another good example of where subscription scoping matters more than simply enabling subscriptions. As the number of weddings and concurrent users increases, keeping events properly scoped by wedding/tenant and avoiding unnecessary client subscriptions will become increasingly important.

I also like the progression from rapid prototyping through the dashboard to SQL migrations and generated TypeScript types. That transition is easy to overlook, but it’s often what separates a successful prototype from a maintainable production system.

The boundary between Next.js Server Components, Supabase client access, and privileged operations is another area worth thinking carefully about. Keeping service-role credentials strictly server-side while allowing browser clients to operate through RLS is a powerful pattern, but those boundaries need to remain explicit as business logic becomes more complex.

And the performance result is a great practical lesson: 800ms → 12ms through proper indexing is a strong reminder that managed PostgreSQL removes infrastructure overhead, not the need for database engineering.

I’m part of a small Canada-based remote development team focused on SaaS architecture, PostgreSQL, Supabase, Next.js, AI, and automation. We’re interested in building genuine long-term relationships with developers who approach engineering at this level.