Best Boilerplates for Marketplace Apps in 2026
Two-sided marketplaces are structurally harder to build than standard SaaS. A standard SaaS application has one payment direction: user pays you. A marketplace has two: buyer pays you, you pay the seller minus your platform fee. This split-payment architecture requires Stripe Connect — a different product from standard Stripe billing that most developers have never used.
Beyond payments, marketplaces need seller onboarding and verification, listing management, review systems, dispute resolution, and often real-time messaging between buyers and sellers. No boilerplate ships all of this pre-configured. The right foundation reduces the custom development from months to weeks.
Marketplace Types and Their Requirements
Before choosing a boilerplate, understand which type of marketplace you're building — each has distinct technical requirements:
| Type | Core Requirement | Examples |
|---|---|---|
| Service marketplace | Booking + escrow, time-based availability | Fiverr, Upwork, Thumbtack |
| Product marketplace | Inventory, shipping, returns processing | Etsy, eBay, Depop |
| Rental marketplace | Availability calendar, security deposits, damage claims | Airbnb, Turo, Fat Llama |
| Digital goods | License delivery, download limits, version management | Gumroad, Creative Market |
| B2B marketplace | Invoice payments, net-30 terms, volume discounts | Faire, Handshake |
Each type adds 2–6 weeks of specialized development on top of the base marketplace infrastructure. Plan for this before committing to a launch date.
Best Foundation Starters
Supastarter — Best Multi-Tenant Foundation
Price: $299+ | Stack: Next.js, Supabase, Stripe
Supastarter's multi-tenant architecture maps cleanly to marketplace sellers. Each "organization" in Supastarter becomes a seller account — with its own members, roles, and settings. This gives you team-based seller accounts from day one.
Supabase's Row Level Security provides database-level access control for marketplace data — a buyer only sees their own purchases, a seller only sees their own orders. This is more secure and performant than application-level filtering.
Customization path for marketplace:
- Replace organization subscription billing with Stripe Connect seller onboarding
- Add
Listing,Order, andReviewmodels to the schema - Build buyer checkout with
application_fee_amounton PaymentIntents - Add a messaging system (Supabase Realtime handles this well)
- Build dispute/refund admin interface
Estimated time to marketplace MVP: 3–4 weeks from Supastarter.
T3 Stack — Best for Custom Architecture
Price: Free | Stack: Next.js, tRPC, Prisma, NextAuth
When marketplace logic doesn't fit standard boilerplate patterns — a rental marketplace with complex availability calendars, a B2B marketplace with net-30 payment terms — T3 Stack gives you maximum control. tRPC's type-safe procedures work well for marketplace operations:
// tRPC router for marketplace listings:
const listingRouter = router({
create: protectedProcedure
.input(z.object({
title: z.string(),
price: z.number().positive(),
description: z.string(),
category: z.string(),
images: z.array(z.string().url()),
}))
.mutation(async ({ input, ctx }) => {
const seller = await ctx.db.seller.findUnique({
where: { userId: ctx.session.user.id }
});
if (!seller?.stripeAccountId) {
throw new TRPCError({
code: 'PRECONDITION_FAILED',
message: 'Complete Stripe onboarding before listing'
});
}
return ctx.db.listing.create({
data: { ...input, sellerId: ctx.session.user.id }
});
}),
search: publicProcedure
.input(z.object({
query: z.string().optional(),
category: z.string().optional(),
minPrice: z.number().optional(),
maxPrice: z.number().optional(),
cursor: z.string().optional(),
}))
.query(async ({ input, ctx }) => {
const listings = await ctx.db.listing.findMany({
where: {
status: 'active',
...(input.query && { title: { contains: input.query, mode: 'insensitive' } }),
...(input.category && { category: input.category }),
...(input.minPrice && { price: { gte: input.minPrice } }),
...(input.maxPrice && { price: { lte: input.maxPrice } }),
},
take: 20,
cursor: input.cursor ? { id: input.cursor } : undefined,
include: { seller: { select: { name: true, avatar: true, rating: true } } },
});
return { listings, nextCursor: listings[19]?.id };
}),
});
Shipfast — Best for Fast Marketplace MVPs
Price: $199 | Stack: Next.js, Supabase, Stripe
For marketplace founders validating product-market fit, Shipfast's landing page, auth, and dashboard infrastructure gets you to a testable MVP in days. Build the Stripe Connect seller onboarding and listing management on top.
Best for: Validating marketplace demand before investing in full marketplace architecture.
Stripe Connect: The Core Architecture
Account Types
| Account Type | Seller Experience | Your Visibility | Best For |
|---|---|---|---|
| Standard | Full Stripe dashboard | Limited payout visibility | Simple freelancer marketplaces |
| Express | Streamlined onboarding | Full payout visibility | Most marketplaces |
| Custom | Fully white-labeled | Complete control | Large-scale branded marketplaces |
Express Connect is correct for 95% of new marketplaces. It gives sellers a streamlined onboarding flow while giving you full visibility into payouts, balances, and disputes.
Seller Onboarding
// Create Stripe Connect Express account and generate onboarding link:
async function onboardSeller(userId: string, email: string) {
// Create the Connect account:
const account = await stripe.accounts.create({
type: 'express',
email,
capabilities: {
card_payments: { requested: true },
transfers: { requested: true },
},
});
// Store account ID:
await db.seller.update({
where: { userId },
data: { stripeAccountId: account.id, onboardingStatus: 'pending' },
});
// Generate onboarding link:
const accountLink = await stripe.accountLinks.create({
account: account.id,
refresh_url: `${BASE_URL}/sellers/onboard?refresh=true`,
return_url: `${BASE_URL}/sellers/dashboard`,
type: 'account_onboarding',
});
return accountLink.url; // Redirect seller to this URL
}
// Webhook: handle onboarding completion:
case 'account.updated':
const account = event.data.object;
if (account.details_submitted) {
await db.seller.update({
where: { stripeAccountId: account.id },
data: { onboardingStatus: 'complete', verified: true }
});
}
break;
Split Payments with Platform Fees
// Buyer checkout with platform fee:
async function createMarketplaceCheckout(
listingId: string,
buyerId: string
) {
const listing = await db.listing.findUnique({
where: { id: listingId },
include: { seller: true }
});
const platformFeePercent = 0.10; // 10% platform fee
const platformFee = Math.round(listing.price * platformFeePercent);
const paymentIntent = await stripe.paymentIntents.create({
amount: listing.price,
currency: 'usd',
application_fee_amount: platformFee,
transfer_data: {
destination: listing.seller.stripeAccountId,
},
metadata: {
listingId: listing.id,
buyerId,
sellerId: listing.sellerId,
},
});
return paymentIntent.client_secret;
}
Escrow for Service Marketplaces
Service marketplaces (like Upwork or Fiverr) hold payment in escrow until work is delivered:
// Create escrow payment (hold funds, don't transfer yet):
const paymentIntent = await stripe.paymentIntents.create({
amount: servicePrice,
currency: 'usd',
capture_method: 'manual', // Don't capture immediately — hold in escrow
application_fee_amount: platformFee,
transfer_data: { destination: sellerStripeAccountId },
});
// Buyer confirms work delivered → capture and transfer:
await stripe.paymentIntents.capture(paymentIntentId);
// Or: buyer disputes → refund the payment:
await stripe.refunds.create({ payment_intent: paymentIntentId });
Marketplace Data Schema
// Core marketplace schema (Prisma):
model Seller {
id String @id @default(cuid())
userId String @unique
stripeAccountId String?
onboardingStatus String @default("pending") // pending, complete
verified Boolean @default(false)
rating Float?
listings Listing[]
}
model Listing {
id String @id @default(cuid())
title String
description String
price Int // In cents
category String
images String[]
status String @default("active")
seller Seller @relation(fields: [sellerId], references: [id])
sellerId String
orders Order[]
reviews Review[]
createdAt DateTime @default(now())
@@index([category, status, price])
}
model Order {
id String @id @default(cuid())
listing Listing @relation(fields: [listingId], references: [id])
listingId String
buyer User @relation(fields: [buyerId], references: [id])
buyerId String
stripePaymentId String @unique
amount Int
platformFee Int
status String @default("pending")
review Review?
createdAt DateTime @default(now())
}
model Review {
id String @id @default(cuid())
order Order @relation(fields: [orderId], references: [id])
orderId String @unique
listing Listing @relation(fields: [listingId], references: [id])
listingId String
rating Int // 1-5
comment String?
createdAt DateTime @default(now())
}
Review System Architecture
Trust is the foundation of any marketplace. Reviews must be:
- Double-blind during the review window — neither party sees the other's review until both submit (prevents retaliatory reviews)
- Verified — only buyers who completed a transaction can review
- Timely — review window closes 14 days after delivery
// Open review window after delivery:
await db.order.update({
where: { id: orderId },
data: {
status: 'delivered',
reviewWindowClosesAt: addDays(new Date(), 14),
}
});
// Submit review (only visible after both parties review):
async function submitReview(orderId: string, reviewerId: string, rating: number, comment: string) {
const order = await db.order.findUnique({
where: { id: orderId },
include: { buyerReview: true, sellerReview: true }
});
const isBuyer = order.buyerId === reviewerId;
const reviewField = isBuyer ? 'buyerReview' : 'sellerReview';
const counterpartyReview = isBuyer ? order.sellerReview : order.buyerReview;
await db.review.create({ data: { orderId, reviewerId, rating, comment } });
// If both parties have reviewed, make both visible:
if (counterpartyReview) {
await db.order.update({
where: { id: orderId },
data: { reviewsPublished: true }
});
}
}
Trust and Safety at Launch
Marketplaces fail not on technology but on trust. Buyers need to trust sellers will deliver. Sellers need to trust they'll get paid. Your platform infrastructure is the mechanism for enforcing both.
Seller verification tiers help buyers understand who they're buying from:
- Basic — email verified, Stripe Connect onboarding complete
- Verified — government ID verified (Stripe Identity handles this), phone verified
- Pro — 50+ completed orders, 4.8+ average rating, response time under 2 hours
- Top Rated — manually reviewed, featured placement
Displaying these tiers prominently on listings and seller profiles converts browsers into buyers. Buyers tolerate premium prices from verified sellers because the risk profile is lower.
Buyer protections that build confidence:
- Escrow payments (hold funds until delivery confirmed)
- Purchase protection for non-delivery
- Clear refund policy
- Dispute resolution with defined timelines
Communicate these prominently on your landing page and checkout flow. Marketplaces that hide their buyer protection policies have lower conversion rates.
Messaging Between Buyers and Sellers
Real-time buyer-seller messaging is expected in most marketplace categories. The implementation depends on your stack:
Supabase Realtime (simplest if already using Supabase):
// Subscribe to a conversation channel:
const channel = supabase
.channel(`conversation:${conversationId}`)
.on('postgres_changes', {
event: 'INSERT', schema: 'public', table: 'messages',
filter: `conversation_id=eq.${conversationId}`,
}, (payload) => addMessage(payload.new))
.subscribe();
Keep your messaging implementation simple at launch. Many early marketplaces have succeeded without real-time messaging — email notifications for new messages work fine until you have volume that justifies the infrastructure investment.
Typical Marketplace Launch Timeline
Building a marketplace MVP from a SaaS foundation like Supastarter typically takes:
| Phase | Timeline | Work |
|---|---|---|
| Foundation | Week 1 | Base boilerplate setup, Stripe Connect integration |
| Listings | Week 2 | Listing CRUD, categories, image upload |
| Checkout | Week 3 | Buyer checkout, payment split, order tracking |
| Reviews + Trust | Week 4 | Review system, seller verification badges |
| Launch prep | Week 5-6 | Testing, landing page, seller onboarding docs |
6 weeks to a launchable marketplace MVP is realistic with a good boilerplate foundation and a focused solo developer. The first version doesn't need real-time messaging, advanced search, or a mobile app — validate demand first.
Related Resources
For the billing infrastructure decisions (Stripe Connect vs Paddle Marketplace), see the best boilerplates with Stripe integration. For multi-tenant SaaS foundations that work well as marketplace backends, see the best multi-tenant SaaS boilerplates.
How to Evaluate Marketplace Boilerplate Foundations
No boilerplate ships marketplace-specific features pre-built. What you're evaluating is how well the foundation reduces the custom development work specific to marketplaces. Key evaluation criteria for the foundation:
Multi-tenancy architecture. Marketplaces are inherently multi-tenant: each seller account is a separate tenant with its own listings, orders, and payouts. A boilerplate with a built-in organization model (Supastarter, Makerkit) maps directly to the marketplace seller concept. A single-user boilerplate (ShipFast) requires you to design and implement the seller account structure yourself.
Database access control. Marketplaces have complex data access rules: buyers see listings and their own orders, sellers see their own listings and all orders for those listings, admins see everything. Application-level access control (checking IDs in every query) is error-prone and creates security gaps when a query is missed. Supabase Row Level Security enforces these rules at the database level, making it structurally impossible for a buyer to query another buyer's orders. Evaluate whether the boilerplate uses RLS or application-level filtering.
Image and file upload handling. Marketplace listings require images. The boilerplate's file upload implementation (Supabase Storage, S3, Cloudflare R2) determines how you handle listing images, profile photos, and any documents required for seller verification. Verify that the upload implementation includes access control (public URLs for listing images, private URLs for seller documents), size limits, file type validation, and CDN delivery.
Background job support. Marketplaces generate significant async work: payout notifications, review reminder emails, fraud detection checks, order status updates. A boilerplate with background job support (Inngest, Trigger.dev, Supabase Edge Functions) handles this more cleanly than a boilerplate that assumes all work happens in API route handlers.
What Marketplace Apps Have in Common
Marketplaces built on SaaS boilerplates share structural decisions that reflect lessons from building two-sided platforms:
Stripe Connect Express is the universal choice for new marketplace payment infrastructure. Standard Connect is too complex for most marketplaces (full Stripe dashboard access for sellers creates support overhead). Custom Connect is too opaque for small teams (you own the entire user interface for seller onboarding). Express Connect provides a middle path: Stripe hosts the seller onboarding and dashboard, you see full payout visibility.
Trust and safety infrastructure is built from day one, not added after the first dispute. Every marketplace that has operated at scale has a dispute story. The infrastructure to handle disputes — escrow holds, refund workflows, seller suspension, buyer protection — is not complex to build but is critical to have before launch. Retrofitting it after a high-profile dispute is significantly more painful than building it as part of the MVP.
Search and discovery is the most underestimated development effort in marketplace MVPs. Most SaaS boilerplates ship with simple database queries for content. Marketplaces need faceted search (filter by category, price range, location, rating), relevance ranking, and performance that scales as listing count grows. PostgreSQL's full-text search (tsvector) covers early-stage needs. Algolia or Elasticsearch become necessary when listing count exceeds tens of thousands or when search quality directly drives conversion.
Commission rates and payout timing are policy decisions that must be reflected in the data model from launch. A platform_fee_percent column on the Listing or Order model allows per-listing or per-category commission rates. Payout timing (instant vs. 7-day hold vs. milestone-based) affects escrow implementation complexity significantly. Decide these policies before building the billing infrastructure, not after.
For the billing infrastructure layer and how Stripe Connect compares to Paddle Marketplace for international payouts, see the best SaaS boilerplates guide. For multi-tenant SaaS foundations that work well as marketplace seller account systems, see the best multi-tenant SaaS boilerplates guide. For B2B marketplace payment infrastructure specifically, the fintech boilerplates guide covers the escrow and payout patterns in depth. For choosing the right foundation based on your marketplace business model (service vs product vs digital goods), see the business model boilerplate selection guide.
Browse marketplace boilerplates and Stripe Connect starters at StarterPick.
Review Supastarter and compare alternatives on StarterPick.
Check out this boilerplate
View Supastarteron StarterPick →