A multi-sided marketplace platform connecting customers with Transport and Experience providers.
- Overview
- Product Areas
- Screenshots
- Tech Stack
- Roles & Permissions
- Architecture
- Project Structure
- Design System
- Engineering Principles
- Getting Started
- Environment Variables
- Roadmap
Waylink is a full-stack SaaS marketplace that connects customers with Transport and Experience service providers. Providers list and manage their own products (rides, tours, activities), while customers discover and book them through a public storefront. An internal admin team oversees the entire platform — providers, listings, subscriptions, and platform-wide financial health.
The platform is built as a single Next.js application with three distinct, role-gated experiences sharing one codebase, one design system, and one data layer.
The customer-facing storefront for discovering and booking services.
- Browse Transport and Experience listings
- Search, filter, and view provider/product details
- Booking flow and checkout
- Responsive, SEO-optimized marketing and listing pages
Where providers run their business on Waylink.
- Product management (multi-step creation wizard: details, variants & pricing, locations, service details, review)
- Booking management
- Subscription & plan management
- Revenue, payout, and peak-booking-hours analytics
- Reviews and provider team/staff management
Internal control center for the Waylink team.
- Provider management and moderation (approve, suspend, review)
- Product/listing moderation with destructive & non-destructive status transitions
- Platform-wide subscriptions management (plans, trials, cancellations, bulk actions)
- Financial reporting (revenue over time, revenue by plan tier, top providers by revenue)
- Platform analytics & KPIs
- User management (roles, bans, provider staff assignment)
- Notification center
| Public Website | Provider Dashboard |
|---|---|
| Admin Dashboard | Financial Analytics |
|---|---|
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16 (App Router) | Routing, Server Components, Server Actions, SSR |
| Language | TypeScript | End-to-end type safety |
| Styling | Tailwind CSS | Utility-first styling |
| UI Components | shadcn/ui | Accessible, composable component primitives |
| Animation | Framer Motion (motion/react) |
Micro-interactions, staggered/spring animations |
| Database | PostgreSQL (via Neon) | Primary data store |
| ORM | Drizzle ORM | Type-safe schema, queries, and migrations |
| Auth | Better Auth | Sessions, roles, admin plugin, access control |
| Background Jobs | Inngest | Async workflows, scheduled/event-driven jobs |
| Forms & Validation | React Hook Form + Zod | Type-safe forms and schema validation |
| Charts | Recharts | Analytics visualizations |
Access control is implemented with Better Auth's createAccessControl, extended with a custom provider role alongside the built-in admin/user roles.
| Role | Access |
|---|---|
| Customer (default user) | Public website, browsing, bookings, own account |
| Provider | Provider Dashboard — own products, bookings, subscriptions, staff, analytics |
| Admin | Admin Dashboard — full platform oversight: users, providers, products, subscriptions, financials |
Waylink follows a server-first architecture:
- Server Components by default — Client Components are opt-in, used only where interactivity requires it.
- Server Actions for all mutations — no ad hoc API routes for internal writes.
- Business logic separated from UI — service/query layers (e.g.
getRevenueOverTime,getPayoutSummary,getDashboardInsights) live independently of the components that render them. - Typed data access — all database access goes through Drizzle ORM; no raw, untyped queries.
- Performance-conscious data fetching — parallelized queries,
unstable_cache, and streaming/Suspenseboundaries throughout dashboards. - SEO by default — public-facing routes implement
generateMetadata.
Adjust to match your actual folder layout — this reflects the current conventions in use across the admin, provider, and public areas.
- Theme: dark purple/slate palette defined with
oklch()custom CSS properties inglobals.css, with class-based dark mode. - Charts: a consistent custom palette (violet, amber-orange, emerald, slate) rather than default shadcn chart colors.
- Interaction patterns: Dribbble-style slide-up panels, floating action bars, and URL-driven drawer/sheet state.
- States: every data view ships with loading (skeleton), empty, and error states — no bare spinners or silent failures.
- Motion: staggered entrance animations and spring-physics transitions via Framer Motion, respecting
useReducedMotion().
When contributing to Waylink, code should prioritize:
- Clean, scalable architecture
- Type-safe TypeScript throughout
- Reusable components and utilities
- Performance and readability
- Consistency with existing project structure and conventions
- Production-ready solutions over quick fixes
- Public booking checkout flow
- Provider payouts automation via Inngest
- Platform-wide notification system (email + in-app)
- Multi-currency support
- Public API for provider integrations
Built and maintained as a solo, full-stack project by nero-tx.













