Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Threejs Impl Drei

  • 19 installs
  • 11 repo stars
  • Updated July 8, 2026
  • openaec-foundation/three.js-claude-skill-package

Helps with ai & agent building tasks.

About

threejs-impl-drei is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • threejs-impl-drei
  • AI & Agent Building
  • AI-coding skill

Threejs Impl Drei by the numbers

  • 19 all-time installs (skills.sh)
  • +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #10,587 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/three.js-claude-skill-package --skill threejs-impl-drei

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs19
repo stars11
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/three.js-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

threejs-impl-drei

Quick Reference

Installation

npm install @react-three/drei @react-three/fiber three

Critical Warnings

ALWAYS wrap components that use loader hooks (useGLTF, useTexture, useFBX, useKTX2, useFont) in <Suspense fallback={...}>. Omitting Suspense causes the entire React tree to crash.

ALWAYS add makeDefault to your primary camera controls (<OrbitControls makeDefault />). Without makeDefault, Drei controls do NOT integrate with R3F's event system and pointer events break.

NEVER use an invalid Environment preset name. The ONLY valid presets are: apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse.

NEVER forget to call .preload() for critical assets. Use useGLTF.preload('/model.glb') at module scope to start loading before component mount.

ALWAYS use <Instances> for rendering more than 100 identical meshes. Individual meshes cause one draw call each; instances batch them into one.

---

Controls

OrbitControls

The most common camera control. Orbit, zoom, and pan around a target.

import { OrbitControls } from '@react-three/drei'

<OrbitControls
  makeDefault           // ALWAYS add — integrates with R3F events
  enableDamping         // smooth movement
  dampingFactor={0.05}
  minDistance={2}
  maxDistance={20}
  minPolarAngle={0}
  maxPolarAngle={Math.PI / 2}  // prevent going below ground
/>

Other Controls

ComponentUse Case
CameraControlsFull-featured camera (recommended for complex scenes)
MapControlsTop-down map navigation (orbit restricted to vertical axis)
PresentationControlsDrag-to-rotate with spring physics (product viewers)
ScrollControlsScroll-driven animation (pages prop sets scroll length)
TransformControlsTranslate/rotate/scale gizmo on selected objects
DragControlsDrag objects in 3D space
KeyboardControlsKeyboard input as React context
FaceControlsFace-tracking camera movement

ScrollControls Pattern

import { ScrollControls, useScroll } from '@react-three/drei'

<ScrollControls pages={3} damping={0.1}>
  <ScrollScene />
</ScrollControls>

function ScrollScene() {
  const scroll = useScroll()
  useFrame(() => {
    const offset = scroll.offset // 0 to 1
  })
  return <mesh />
}

---

Environment and Staging

Environment

Loads HDR environment maps for realistic reflections and lighting.

import { Environment } from '@react-three/drei'

// Preset (downloads from polyhaven CDN)
<Environment preset="city" background blur={0.5} />

// Custom HDR file
<Environment files="/env.hdr" background />

// Custom environment with Lightformers
<Environment background>
  <Lightformer form="rect" intensity={2} position={[0, 5, -5]} scale={[10, 5, 1]} />
</Environment>

Valid presets: apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse.

Stage

Complete lighting and shadow setup in one component. Ideal for product viewers.

import { Stage } from '@react-three/drei'

<Stage preset="rembrandt" intensity={0.5} environment="city" adjustCamera>
  <Model />
</Stage>

Shadow Components

ComponentUse CaseKey Props
ContactShadowsSoft ground shadows (no light needed)opacity, scale, blur, far, resolution, color
AccumulativeShadowsHigh-quality baked soft shadowsframes, alphaTest, scale, opacity
RandomizedLightChild of AccumulativeShadowsamount, radius, intensity, position
BakeShadowsBake shadow maps once, stop updating
SoftShadowsPCSS soft shadows for real-time lights

AccumulativeShadows Pattern

<AccumulativeShadows temporal frames={100} scale={10} position={[0, -0.5, 0]}>
  <RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
</AccumulativeShadows>

Atmosphere

ComponentPurposeKey Props
SkyProcedural sky domesunPosition, turbidity, rayleigh
StarsParticle starfieldradius, count, factor, fade
SparklesFloating particlescount, size, speed, color
CloudVolumetric cloudsopacity, speed, segments, bounds

---

Text and HTML

Text (SDF)

High-quality 2D text rendered with signed distance fields via troika-three-text.

import { Text } from '@react-three/drei'

<Text
  fontSize={0.5}
  color="white"
  anchorX="center"
  anchorY="middle"
  maxWidth={2}
  font="/fonts/Inter-Bold.woff"
>
  Hello World
</Text>

Text3D

Extruded 3D geometry text. Requires a JSON font file (use facetype.js to convert).

import { Text3D, Center } from '@react-three/drei'

<Center>
  <Text3D font="/fonts/Inter_Bold.json" size={0.75} height={0.2} bevelEnabled bevelSize={0.02}>
    Hello
    <meshStandardMaterial color="orange" />
  </Text3D>
</Center>

Html

Renders DOM elements positioned in 3D space.

import { Html } from '@react-three/drei'

<mesh position={[0, 2, 0]}>
  <Html
    transform            // transforms with 3D position
    distanceFactor={10}  // scales with distance
    occlude              // hides behind 3D objects
    center               // centers the HTML element
    className="label"
  >
    <div style={{ color: 'white' }}>Annotation</div>
  </Html>
</mesh>

Billboard

ALWAYS faces the camera. Use for labels and sprites.

import { Billboard, Text } from '@react-three/drei'

<Billboard follow={true} lockX={false} lockY={false} lockZ={false}>
  <Text fontSize={0.5}>Always Visible</Text>
</Billboard>

Hud

Renders a heads-up display in a separate orthographic scene.

import { Hud, OrthographicCamera } from '@react-three/drei'

<Hud renderPriority={1}>
  <OrthographicCamera makeDefault position={[0, 0, 5]} />
  <Text position={[0, 0, 0]} fontSize={0.1}>HUD Text</Text>
</Hud>

---

Materials

ComponentPurpose
MeshReflectorMaterialReflective floors with blur, distortion, resolution
MeshTransmissionMaterialGlass with chromatic aberration, distortion, thickness
MeshRefractionMaterialRefraction using environment cube map
MeshWobbleMaterialAnimated wobble on MeshStandardMaterial
MeshDistortMaterialPerlin noise distortion on MeshStandardMaterial
MeshDiscardMaterialRenders nothing (shadow-only objects)
shaderMaterialHelper to create custom ShaderMaterial as JSX

MeshReflectorMaterial Example

<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
  <planeGeometry args={[50, 50]} />
  <MeshReflectorMaterial
    blur={[300, 100]}
    resolution={1024}
    mixBlur={1}
    mixStrength={50}
    roughness={1}
    depthScale={1.2}
    minDepthThreshold={0.4}
    maxDepthThreshold={1.4}
    color="#151515"
    metalness={0.5}
  />
</mesh>

shaderMaterial Helper

import { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'

const WaveMaterial = shaderMaterial(
  { uTime: 0, uColor: new THREE.Color(0.2, 0.0, 0.1) },
  /* vertex */ `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`,
  /* fragment */ `uniform float uTime; uniform vec3 uColor; varying vec2 vUv; void main() { gl_FragColor = vec4(vUv * uColor, 1.0); }`
)
extend({ WaveMaterial })
// Usage: <waveMaterial uTime={clock.elapsedTime} />

---

Loaders

ALWAYS wrap loader-consuming components in <Suspense>.

HookReturnsPreload
useGLTF(url){ nodes, materials, scene, animations }useGLTF.preload(url)
useTexture(url)THREE.Texture or map objectuseTexture.preload(url)
useFBX(url)THREE.GroupuseFBX.preload(url)
useKTX2(url)Compressed textureuseKTX2.preload(url)
useFont(url)Font data for Text3DuseFont.preload(url)
useAnimations(clips, ref){ actions, names, mixer, ref }
useVideoTexture(url)THREE.VideoTexture

useGLTF Pattern

import { useGLTF } from '@react-three/drei'

function Model(props) {
  const { nodes, materials } = useGLTF('/model.glb')
  return (
    <group {...props}>
      <mesh geometry={nodes.Body.geometry} material={materials.Metal} />
    </group>
  )
}
useGLTF.preload('/model.glb')

useTexture with Multiple Maps

const textures = useTexture({
  map: '/color.jpg',
  normalMap: '/normal.jpg',
  roughnessMap: '/roughness.jpg',
  aoMap: '/ao.jpg',
})
// Spread directly onto material
<meshStandardMaterial {...textures} />

useAnimations Pattern

function AnimatedModel() {
  const group = useRef()
  const { nodes, animations } = useGLTF('/character.glb')
  const { actions } = useAnimations(animations, group)

  useEffect(() => {
    actions['Walk']?.play()
    return () => actions['Walk']?.stop()
  }, [actions])

  return <group ref={group}><primitive object={nodes.Scene} /></group>
}

---

Performance

Instances

ALWAYS use for large numbers of identical meshes (>100). Reduces draw calls from N to 1.

import { Instances, Instance } from '@react-three/drei'

<Instances limit={1000} range={1000}>
  <boxGeometry />
  <meshStandardMaterial />
  {positions.map((pos, i) => (
    <Instance key={i} position={pos} color="orange" />
  ))}
</Instances>

Merged

Merges different geometries into a single draw call.

import { Merged } from '@react-three/drei'

function Furniture({ nodes }) {
  return (
    <Merged meshes={[nodes.Chair, nodes.Table, nodes.Lamp]}>
      {(Chair, Table, Lamp) => (
        <>
          <Chair position={[0, 0, 0]} />
          <Table position={[2, 0, 0]} />
          <Lamp position={[1, 1, 0]} />
        </>
      )}
    </Merged>
  )
}

Performance Helpers

ComponentPurpose
DetailedLOD — switches geometry based on camera distance
BakeShadowsBakes shadows once, stops updating
AdaptiveDprLowers device pixel ratio during performance drops
AdaptiveEventsReduces event frequency during performance drops
PerformanceMonitorMonitors FPS, triggers regression callbacks
BvhBVH-accelerated raycasting for complex meshes
meshBoundsFast bounding-box raycasting (replaces per-triangle)

PerformanceMonitor Pattern

<PerformanceMonitor
  onIncline={() => setDpr(2)}
  onDecline={() => setDpr(1)}
  flipflops={3}
  onFallback={() => setDpr(0.5)}
/>

---

Staging and Layout

ComponentPurposeKey Props
CenterCenters children at origintop, right, bottom, left, front, back
FloatFloating hover animationspeed, rotationIntensity, floatIntensity
BoundsAuto-fit camera to contentfit, clip, observe, margin
ResizeNormalizes children to unit sizewidth, height, depth

---

Abstractions and Effects

ComponentPurpose
EdgesRenders wireframe edges
OutlinesScreen-space outlines
TrailMotion trail behind objects
DecalProject texture onto mesh surface
SplatGaussian splatting renderer
CloneDeep clone with shared geometry/materials
ImageTexture-mapped plane with shader effects
MeshPortalMaterialPortal — renders scene inside mesh surface
GradientTextureProcedural gradient texture

---

Gizmos

ComponentPurpose
GizmoHelperViewport orientation widget
PivotControlsInteractive pivot gizmo (translate/rotate/scale)
TransformControlsThree.js TransformControls wrapper
GridInfinite configurable grid plane
Helper / useHelperVisualize light/camera helpers

---

Component Selection Guide

ScenarioComponent
Product viewerStage + OrbitControls + Environment
Architectural walkthroughCameraControls + Environment + ContactShadows
Scrolling experienceScrollControls + useScroll
Data visualizationInstances + Html + Billboard
Text labels in 3DText (2D) or Text3D (extruded) + Billboard
Glass/transparent objectsMeshTransmissionMaterial + Environment
Reflective floorsMeshReflectorMaterial
Large identical meshesInstances (>100) or Merged (mixed geometries)
Model loadinguseGLTF + Suspense + .preload()
HUD / overlayHud or Html with fullscreen

---

Reference Links

  • references/methods.md -- Key component props and hook signatures
  • references/examples.md -- Complete working examples
  • references/anti-patterns.md -- Common mistakes and fixes

Official Sources

  • https://drei.docs.pmnd.rs/
  • https://github.com/pmndrs/drei
  • https://r3f.docs.pmnd.rs/

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.