Product Viewer

@sushindustries/react-product-viewer

A 3D product viewer for TanStack applications, documented with itself.

12 min read
View as MarkdownEdit on GitHub

Below is the real component, loading the real asset — the Sushindustries mark, reconstructed from a 500,000-triangle scan and decimated to 40,000, with four finishes authored into the GLB.

Drag it.

Viewport width
Phone22remthe floor, the narrowest this promises to work at
tanstacktanstack add https://adamjurek.com/r/tanstack/product-viewer.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/product-viewer.json

That is not a screenshot and not a video. It is the component this page documents, mounted from the same package you would install, which is why it cannot go out of date.

Why it is built for TanStack

Two optional entry points, and both of them are the reason this exists rather than another <model-viewer> wrapper:

// Query owns the asset, so a route loader preloads it — on hover, under
// defaultPreload: "intent" — and cache eviction actually frees the GPU.
import { productModelOptions } from "@sushindustries/react-product-viewer/query";

// Router owns the selection, so a configured product is a URL you can send.
import { useVariantSearch } from "@sushindustries/react-product-viewer/router";
ts

If Query owns the GLB, the model is in memory before the route renders. If Router owns the selection, "the mark, in white" is a link.

Disposal is not optional

three.js does not garbage-collect GPU memory. The core package pairs loadProductModel with disposeProductModel, and a viewer that mounts and unmounts without calling it leaks until the tab closes.

Install

tanstack add https://adamjurek.com/r/tanstack/product-viewer.json
shell
pnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/product-viewer.json
shell
pnpm add @sushindustries/ui @sushindustries/atoms
shell

What you get

Version0.1.0
Category3d · Scenes
Fileselements/model-viewer/model-viewer.tsx
Dependencies@sushindustries/react-product-viewer@workspace:*, @react-three/fiber@9.7.0, @react-three/drei@10.7.8, three@0.185.1
Tagsblock, 3d, perspective, facade, responsive
Used byProduct VariantsProduct VariantsOne model, several configurations, switched without reloading the asset - the GLB already holds them.@sushindustries/ui · 3d