VRS puts a three.js storefront in a Next.js app, and Airtable holds the products
A serverless virtual reality e-commerce experience powered by Vercel
At a glance
- What is it?
- VRS is Vercel's serverless virtual reality e-commerce demo, a Next.js 12 app with three.js, NextAuth, Stripe Elements and Airtable as the catalogue. It runs with mock data and no credentials, and its stack is pinned to 2022-era versions.
- Who is it for?
- Adopt VRS as a reference if you are building a WebGL product experience with a serverless deployment and want to see how the three.js scene, the Next.js API routes and the payment flow fit together in one codebase. Do not adopt it as a starting point for a new production store, because the dependency set is pinned to Next.js 12 and React 17 and the checkout is a demonstration rather than a payment integration.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months 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 October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A storefront you walk through, not a page you scroll
VRS is described as a fully-functional e-commerce store using Next.js 12, three.js, NextAuth.js, Stripe Elements and Airtable, and the repository description calls it a serverless virtual reality e-commerce experience powered by Vercel.
The virtual reality part is literal. The catalogue is a three.js scene rather than a grid of product cards, and the interaction model is navigation by moving through the space. The homepage of the README points at a live demo at serverless-vrs.vercel.app, and the project homepage given in the repository metadata is vrs.vercel.app, so there are two URLs for the same idea across two eras of the platform's naming.
The three.js version matters. The package.json pins three at ^0.85.2, which is a release from before the modern examples structure and before the physically correct lighting defaults that arrived in later releases. If you are reading this to learn three.js, be aware that the API surface here is old and the conventions in current three.js documentation will not match.
The primary language is TypeScript, the licence is Apache-2.0 with the licence file at the repository root named license.md, and the default branch is master. There are no GitHub releases, and the last push was on 2026-04-19.
Cloning it and running it with no credentials at all
The configuration section is a three step setup, and the second step is where the interesting design decision sits.
Step one is to clone the repository.
$ git clone https://github.com/vercel/vrs.gitStep two is to set up the environment file. In order to run this example locally, you have to set up your environment in the `.env.local` file, and the README tells you to copy `.env.local.example` to `.env.local`, which will be ignored by Git.
cp .env.local.example .env.localThen you add the missing environment variables, and the first group of them is the required set. `NEXTAUTH_SECRET` is a secret value used by NextAuth.js to encrypt JWTs. `STRIPE_PK` and `STRIPE_SK` are Stripe's publishable and secret keys. And `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` are the client ID and client secret of your registered OAuth application within GitHub.
The optional group is what makes this example runnable by anyone. In this example, we're using Airtable as our data source, and if you haven't configured Airtable, this example uses the local mock data that can be found in `mockdata.ts`. You can optionally provide `AIRTABLE_API_KEY`, `AIRTABLE_BASE_NAME`, `AIRTABLE_TABLE_NAME` and `AIRTABLE_VIEW_NAME`.
That fallback is the difference between a demo you can clone and run in a minute and one that blocks on four integrations. The mock data file sits at the top level of the repository, next to next.config.js and package.json, and the repository top level also carries components/, context/, pages/, public/, styles/, utils/ and a declaration.d.ts.
So the checkout flow and the catalogue work out of the box, and the parts that need a live account are the ones that need a live account.
The dependency set tells you what kind of project this is
The package.json is short and revealing, and the versions date it precisely.
Next is pinned to 12.3.7 and React to 17.0.2, with react-dom on the same version. next-auth is at 4.24.14. Stripe's react-stripe-js is at ^1.7.0 with stripe itself at ^8.205.0. Airtable's client is at ^0.11.2. TypeScript is ^4.6.2 and there is a sharp at ^0.30.5 in the dev dependencies, which is the image processing library and is what makes the product imagery work.
The supporting libraries are the interesting part, because they describe the interface design. There is react-motion at ^0.5.0 and react-smooth-scrollbar at ^7.2.2 for the transitions, tween.js at ^16.6.0 for the animation, react-click-outside from a fork by tj, react-color at ^2.12.0 for a colour picker, material-icons at ^1.10.7 for the icon set, tachyons at ^4.7.1 as the CSS utility framework, nprogress for the loading bar and lodash at ^4.17.21.
Tachyons is worth pausing on. The styling is utility class CSS rather than a component library or CSS modules, which fits a project that spends its complexity budget on the 3D scene rather than on a design system. And material-icons paired with tachyons is the combination you would expect from a demo built to look like a real storefront without a design team.
The scripts section is the standard Next.js trio.
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},The yarn.lock at the top level tells you the package manager, and next.config.js holds the Next.js configuration.
What the pieces actually do in the application
Each dependency has a job, and the combination is what makes the demo work.
Next.js 12 supplies the framework, the server side rendering and, importantly here, the API routes. An Airtable-backed catalogue and a payment flow need server-side endpoints, and the Next.js API routes in the pages/ directory are where those live. Deploying that to Vercel means the whole thing, including the API routes, runs as serverless functions, which is where the name comes from.
NextAuth.js handles sign-in, and it is wired to GitHub OAuth rather than to an email and password form, which explains the two GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET variables. The NEXTAUTH_SECRET encrypts the JWTs that keep the session, and it is the one variable that is a genuine secret rather than an identifier.
Stripe Elements handles the card entry, with the publishable key STRIPE_PK sent to the client and the secret key STRIPE_SK used server side. The split between the two keys is the point of Stripe Elements: the card data goes straight to Stripe and never touches your server, so your deployment only needs the secret key for creating the payment intent.
Airtable is the catalogue. It is a spreadsheet API used as a product database, which is a deliberate simplification for a demo, and the four optional variables point at a base, a table and a view. The mockdata.ts file provides the same product list locally so the store has something to show without any of it.
Three.js then does the spatial part, and it is the only dependency that carries the whole concept of the project. Everything else is ordinary e-commerce plumbing with the labels replaced by a spatial interface.
Why this is a demonstration and not a store you can run
Three things separate VRS from something you would put in front of customers, and they are all visible in the repository files.
The first is the version floor. Next 12 and React 17 are both well behind current releases, and the three.js release is older still. A checkout flow built on those versions is a checkout flow you would have to rebuild on a supported stack before shipping, and the security and API changes between those versions are not trivial for a payment path.
The second is the data layer. Airtable is a spreadsheet API standing in for a product database. It is a perfectly good way to get a demo running with a visible catalogue that you can edit by hand, and it is not a way to hold prices, stock levels and variants for a real shop.
The third is that the payment path is a demonstration. The README describes Stripe Elements as one of the components and the keys to set, but it does not describe order persistence, webhook handling, refunds, tax, shipping, or any of the parts of a payment integration that are not the card form. There is no database of orders anywhere in the repository layout.
None of that makes it a poor project. It is doing a specific job, which is showing what a spatial storefront looks like when the whole thing is serverless, and it does that job with a stack that a reader can understand in one pass. The mistake would be to read it as a template.
The upstream assets point the same way. The README links an old now.sh deployment image from assets.zeit.co, which is the platform before it was renamed to Vercel, so the visual references in the file predate the current naming.
Where VRS is the wrong thing to build on
Three cases, and the first is the most common.
If you want a three.js product viewer in a modern Next.js app, do not start from this. The dependency set is the problem rather than the architecture. Next.js 12 with React 17 and three.js 0.85 is far enough back that every tutorial and API reference you would consult while building describes a different framework, and the current App Router, the current three.js examples and the current React patterns all differ from what is in this tree. The architecture is portable, the code is not.
The second is if you want to sell anything. Airtable plus Stripe Elements with no order store is a demonstration of a checkout. If the requirement is that a customer can pay and you can fulfil, you need orders, and there is no order model here to extend.
The third is if you are looking for a maintained reference. The last push was on 2026-04-19, there are no GitHub releases, and the repository is a demonstration rather than a product with a changelog and a support surface.
There is also the GitHub OAuth coupling to think about. Signing in through GitHub OAuth is fine for a demo and awkward for a commercial store, since your customers may not have GitHub accounts. The NextAuth layer would need a second provider, and the README documents only the GitHub one.
For what it is, though, the repository is honest about the boundaries. It names the mock data fallback, it marks the Airtable variables as optional, and it does not claim to be more than an example.
Editorial conclusion
Adopt VRS as a reference if you are building a WebGL product experience with a serverless deployment and want to see how the three.js scene, the Next.js API routes and the payment flow fit together in one codebase. Do not adopt it as a starting point for a new production store, because the dependency set is pinned to Next.js 12 and React 17 and the checkout is a demonstration rather than a payment integration. Verify first what you actually need from it, since the Airtable configuration is optional and the app runs on mockdata.ts without any credentials.
Frequently asked questions
What is VRS?
VRS is a fully-functional e-commerce store example built with Next.js 12, three.js, NextAuth.js, Stripe Elements and Airtable, deployed as a serverless experience on Vercel. The catalogue is a navigable three.js scene rather than a conventional product grid.
How do I run the VRS example locally?
Clone the repository, then copy .env.local.example to .env.local and fill in the variables. The required ones are NEXTAUTH_SECRET, STRIPE_PK, STRIPE_SK, GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET. If you have not configured Airtable, the example falls back to the local mock data in mockdata.ts.
Do I need Airtable to use the VRS example?
No. AIRTABLE_API_KEY, AIRTABLE_BASE_NAME, AIRTABLE_TABLE_NAME and AIRTABLE_VIEW_NAME are all marked optional, and without them the example uses the local mock data found in mockdata.ts, so the store still has a catalogue to show.
What versions does the VRS project depend on?
The package.json pins next at 12.3.7, react and react-dom at 17.0.2, next-auth at 4.24.14 and three at ^0.85.2, with TypeScript at ^4.6.2. The dev scripts are next dev, next build and next start, and the project uses yarn.
How does sign-in work in the VRS example?
Authentication is handled by NextAuth.js wired to GitHub OAuth, which is why the setup needs GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET, and NEXTAUTH_SECRET to encrypt the JWTs that carry the session. The README documents no other sign-in provider.
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-vrs)Was this useful?