Plan your wedding without handing your guest list to a SaaS company.
OSWP is an AI-native, self-hostable wedding planning platform. It handles guest management, RSVP collection, vendor tracking, and your wedding website — with Etta, an AI wedding assistant built in. You own your data, your schema, and your deployment.
oswp.carvallo.io — a live demo running on real infrastructure. Log in as Shrek & Fiona and explore the full app: guest list, RSVPs, vendor tracking, wedding website, and Etta AI assistant.
| Account | Password | |
|---|---|---|
| Primary couple | shrek@swamp.wed | password123 |
| Second partner | fiona@swamp.wed | password123 |
The demo runs on the same Vercel + PostgreSQL stack described in the self-hosting guide. What you see is what you get when you deploy your own instance.
Guest & RSVP management
- Organize guests into households, tag them by relationship or group, and track attendance likelihood before invitations go out
- Create multiple events (ceremony, rehearsal dinner, after-party) and invite different guest subsets to each
- Collect RSVPs with custom questions — dietary restrictions, song requests, or anything else you need
- Filter, sort, and search your guest list; switch between card and table views
Vendor management
- Track vendors with quotes (flat fee or per-guest), files, and notes in one place
- Preview PDFs and images inline without leaving the app
Wedding website
- Generate a custom website with a unique URL for your guests
- Password-protect it, toggle RSVP collection on/off, and upload a cover photo
Etta — AI wedding assistant
- Built-in AI agent with a dual-persona chat interface
- Helps couples think through planning decisions, draft communications, and get unstuck
Multi-user support
- Invite a partner, coordinator, or family member to co-manage the wedding
- Org-scoped permissions keep each couple's data separate
| Layer | Technology |
|---|---|
| Framework | Next.js 15 + React 19 (App Router, Server Components) |
| Language | TypeScript (strict mode) |
| API | tRPC v11 |
| Database | PostgreSQL via Prisma v7 |
| Auth | Better Auth (self-hosted, open source) |
| AI | Claude (Anthropic) via Etta agent |
| Styling | Tailwind CSS + shadcn/ui |
| Validation | Zod v4 |
| Storage | Vercel Blob (optional) |
| Observability | OpenTelemetry |
- Node.js v18+
- PostgreSQL (or a Supabase free-tier project)
- An Anthropic API key (optional — only needed for Etta)
git clone https://github.com/dccakes/SCV.git
cd oswp
npm installcp .env.example .envRequired variables:
# Database
DATABASE_URL="postgresql://user:password@host:port/database"
DIRECT_URL="postgresql://user:password@host:port/database"
# Auth
BETTER_AUTH_SECRET="your-secret-key" # openssl rand -base64 32
NEXT_PUBLIC_APP_URL="http://localhost:3000"Optional:
# Social login
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
# File storage (Vercel Blob)
BLOB_READ_WRITE_TOKEN=""
# Etta AI assistant
ANTHROPIC_API_KEY=""npx prisma db push
npx prisma generateOptionally seed with sample data:
npx prisma db seednpm run devOpen http://localhost:3000.
OSWP is built to run anywhere. Three paths are supported:
| Path | Best for |
|---|---|
| Vercel + Supabase | Easiest setup, free tier, zero infrastructure |
| Docker Compose | VPS or homelab |
| Fly.io | Managed infrastructure, one-command deploys |
→ Full self-hosting guide — environment variables, reverse proxy setup, security checklist, and troubleshooting.
- Fork this repo
- Import at vercel.com/new
- Add your environment variables (see docs/self-hosting.md for the full reference)
- Deploy
Vercel runs npm install, generates the Prisma client, and builds automatically.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Production build |
npm run test:unit |
Run unit tests (Jest) |
npm run lint |
ESLint check |
npm run lint:fix |
Fix auto-fixable lint errors |
npm run prettier:fix |
Fix formatting |
npx prisma studio |
Open database GUI (port 5555) |
npx prisma migrate dev |
Run a new migration |
server/
├── domains/ # Business entities (Event, Guest, Household, etc.)
│ └── event/
│ ├── event.repository.ts # Database access
│ ├── event.service.ts # Business logic
│ ├── event.validator.ts # Zod schemas
│ ├── event.types.ts # Domain types
│ └── event.router.ts # tRPC router (thin)
├── application/ # Cross-domain orchestration
└── infrastructure/ # Database, email, storage
app/ # Next.js App Router pages
components/ # React components
tests/
└── unit/ # Jest unit tests
See CLAUDE.md for architecture guidelines and the domain migration plan.
Core models:
- User — accounts and auth
- Wedding — the couple's wedding record (org-scoped)
- Event — ceremony, reception, and other events
- Household — guest group at a shared address
- Guest — individual guests
- Invitation — guest ↔ event link with RSVP status
- Question / Answer — custom RSVP questions and responses
- Vendor — vendor contacts, quotes, and files
- Website — wedding website configuration
Full schema in prisma/schema.prisma.
Questions, ideas, and show-and-tells live in GitHub Discussions:
- Q&A — stuck on setup or a feature? Ask here.
- Ideas — propose features before opening a PR.
- Show and Tell — share your OSWP deployment.
See CONTRIBUTING.md to get set up and submit your first PR. All contributions — bug reports, feature proposals, and pull requests — are welcome.
Prisma client not found
npx prisma generateDatabase connection error
- Verify
DATABASE_URLis correct - For Supabase: use the "Connection Pooling" URL for
DATABASE_URL
Port 3000 in use
lsof -ti:3000 | xargs kill -9
# or
PORT=3001 npm run devTypeScript errors after pulling changes
rm -rf .next node_modules package-lock.json
npm install
npx prisma generate
npm run buildPolyForm Noncommercial License — free for personal use, open to review and contribution.