Skip to content

Creative Development

React Three Fiber: 3D With A Component Budget.

Use Three.js through React. Keep the page fast enough to matter.

Aidxn
Written by Aiden Wood Founder and Lead Design Engineer
React state to render loop React composes the scene while React Three Fiber owns the Three.js renderer and frame loop. Product content stays outside the decorative scene.

React state to render loop

React composes the scene while React Three Fiber owns the Three.js renderer and frame loop. Product content stays outside the decorative scene.

Preview Radial Gallery

React Three Fiber is a React renderer for Three.js. That distinction matters. It gives React teams a component model for scene graphs, but it does not make 3D cheap, meaningful, or appropriate above every headline.

Use it when a real spatial idea helps a visitor understand a product. Load it after critical content. Keep the message and controls in HTML. If a gradient, SVG, or Radial Gallery tells the story, ship the smaller thing.

A small scene with a real component boundary

A scene component owns its mesh and per frame work. The page component owns the copy, image fallback, and loading boundary. That separation keeps a decorative renderer from becoming your page architecture.

import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { useRef } from 'react';
import type { Mesh } from 'three';

function ProductMark() {
  const meshRef = useRef<Mesh>(null);

  useFrame((_, delta) => {
    if (meshRef.current) meshRef.current.rotation.y += delta * 0.35;
  });

  return (
    <mesh ref={meshRef}>
      <icosahedronGeometry args={[1, 3]} />
      <meshStandardMaterial color='#9d67ff' roughness={0.28} metalness={0.55} />
    </mesh>
  );
}

export function ProductScene() {
  return (
    <Canvas dpr={[1, 1.5]} camera={{ position: [0, 0, 4], fov: 42 }}>
      <ambientLight intensity={1.4} />
      <directionalLight position={[3, 4, 2]} intensity={2} />
      <ProductMark />
      <OrbitControls enablePan={false} enableZoom={false} />
    </Canvas>
  );
}

useFrame writes directly to a ref. Do not put frame state into React state. Calling setState sixty times per second asks React to reconcile a scene that did not need a React update.

Load it as enhancement, not a gate

import { lazy, Suspense } from 'react';

const ProductScene = lazy(() => import('./ProductScene'));

export function ProductHero() {
  return (
    <section>
      <div>
        <p>Velocity Components</p>
        <h1>Build with pieces that earn their bytes.</h1>
        <a href='/components/'>Browse the library</a>
      </div>

      <Suspense fallback={<img src='/images/product-mark.webp' alt='' />}>
        <div aria-hidden='true' className='scene-frame'>
          <ProductScene />
        </div>
      </Suspense>
    </section>
  );
}

In Astro, mount the interactive scene with an appropriate client directive so the document ships before the renderer. The fallback is not a loading apology. It is the page working without 3D.

Choose one performance mode

For an animated object, use the normal frame loop and keep work inside useFrame tiny. For a static preview, request a frame only when props change.

// Static configuration preview: no continuous render loop.
<Canvas frameloop='demand' dpr={[1, 1.5]}>
  <ProductMarkStatic />
</Canvas>

// Animated scene: use the default loop and mutate refs in useFrame.
<Canvas dpr={[1, 1.5]}>
  <ProductMark />
</Canvas>

Do not combine frameloop='demand' with an animation and expect it to move by itself. Demand mode is a useful budget tool when the scene truly is static.

When the component library is the better tool

Three dimensional visuals work best when depth is the content. A product configurator, spatial data view, or real model may earn React Three Fiber. A marketing texture usually does not. Use Shader Backgrounds for ambient WebGL with fallback guards, or Radial Gallery for a visual project browser that stays usable with ordinary links.

This is how a developer subscription stays useful. Velocity Components give you a fast proven option first. Reach for a custom scene when the product requirement is genuinely three dimensional.

Accessibility checklist

  • Treat decorative scenes as hidden from assistive technology.
  • Keep every label, action, and product claim in HTML.
  • Offer a still image or no scene when motion is reduced.
  • Do not make drag or hover the only way to learn something.
  • Check CPU, battery, and interaction response on a real mobile device.

Sources and further reading

Let us make some quick suggestions?

Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.