vercel/platforms: A Production-Ready Multi-Tenant Next.js Template with Subdomain Routing
A full-stack Next.js app with multi-tenancy.
At a glance
- What is it?
- vercel/platforms is a reference application showing how to build a multi-tenant site where each tenant gets its own subdomain, using Next.js 16, Upstash Redis, and Vercel's deployment infrastructure.
- Who is it for?
- Developers building a platform product where each customer needs their own subdomain, such as a site builder or a hosted documentation service, should use vercel/platforms as a starting point rather than building subdomain routing from scratch. Organizations that cannot use Vercel for deployment or Upstash for Redis will need to replace both integrations manually, since neither is abstracted behind a swappable interface in the current codebase.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 83 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What multi-tenancy problem vercel/platforms solves
A multi-tenant application serves multiple customers from a single deployed codebase while isolating each customer's content and identity. The most common user-facing pattern is per-tenant subdomains: customer A's site lives at customer-a.yourdomain.com while customer B's lives at customer-b.yourdomain.com, and each sees only their own content.
Building this correctly requires solving several problems at once: routing incoming requests to the right tenant, storing tenant data in a way that is fast to look up on every request, handling local development where subdomains do not naturally resolve to localhost, and keeping Vercel preview deployments working so each branch can be previewed correctly. vercel/platforms provides a working solution to all four, packaged as a runnable application rather than a library.
How proxy.ts handles subdomain routing
Next.js 16 replaced middleware.ts with proxy.ts for request interception. In vercel/platforms, proxy.ts reads the hostname from the incoming request and extracts the subdomain. The README explains the logic:
- Requests to the main domain (no subdomain) are routed to the landing page and admin panel at /admin - Requests with a subdomain are matched against the Redis key pattern subdomain:{name} and routed to the corresponding tenant's content - Preview deployments on Vercel add extra hostname segments, and the proxy handles this case explicitly - Local development uses [tenant-name].localhost:3000
The tenant's content is fetched from Redis using @upstash/redis for every routed request. This makes Redis a hard runtime dependency: if the Redis connection is down, tenant routing fails.
Setting up the project locally
The README requires Node.js 20.9.0 or later and recommends pnpm. To start:
git clone https://github.com/vercel/platforms.git
cd platformspnpm installCreate a .env.local file with the Upstash Redis credentials:
KV_REST_API_URL=your_redis_url
KV_REST_API_TOKEN=your_redis_tokenThen start the development server:
pnpm devThe main site runs at http://localhost:3000 and the admin panel at http://localhost:3000/admin. Tenant subdomains use the pattern http://[tenant-name].localhost:3000. For local subdomain routing to work, your local DNS must resolve [anything].localhost to 127.0.0.1. On macOS and Linux this typically works out of the box; on some Windows configurations it may require a manual hosts file entry.
Deploying to Vercel with wildcard DNS
The README describes deployment as a push-to-GitHub-then-connect-to-Vercel workflow. After deploying:
1. Add your root domain to the Vercel project settings 2. Set up a wildcard DNS record for *.yourdomain.com pointing at Vercel's DNS
The wildcard record is what allows Vercel to accept requests for any subdomain and route them to your application. Without it, only the root domain and explicitly added subdomains would resolve. Vercel handles TLS certificates for wildcard subdomains automatically when the domain is configured through their interface.
The Redis data model and tenant isolation
Tenant data is stored in Upstash Redis using a key pattern of subdomain:{name}. The admin interface at /admin allows creating and managing tenants through a web form. Each tenant entry in Redis contains the data needed to render that tenant's pages.
The template uses @upstash/redis for the Redis client, which communicates over HTTP rather than the traditional Redis wire protocol. This means it works from serverless functions and edge runtimes where a persistent TCP connection to Redis is not available. The trade-off is that each Redis operation involves an HTTP request, adding latency compared to a persistent connection. Upstash's free plan has rate limits; production workloads with many subdomain requests per second should be tested against those limits.
The components/ directory holds the admin interface components built from Radix UI primitives via shadcn/ui. The lib/ directory contains the Redis utility functions that the proxy and the admin panel share. There is no dedicated type file for the tenant schema; the data shape is inferred from how the Redis keys are read and written in the application code.
Where the template falls short
The template includes no authentication model for tenant users. The admin panel at /admin has no built-in access control; anyone who can reach the URL can manage tenants. Adding authentication is left entirely to the implementer. This is the most significant gap for a production deployment: any team building on this template should treat adding authentication to the admin panel as the first task before deploying to a public URL.
There is also no database beyond Redis. If a tenant's data model requires relational queries, joins, or structured schemas, Redis alone is insufficient. The template would need to be extended with a relational database or a Vercel-native storage option. Redis key-value pairs work well for simple tenant settings and metadata, but poorly for content with relationships.
The @upstash/redis dependency and the proxy.ts subdomain detection logic both assume Vercel as the deployment target. Running the application on a different platform (AWS Lambda, Fly.io, a self-hosted server) requires replacing or adapting both. The README does not document any alternative deployment path. The UI components use shadcn/ui and Radix primitives; these are composable but not themeable without modifying the component source, since shadcn/ui copies component code directly into the project rather than providing a versioned npm package.
Maintenance and licensing
The repository has no license file; the package.json lists the license field as absent. Before adopting the template in a commercial product, verify the licensing status directly with Vercel. The last push was on 2026-07-08. There are no GitHub releases.
The tech stack, Next.js 16, React 19, Tailwind 4, and shadcn/ui, represents the current generation of Next.js application tooling. Tailwind 4 and Next.js 16 are relatively recent major versions; check the Next.js and Tailwind changelogs before upgrading them incrementally to avoid proxy.ts breaking changes.
Editorial conclusion
Developers building a platform product where each customer needs their own subdomain, such as a site builder or a hosted documentation service, should use vercel/platforms as a starting point rather than building subdomain routing from scratch. Organizations that cannot use Vercel for deployment or Upstash for Redis will need to replace both integrations manually, since neither is abstracted behind a swappable interface in the current codebase. The last push was on 2026-07-08; review the proxy.ts logic carefully before deploying, since it encodes environment-specific subdomain detection that may need tuning for non-Vercel hosts.
Frequently asked questions
Does vercel/platforms require an Upstash account?
Yes. The application uses @upstash/redis for tenant data storage, and the KV_REST_API_URL and KV_REST_API_TOKEN environment variables must point to an Upstash Redis instance. The README does not document any alternative Redis provider.
Can vercel/platforms run outside Vercel?
The proxy.ts subdomain detection logic handles Vercel-specific hostname formats explicitly, and the README only documents Vercel deployment. Adapting it to another platform requires modifying proxy.ts and potentially replacing the @upstash/redis client if the target platform does not support HTTP-based Redis.
How does vercel/platforms handle local subdomain development?
Tenant subdomains in local development use the pattern [tenant-name].localhost:3000. The proxy.ts detects the localhost environment and routes requests accordingly. The main admin interface runs at http://localhost:3000/admin.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vercel-platforms)
Community notes