All case studies

DEV3 Technologies · own product

FORMA: a 3D fashion storefront template with a real-time product configurator

Our own Next.js storefront template for footwear and apparel: a scroll-choreographed three.js home page, a product configurator built on glTF material variants, procedural 3D apparel and a complete shop, cart and demo checkout.

Industry
Fashion & e-commerce (Next.js template)

Live project preview

DEV3 Technologies · own product — screenshots
Open live demo
3D sneaker hero — a real-time Aero Runner 01 floats over kinetic type with a colourway picker for the fictional FORMA store.

3D sneaker hero — a real-time Aero Runner 01 floats over kinetic type with a colourway picker for the fictional FORMA store.

The challenge

Most 3D e-commerce demos stop at a spinning model on a blank page. A real store needs a shop grid, filters, a cart that survives a reload, a wishlist, search and a checkout, and the 3D has to serve those pages rather than replace them. We wanted a template where 3D does the jobs product photography cannot do (show a colourway and finish change live, take the product apart, keep one consistent look across a whole catalogue) while the store stays fast, honest about being a demo, and easy to point at a real catalogue and payment provider.

Our solution

We built FORMA on Next.js 16 with the App Router, React 19.3, three.js and React Three Fiber, with Lenis for smooth scroll.

Key design decisions

  • Material variants from the file. The sneaker is a glTF model with three KHR_materials_variants. The template reads each variant's base-colour texture through the glTF parser and blends two of them in one physical material, so a colour change plays as a heel-to-toe wipe with a light sheen band instead of a hard swap.
  • More colourways than the file has. A small shader function splits the texture into light, accent and dark panels by saturation and luminance and recolours each, so a catalogue can add colourways without new textures.
  • Finishes as material settings. Knit, Suede and Patent are roughness, sheen and clearcoat presets on the same material.
  • Anatomy from one mesh. The mesh is split at runtime into outsole, midsole, upper and laces by triangle position, with a per-pixel clip for a clean cut line between outsole and midsole, which drives the exploded scroll section.
  • Procedural apparel. Garments are inflated from 2D polygon silhouettes with sheen fabric, a knit normal map and a canvas detail map, so the catalogue has no stock photos. Product images are rendered from the same models by a script.
  • A store without a backend. Cart, wishlist and UI state live in a small external store on useSyncExternalStore, persisted to localStorage, with clear seams for a real cart API and a Stripe Checkout Session.

Results

FORMA ships as a complete Next.js storefront: a 3D home page with hero, drop, categories, studio rail, exploded anatomy and lookbook; shop and category pages with animated filters; product pages with the 3D configurator; cart drawer, bag page, wishlist, search overlay and a four-step demo checkout, with 15 sample products across footwear, apparel and accessories.

It passes TypeScript and ESLint checks, respects prefers-reduced-motion, and builds as a static export for the public live demo. The sneaker model is credited under CC BY 4.0; all other models, renders and copy are original.

FORMA is available on the DEV3 marketplace.

Setup guide

Requirements

  • Node.js 20.9 or newer and npm
  • A browser with WebGL (any current desktop or mobile browser)
  • No environment variables, API keys or database are needed

Install and run

  1. Download the ZIP from your DEV3 account and unzip it.

  2. Open a terminal in the unzipped folder and install the dependencies:

    npm install
    
  3. Start the development server:

    npm run dev
    

    The dev script listens on port 3220; open the address it prints in your browser and scroll through the 3D home page.

  4. Optional checks before you change anything:

    npm run typecheck && npm run lint
    

Build for production

npm run build
npm run start

npm run build creates an optimised Next.js build, and npm run start serves it.

Deploy to Vercel

  1. Push the project to a Git repository (GitHub, GitLab or Bitbucket).
  2. In Vercel, choose Add New → Project, import the repository and keep the detected Next.js settings.
  3. Click Deploy. No environment variables are required.

Any host that runs Node.js (a VPS, Render, Railway, Netlify with the Next.js runtime) works the same way: run npm run build, then npm run start.

Static export

FORMA can be exported as plain static files for any static host or CDN. next.config.ts switches to output: "export" when DEMO_EXPORT_BASE is set to the sub-path the site will live under, for example:

DEMO_EXPORT_BASE=/shop-demo npm run build

The site is written to out/; upload that folder to the matching path. To export to the root of a domain, set output: "export", trailingSlash: true and images: { unoptimized: true } in next.config.ts and run npm run build. The included build:demo script is the one used for our public live demo; edit its values before you use it.

Licence notes

The sneaker model (public/models/shoe.glb) is "MaterialsVariantsShoe" © Shopify, CC BY 4.0, from the Khronos glTF Sample Assets. Keep the credit in the footer and README, or replace the model with your own. FORMA is a fictional brand; replace the name, products and copy before launch.

How to use

Rebrand the store

Open config/brand.ts. It holds the brand name, tagline, season label, currency and locale, the free-shipping threshold, shipping and tax, the localStorage key, navigation, social links, credits and the colour tokens. The tokens become CSS variables on <html> (--paper, --ink, --accent and so on) and every component reads them, so changing accent recolours buttons, badges and highlights everywhere.

Change the fonts in config/fonts.ts. They load through next/font/google and set --font-display, --font-serif and --font-mono. The display font's width axis drives the kinetic type; if you pick a font without one, the type still works but stops stretching. app/globals.css holds layout and motion if you want to restyle beyond the tokens.

Edit products and categories

The whole catalogue is in data/products.ts, fully typed. Each product has a slug, name, subtitle, category, price, optional badge, colours, sizes (with stock; zero shows as sold out), a model, gallery images, description, details, materials, care notes and tags.

  • Colours: each colour has a name, a swatch, an image, stage colours (the background and text around the 3D product), and for the sneaker a glTF variant and an optional tint with light, accent and dark hex values that recolour the texture.
  • Images: image and gallery can be any URL, including real product photos.
  • Categories, lookbook images and the colour-filter families are at the bottom of the same file.
  • The product featured in the home hero is HERO_PRODUCT.

Swap the 3D models

  • Your own glTF/GLB: put it in public/models/ and set model: { kind: "gltf", url: "/models/your.glb" }. The shoe pipeline expects one mesh with a base-colour map. If the file uses KHR_materials_variants, set each colour's variant to the variant name. The exploded anatomy split is tuned for a shoe; other models still work in the viewer.
  • Procedural garments: set model: { kind: "procedural", type: "hoodie" }. Types are tee, longsleeve, crew, hoodie, jacket, shorts, socks, tote, cap and beanie. Add a new shape by adding a polygon to SPECS in components/three/garments.ts.
  • Finishes: Knit, Suede and Patent are presets in FINISHES in components/three/shoe.ts (roughness, sheen and clearcoat). Edit or add presets there.

Re-render product images

Catalogue images are rendered from the 3D models by scripts/render-products.mjs through the hidden /studio route. With the dev server running and Playwright available, run the script with optional product slugs to render only those. It needs a headed Chrome for full-quality WebGL; see the README for the exact command.

Edit the home page story

The home page sections (hero, new-season drop, categories, studio rail, anatomy, lookbook, marquee) live in components/home/HomeView.tsx, and the fixed WebGL scene in components/home/HomeScene.tsx. Edit headlines and copy in HomeView, reorder or remove sections there, and change marquee and kinetic lines in components/home/Kinetic.tsx.

Connect a real backend and payments

  • Catalogue: replace PRODUCTS with data fetched in the server components (app/shop/* and app/product/[slug]/page.tsx) from Shopify Storefront API, Medusa, Sanity or your own database, mapped to the Product type.
  • Cart: lib/store.ts persists to localStorage. Call your API inside add, setQty and remove, and hydrate in load().
  • Payments: the checkout is a demo that never collects card data. In components/checkout/CheckoutView.tsx, replace placeOrder() with a request to a route handler that creates a Stripe Checkout Session and redirect to its URL, then confirm the order server-side.
  • Newsletter: components/layout/Newsletter.tsx is a mock form; post it to your email provider.

Motion and accessibility

Visitors with prefers-reduced-motion get no smooth scroll, marquees, wipes, custom cursor or auto-rotation, and colour changes apply instantly. Keep that behaviour when you add sections by reading the shared reduced-motion flag in lib/live.ts.

Related case studies