Skip to content

Three.js - Hello Cube App

Three.js - Your First 3D Scene: “Hello, Cube!”

Section titled “Three.js - Your First 3D Scene: “Hello, Cube!””

Following the tradition of “Hello, World!”, we’ll begin our journey into Three.js by creating a simple scene containing a single rotating cube. This will introduce the fundamental concepts and building blocks of any Three.js application.

While you can use a simple <script> tag to include Three.js, a modern workflow uses a package manager (like npm) and a build tool (like Vite). This gives you a local development server, automatic page reloading, and easy dependency management.

  1. Install Node.js: If you don’t have it, download and install it from nodejs.org.
  2. Create a project: Open your terminal, navigate to a new folder, and run npm init -y. This creates a package.json file.
  3. Install dependencies: Run npm install three to get the Three.js library.
  4. Set up a development server (optional but highly recommended): Run npm install --save-dev vite. Then, add the following to the "scripts" section of your package.json: "dev": "vite".

Create a simple index.html file in your project’s root directory. This will be our entry point.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js - Hello Cube</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
overflow: hidden;
}
.webgl {
position: fixed;
top: 0;
left: 0;
outline: none;
}
</style>
</head>
<body>
<canvas class="webgl"></canvas>
<script type="module" src="./src/main.js"></script>
</body>
</html>

Key points: We have a <canvas> element where our scene will be rendered, and we link to a JavaScript file (./src/main.js) using type="module" to enable modern ES6 imports.

Create a src folder and a main.js file inside it. This is where our Three.js code will live. Every Three.js app needs three core components:

  • Scene: A container for all your objects, lights, and cameras.
  • Camera: The viewpoint from which the scene is observed.
  • Renderer: The engine that draws the scene onto the canvas based on the camera’s perspective.
import * as THREE from 'three';
// 1. SCENE
const scene = new THREE.Scene();
// 2. CUBE (an object in the scene)
const geometry = new THREE.BoxGeometry(1, 1, 1); // Shape
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true }); // Appearance
const cube = new THREE.Mesh(geometry, material); // The final object
scene.add(cube);
// SIZES
const sizes = {
width: window.innerWidth,
height: window.innerHeight
};
// 3. CAMERA
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100);
camera.position.z = 3;
scene.add(camera);
// 4. RENDERER
const canvas = document.querySelector('canvas.webgl');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
// Initial render
renderer.render(scene, camera);

To make the cube rotate, we need an animation loop. We use window.requestAnimationFrame(), which tells the browser to call a function to update the screen before the next repaint. This is more efficient than a simple setInterval.

// ... (previous code)
// ANIMATION LOOP
const clock = new THREE.Clock();
const animate = () => {
// Get elapsed time
const elapsedTime = clock.getElapsedTime();
// Update cube rotation
cube.rotation.x = elapsedTime;
cube.rotation.y = elapsedTime;
// Render the scene
renderer.render(scene, camera);
// Request the next frame
window.requestAnimationFrame(animate);
};
// Start the animation
animate();

If the user resizes their browser window, our scene will look distorted. We need to listen for the resize event and update the camera’s aspect ratio and the renderer’s size.

// ... (before the animation loop)
window.addEventListener('resize', () => {
// Update sizes
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
// Update camera aspect ratio
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();
// Update renderer size
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});

If you set up Vite, you can now run npm run dev in your terminal. This will start a local server, and you can open the provided URL (e.g., http://localhost:5173) in your browser to see your rotating cube! Any changes you save to your files will now update the page automatically.