
Three.js Developer Interview Questions (2026): What You'll Be Asked and How to Answer
Whether you're preparing for your first Three.js interview or trying to level up before applying to more senior roles, these are the questions that come up. For each one, we explain what the interviewer is actually trying to find out and what a good answer covers — so you know where to focus your preparation.
Fundamentals
1. What are the three core objects in every Three.js scene, and what does each one do?
What the interviewer wants to know: That you understand the basic architecture before anything else. This is a beginner question, but a vague answer is a red flag regardless of your experience level.
A solid answer covers: Scene — the container that holds all objects, lights, and cameras. Camera — defines the viewpoint and projection (perspective for 3D scenes, orthographic for 2D/UI-like views). Renderer — takes the scene and camera and draws the result to a canvas using WebGL. The renderer's render(scene, camera) call is what actually produces each frame.
Bonus: mention WebGLRenderer specifically, and that antialias: true is a common option you'd set at initialization.
2. How does the render loop work, and what common mistake breaks it in a React app?
What the interviewer wants to know: That you understand requestAnimationFrame and can spot a common bug that affects almost every developer who first combines Three.js with React.
A solid answer covers: You call renderer.render(scene, camera) inside a function that schedules itself with requestAnimationFrame, creating a continuous loop. The bug in React: if your component mounts, starts a loop, then re-renders or unmounts and starts another loop, you end up with multiple overlapping loops firing per frame. The fix is to cancel the animation frame (store the ID, call cancelAnimationFrame in a cleanup function) when the component unmounts.
In React Three Fiber this is handled for you — useFrame runs once per frame in a single loop managed by R3F.
3. How do you load and display a GLTF model? What do you need to handle beyond just the loader?
What the interviewer wants to know: Whether you've actually worked with 3D assets in production, not just basic primitives.
A solid answer covers: Using GLTFLoader to load the file asynchronously, then adding gltf.scene to your Three.js scene. Beyond that, the interviewer wants to hear: setting up lighting (GLTF materials expect a light source, or an environment map via RGBELoader + PMREMGenerator for PBR materials to look right), handling the async load (show a loading state, don't block the UI), and — for large models — using Draco compression (DRACOLoader) to reduce file size.
In R3F: useGLTF from @react-three/drei handles the loading, caching, and Draco setup.
Mid-Level
4. What is dispose() and when do you need to call it?
What the interviewer wants to know: Whether you've shipped a Three.js app that ran long enough to hit memory issues — or whether you've read about it without ever experiencing it.
A solid answer covers: Three.js does not automatically free GPU memory. When you remove a mesh from the scene, the geometry, material, and textures are still allocated on the GPU until you explicitly call geometry.dispose(), material.dispose(), and texture.dispose(). In a long-running app — a product configurator, a page with route transitions, anything that swaps 3D content dynamically — not calling these will cause the GPU memory to grow over time, eventually degrading performance or crashing the tab.
The common place to do this is in a cleanup function: in vanilla JS, when you remove an object; in React, in the useEffect return.
5. Walk me through structuring a scene for a product configurator where users can swap materials.
What the interviewer wants to know: That you can apply Three.js's object model to a real product requirement.
A solid answer covers: Load the product geometry once and keep a reference to it. When the user selects a material option, swap mesh.material to a pre-created material object — don't recreate the mesh. Pre-create the material variants at load time (or cache them), so swapping is instant. Dispose of materials the user will never come back to if memory is a concern. The key insight: the geometry never changes, only the material property on the mesh.
6. What is instancing and when would you use InstancedMesh?
What the interviewer wants to know: Whether you know the single most important draw call optimization in Three.js.
A solid answer covers: Every object in a scene is normally a separate draw call to the GPU. At a few hundred objects this starts to hurt performance. InstancedMesh lets you render thousands of copies of the same geometry in a single draw call, with each instance having its own transform matrix. You'd use it for anything with many repeated objects: particles, trees, crowds, product grids. You update each instance's position via setMatrixAt() and call instanceMatrix.needsUpdate = true.
The tradeoff: all instances share the same geometry and material, so it doesn't work if each object needs a different shape or shader.
7. A Three.js scene runs at 60fps on desktop but drops to 25fps on a mid-range phone. How do you diagnose it?
What the interviewer wants to know: Whether you have a real debugging process or you just guess and tweak randomly.
A solid answer covers two distinct bottleneck types:
CPU-side (JavaScript): Too many objects, too many draw calls. Check renderer.info.render.calls — if you're above ~100–200 draw calls on mobile, start merging or instancing. Chrome DevTools Performance tab shows JS frame time.
GPU-side: Fragment shader complexity, overdraw (many transparent layers rendered on top of each other), or high-resolution textures. Spector.js can capture a frame and show you what the GPU is doing. Symptoms: the CPU frame time looks fine but the frame still drops.
Common mobile-specific fixes: reduce texture resolution, use renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) to cap at 2x, simplify or remove post-processing, reduce shadow map resolution or disable shadows entirely.
Advanced
8. Have you written custom GLSL shaders? What can you do with them that built-in materials can't?
What the interviewer wants to know: Where you sit on the seniority spectrum — this is the clearest signal.
What each level looks like:
- Junior: Uses
MeshStandardMaterial,MeshBasicMaterial, tweaks their properties. Has not written GLSL. - Mid-level: Has used
ShaderMaterialwhen a built-in couldn't do what was needed. Understands uniforms and can modify an existing shader. - Senior: Writes vertex and fragment shaders from scratch. Understands the full pipeline: vertices transformed in the vertex shader, interpolated values (varyings) passed to the fragment shader, uniforms for shared data. Can build effects like dissolve, noise-based displacement, custom lighting models, or data visualizations.
If you haven't written GLSL yet and you're aiming for mid-to-senior roles: Bruno Simon's Three.js Journey has a dedicated shader section, and Book of Shaders is the standard reference for learning GLSL fundamentals.
9. How do you implement click and hover interactions with 3D objects — and what makes it unreliable?
What the interviewer wants to know: That you understand raycasting and its real-world edge cases, not just the happy path.
A solid answer covers: Raycaster casts a ray from the camera through the mouse position and returns intersections with objects in the scene. The basic usage is straightforward. The edge cases are where it gets interesting: raycasting works against the CPU-side geometry, not the rendered pixels — so if you've displaced vertices in a shader (e.g., a wave effect), the clickable area won't match what the user sees. InstancedMesh requires extra setup (raycaster.intersectObjects doesn't work out of the box). Highly subdivided meshes can make raycasting slow since it tests every triangle.
In R3F, @react-three/drei's event system handles most of this with onClick, onPointerOver etc., but the same underlying constraints apply.
10. Describe a Three.js project that hit a technical problem. What went wrong and what did you change?
What the interviewer wants to know: Whether you've actually shipped something and learned from it, or whether your experience is only tutorial projects.
There's no trick here — this is the most honest question on the list. The best answers are specific: not "it was slow" but "it was slow because we had 400 separate meshes for a particle system and we switched to InstancedMesh, which brought draw calls from 400 to 1." Or: "textures weren't being disposed on route change, and after 10 minutes the tab would crash on mobile — we fixed it by adding a cleanup function."
If you're a beginner and haven't shipped a real project yet, say so directly. Then describe what you've built in learning, and what you'd approach differently now that you know more. Honesty about experience level is always better than a vague answer that sounds experienced but isn't.