My favorite moment when teaching kids to code is the exact second their Snake starts moving across the screen. There's this gasp, every time. They wrote the code, they hit run, and now a little green square is sliding across a grid, obeying their instructions. That's the hook. After that, they're all in.
Building a Snake game makes one of the best first projects for kids learning JavaScript. It's simple enough to finish in a few sessions, but it teaches real programming ideas: arrays, loops, conditionals, event listeners, and game logic. Nothing motivates a kid like building something they can actually play.
If your child is new to JavaScript, our guide on what JavaScript is and why it's great for kids is a solid place to start before diving into this project.
What your kid needs to know before starting
Here's the good news: not much. If your child can type reasonably well and understands what a variable is, they're ready. They don't need to have built anything before. Snake is genuinely a beginner project, it just feels advanced because the result is a real game.
That said, a little familiarity with these concepts will help things click faster:
- Variables: storing the snake's position and score
- Arrays: the snake's body is literally a list of coordinates
- If statements: checking for collisions and food
- Functions: organizing the game into manageable pieces
If those terms sound unfamiliar, don't worry. We'll explain each one as it comes up. And if your child wants a head start on arrays specifically, this beginner-friendly guide to arrays breaks them down really well.
Setting up the game board
We're going to build this using an HTML Canvas element, it's basically a drawing surface that lives in the browser. Your kid writes JavaScript to draw on it. No extra tools, no downloads, no frameworks. Just pure HTML and JavaScript.
First, the HTML. It's tiny:
<canvas id="gameBoard" width="250" height="250"></canvas>
<p>Score: <span id="score">0</span></p>
That gives us a 250×250 pixel square to work with. Now in JavaScript, we grab that canvas and set up the basics:
// Get the canvas and set up drawing
const canvas = document.getElementById("gameBoard");
const ctx = canvas.getContext("2d");
const blockSize = 25; // each grid square is 25px
let score = 0;
// Snake starts as 3 blocks
let snake = [
{ x: 50, y: 50 },
{ x: 25, y: 50 },
{ x: 0, y: 50 }
];
// Snake moves right to start
let direction = { x: blockSize, y: 0 };
See that snake array? Each item is a coordinate: the head, middle, and tail. The snake is just a list of positions on a grid. When I explain it this way to kids, the lightbulb goes on. An array isn't some abstract concept anymore. It's the snake's body.
With blockSize = 25 and a 250px board, we get a clean 10×10 grid. Kids can change blockSize to 50 for a 5×5 board (easier) or shrink it to 10 for a 25×25 board (much harder). That kind of tinkering is where the real learning happens.
Making the snake move and eat food
This is where the game comes alive. Every fraction of a second, we need to move the snake forward, check if it ate food, check if it crashed, and redraw everything. That's called a game loop, and it's the beating heart of every video game. (If your kid is curious about how game loops work under the hood, this post digs into that concept.)
Here's the movement logic:
function moveSnake() {
// Create new head position
const newHead = {
x: snake[0].x + direction.x,
y: snake[0].y + direction.y
};
// Add new head to front of snake
snake.unshift(newHead);
// Check if snake ate the food
if (newHead.x === food.x && newHead.y === food.y) {
score++;
document.getElementById("score").innerHTML = score;
placeFood(); // put food somewhere new
} else {
snake.pop(); // remove tail so snake stays same length
}
}
The trick is elegant: every frame, we add a new block at the front (unshift) and remove one from the back (pop). The snake appears to slide forward. But when it eats food? We skip the pop. The snake grows by one block. Kids love this, it's such a clever little trick, and they understand it immediately.
For the food, we just need a random position on the grid:
let food = { x: 0, y: 0 };
function placeFood() {
food.x = Math.floor(Math.random() * 10) * blockSize;
food.y = Math.floor(Math.random() * 10) * blockSize;
}
Now we need keyboard controls. This is where kids learn about event listeners, the browser is listening for key presses and running code when it hears one:
document.addEventListener("keydown", function(e) {
if (e.key === "ArrowUp" && direction.y !== blockSize) {
direction = { x: 0, y: -blockSize };
} else if (e.key === "ArrowDown" && direction.y !== -blockSize) {
direction = { x: 0, y: blockSize };
} else if (e.key === "ArrowLeft" && direction.x !== blockSize) {
direction = { x: -blockSize, y: 0 };
} else if (e.key === "ArrowRight" && direction.x !== -blockSize) {
direction = { x: blockSize, y: 0 };
}
});
Notice those extra checks like direction.y !== blockSize? That prevents the snake from reversing into itself. If you're going right, you can't suddenly go left. It's a small detail, but it's a great teaching moment about conditionals and why we need them.
Drawing everything and detecting collisions
The drawing function clears the board and redraws the snake and food each frame:
function draw() {
// Clear the board
ctx.fillStyle = "#222";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw food
ctx.fillStyle = "red";
ctx.fillRect(food.x, food.y, blockSize, blockSize);
// Draw snake
ctx.fillStyle = "lime";
snake.forEach(block => {
ctx.fillRect(block.x, block.y, blockSize, blockSize);
});
}
For collision detection, we check two things: did the snake hit a wall, or did it hit its own body?
function checkGameOver() {
const head = snake[0];
// Wall collision
if (head.x < 0 || head.x >= canvas.width ||
head.y < 0 || head.y >= canvas.height) {
return true;
}
// Self collision (skip index 0, that's the head)
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
Tie it all together with setInterval to run the game loop:
placeFood();
const game = setInterval(function() {
moveSnake();
if (checkGameOver()) {
clearInterval(game);
alert("Game Over! Score: " + score);
}
draw();
}, 150); // 150ms = snake speed
That 150 controls how fast the snake moves. Kids can change it to 100 for a faster game or 250 for a slower one. I've watched kids spend 20 minutes just tweaking the speed, changing colors, and making the board bigger. That experimentation is real learning.
Making it their own: challenges for older kids
Once the basic game works, the fun really starts. Here are some modifications that push kids to think deeper:
Have them add a speed increase: every 5 points, decrease the interval by 10 milliseconds. This means restructuring the game loop, which teaches them about clearInterval and restarting timers.
They could add obstacles: random blocks on the board that the snake has to avoid. This is just another collision check, but it forces them to think about how game difficulty works.
Or try a wrap-around mode where the snake comes out the other side instead of dying at walls. That's a one-line change per direction (using the modulo operator), and it blows kids' minds when they figure it out.
Snake keeps showing up as a first project for a reason, it hits the sweet spot between "I can understand this" and "I built something cool."
If your child finishes Snake and wants another game project, building a memory matching game is a great next challenge that introduces different programming patterns. Or check out our guide on why game development sparks joy in learning coding.
The best part: they built a real game
What I love about the Snake project is that kids end up with something they're genuinely proud of. It's not a tutorial exercise that gets thrown away, it's a game they can show their friends, tweak endlessly, and point to as proof that they can code. That confidence matters more than any specific JavaScript concept they picked up along the way.
If your child is ready to build Snake (or wants to work up to it with some foundational interactive JavaScript lessons), Learnspace's built-in code editor lets them write, run, and experiment with real JavaScript right in the browser. No setup, no downloads, just start building. Start building games with Learnspace and let them see what they can create.