Three.js with TypeScript: Setup and Common Gotchas
Three.js ships its own TypeScript type definitions built in (no separate @types/three package needed for current versions). Install three and start importing with full type support immediately. The main practical friction points are typing custom shader uniforms correctly and typing TSL node material properties, both of which have straightforward patterns once you've seen them once.
Setup: it just works
Modern Three.js includes its own .d.ts type definitions in the package itself. npm install three and import * as THREE from 'three' gets full autocomplete and type checking with no separate types package. (Older project templates you might find online still reference @types/three as a separate install; that's no longer necessary for current Three.js versions and can actually cause version-mismatch type errors if installed alongside the built-in types.)
Typing custom shader uniforms
ShaderMaterial's uniforms object is typed as a fairly loose { [uniform: string]: IUniform } by default, which means TypeScript won't catch a typo'd uniform name or a wrong value type at the uniforms object itself. The common pattern for stricter typing is defining your own uniforms interface and casting, or, often simpler in practice, switching custom shaders to TSL node materials, where uniform values are typed values from uniform() calls rather than untyped object properties, giving real type safety without extra interface boilerplate.
Common type errors and what they mean
- "Property 'X' does not exist on type 'Object3D'": usually means you're accessing a property specific to a subclass (like
Mesh.materialorLight.intensity) on a variable typed as the more generalObject3D. Fix by typing the variable as the specific subclass, or narrowing with aninstanceofcheck (e.g.if (child instanceof THREE.Mesh)) when traversing a loaded scene graph of mixed object types. - Errors after a Three.js version upgrade: Three.js's public API occasionally changes between releases, and type definitions change with it; check the release's migration notes rather than assuming your code has a bug.
- Type errors from a stale
@types/threeinstall: if you have the separate@types/threepackage still installed alongside a modern Three.js version, remove it. The version mismatch between the external types package and the library's own built-in types is a common source of confusing errors.
Code
Learn this properly
Learn Practical TSL
Your First Node Material
Every lesson in the course uses TSL's naturally type-safe node API.
Frequently asked questions
Do I need @types/three for TypeScript with Three.js?
No, not for current Three.js versions. The library ships its own built-in type definitions. Installing the separate @types/three package alongside it can actually cause version-mismatch type errors.
How do I type a custom Three.js ShaderMaterial's uniforms?
ShaderMaterial's uniforms object is loosely typed by default, so typos or wrong value types aren't caught automatically. Define your own uniforms interface and cast, or switch to TSL node materials, where uniform() calls are typed values with real type safety built in.
Why does TypeScript say a property doesn't exist on Object3D?
You're likely accessing a subclass-specific property (like .material on Mesh) on a variable typed as the more general Object3D. Type it as the specific subclass, or narrow with an instanceof check when traversing a mixed scene graph.
Keep reading
React Three Fiber
React Three Fiber (R3F) is a React renderer for Three.js: it lets you build a Three.js scene declaratively as React comp…
Materials
For most realistic objects, use MeshStandardMaterial: physically-based, responds correctly to lights, and the sensible d…
GLTFLoader
GLTFLoader is the standard way to load 3D models into Three.js: instantiate it, call loader.load(url, onLoad), and add g…
All Three.js Guides
Back to the guides hub.