Award Site Teardowns
中文

Bruno's Portfolio

Bruno's Portfolio is the personal portfolio of French creative developer Bruno Simon, built as a small island that visitors explore in a toy jeep. At the start, the screen shows a glowing ring that shrinks to a point, and a small round patch of ground grows out of it with a red jeep parked on top. When the visitor clicks to start, the patch spreads into the whole island, and each part of the content sits wherever the jeep can drive to. The sky and the seasons follow the real clock, so everyone who opens the site at the same moment sees the same dusk, and messages left by other visitors float over the island.

Bruno Simon designed and built the site alone. The FWA gave it FWA of the Year for 2025 and the visitor-voted People's Choice Award for the same year, it won the day and month awards on both platforms, and Awwwards added a Developer Award.

The landing area by day, with the giant lilac 3D letters BRUNO SIMON on the ground, the red jeep parked beside a street lamp and a pink tree, a message left by another visitor reading LOVING YOUR WORK BRUNO! floating next to the jeep, a black notice bar at the top centre reading SERVER CONNECTED, and a red-roofed hut on the right
The landing area by day, with the giant lilac 3D letters BRUNO SIMON on the ground, the red jeep parked beside a street lamp and a pink tree, a message left by another visitor reading LOVING YOUR WORK BRUNO! floating next to the jeep, a black notice bar at the top centre reading SERVER CONNECTED, and a red-roofed hut on the right

01Concept

The first page of the Bruno's Portfolio menu carries a welcome note. In it, Bruno Simon gives a short self-introduction as a creative developer who works mostly for the web. The note then asks visitors to drive around to learn about the author and discover the many secrets of this world, and ends by asking them not to break anything. A portfolio is usually a page with a list of projects, but this site splits projects, career and contact details across thirteen areas of an island, and visitors have to drive to whatever they want to see. Finding the content becomes part of the fun, though visitors also have to learn to drive before they reach a single project.

The areas fall into two groups, and the first group holds the serious portfolio content. The projects area prints the work on boards standing in the ground, the career area turns each job into a coloured strip on the ground with an engraved stone slab, and there is also a lab. One more area holds a time machine, and when the visitor drives up and presses the interact key, the site opens the previous version of Bruno Simon's portfolio from 2019. The second group of areas exists purely for fun, such as a race track that runs around half the island, a neon bowling alley and a wooden outhouse with a moon glowing on its door at night. Visitors start from the landing area in the middle of the island, which keeps every area within a short drive. Pressing M opens a top-down map of the whole island, where white diamonds mark the places, and clicking one teleports the jeep straight there.

The top-down map of the whole island, with a race track edged in red and white kerbs along the left and top, grass, sand and winding channels of water in the middle and on the right, a dozen or so white diamonds marking places, the red jeep icon at the lower right, and the darkened landing area showing behind the map on both sides
The top-down map of the whole island, with a race track edged in red and white kerbs along the left and top, grass, sand and winding channels of water in the middle and on the right, a dozen or so white diamonds marking places, the red jeep icon at the lower right, and the darkened landing area showing behind the map on both sides

Bruno's Portfolio also gives visitors plenty of reasons to stay and come back, starting with the achievements page in the menu, which lists 38 achievements, such as visiting every area, seeing every project in the projects area, and staying on the site for one full day-night cycle. Bruno Simon writes in the Awwwards case study that unlocked achievements also change the look of the jeep. The race track has a leaderboard that resets every day and shows the flags and lap times of the top ten visitors. Pressing T lets a visitor leave a whisper of up to 30 characters. The island holds at most 30 whispers at a time, each visitor can leave only one, and a new whisper pushes out the oldest. A cookie stand and an altar on the island each keep a counter, and every visitor's interactions there add to the same number.

After all this play, the portfolio ends at the behind-the-scene page in the menu. That page explains the technology behind the site and thanks the creator of three.js and the developer who added TSL to it. It then points visitors to Bruno Simon's own three.js course Three.js Journey, the video devlogs of the build and the source code published on GitHub. The published source code is under the MIT license and even includes the Blender files. A visitor who has seen the whole island and wonders how it was made ends up at a course that teaches how to build sites like this, so the island also works as the best sample of that course.

02Design

Bruno's Portfolio turns the whole island into a toy diorama on a tabletop. The camera always looks down at the same slanted angle, and visitors can only pan and zoom, not rotate, so everything on the island reads like a set of miniature models. Every model is low-poly, built from large flat faces with no realistic texture. The grass is a field of sharp triangles, the tree crowns are clumps of fragments, and white wave lines run along the water's edge. Bruno Simon writes in the case study that every colour on the island comes from one small palette, with each model simply picking squares from it. As a result the same reds, oranges, pinks and purples recur everywhere, and the picture never turns messy however busy it gets.

The light and colour on the island follow the time of day, and this is where the picture changes most. The site defines a colour set for each of four times of day, made of a sunlight colour, a shadow colour and two fog colours. By day the sunlight is a warm peach (#FFD2C2) while the shadows are a saturated purple (#6D3FFF), and the fog blends from cyan to pale violet. At dusk the sunlight turns coral red (#FF8181) and the fog blends from blue to pink, while at dawn the sunlight is orange (#FFA882) with magenta-leaning shadows (#DB004F). At night the light is a deep blue (#3240FF) more than three times as bright as the daylight, the whole island sinks into blue-violet, and the warm glow of lanterns and signs becomes the strongest colour on screen. In all four sets the shadows are not grey but a colder, more saturated colour than the sunlight, so nothing in shadow looks dirty and the picture always reads like a cartoon illustration.

A stretch of shore at night, with the whole picture in deep blue-violet, bright blue wave lines along the water's edge, many leaves floating on the water, a lit lantern beside a wooden outhouse with a yellow moon glowing on its door, the red jeep parked on the sand, and two more lanterns in the distance
A stretch of shore at night, with the whole picture in deep blue-violet, bright blue wave lines along the water's edge, many leaves floating on the water, a lit lantern beside a wooden outhouse with a yellow moon glowing on its door, the red jeep parked on the sand, and two more lanterns in the distance

The plants on the island get a lot of depth out of very few shapes. Each tree is a trunk plus a clump of foliage cards that face the camera, with the outlines of individual leaves drawn on the cards and two colours for the sides facing toward and away from the sun. The island has three kinds of tree, birch, oak and cherry, and the cherries are pink while the leaves of the other two show as yellow, orange and red on screen. When a tree crown sits between the jeep and the camera, the leaves covering the jeep thin out and turn see-through, so the visitor can always see the car.

The interface of Bruno's Portfolio has only a few parts, but its colours and type are clearly defined. Titles, notices and the text floating over the island all use the bold weight of Amatic SC, a tall, narrow handwritten face, as in CLICK TO START, SERVER CONNECTED and the visitors' whispers, while body text uses the rounded Nunito. The panels are two very dark purple-greys (#251F2B, #1D1721) with white text. The accent is a very pale pink (#FFCECA), used for the menu icons, achievement titles and progress bars, and the thin countdown line under each notice. Completed achievements and successful actions switch to a lime green (#D5FF95), and the menu, map and close buttons are a deep red (#C21515).

The shapes of the interface parts are as plain as the colours. The styles contain no rounded corners at all, so every panel and button is square, which next to the handwritten type makes the interface look cut from paper and lettered with a marker. When the visitor opens the menu, a row of seven icon squares along the top switches between pages such as home, options and achievements, with the selected square brighter than the rest. Each page has a live-rendered scene from the island on its left.

On phones and tablets the island stays the same, but the camera angle is steeper, closer to looking straight down, and the interface is rearranged for the narrow screen. CLICK TO START on the opening screen becomes TAP TO START, and the menu and map buttons at the top right stack into a column of squares. When the jeep reaches something it can interact with, a large INTERACT button appears at the bottom of the screen in place of the Enter key on desktop. On phones the menu fills the whole screen, and the live-rendered scene moves from the left of the text to above it.

Three phone screens. On the left, the landing area after the start. In the middle, the white ring that appears around the jeep while a finger holds the screen, with a MAP label beside the jeep and INTERACT at the bottom. On the right, the full-screen menu with a row of icons at the top, and below them a picture of the jeep parked on a round patch of ground above the BRUNO'S HOME welcome note
Three phone screens. On the left, the landing area after the start. In the middle, the white ring that appears around the jeep while a finger holds the screen, with a MAP label beside the jeep and INTERACT at the bottom. On the right, the full-screen menu with a row of icons at the top, and below them a picture of the jeep parked on a round patch of ground above the BRUNO'S HOME welcome note

03Motion

Bruno's Portfolio turns the loading process itself into the opening animation. The black ground is covered with a purple grid of crosses, and the glowing arc in the middle of the grid is the loading progress, growing longer as more of the assets arrive. The arc never jumps to a new position. Each frame it closes only a small part of the remaining gap, so it grows smoothly. When the download finishes, the closed ring shrinks to a point, slowly at first and then faster, in about 1.5 seconds.

Once the ring is gone, a round patch of ground grows outward from the same point, reaching full size in about 2 seconds and overshooting slightly before settling back. At the same time, the camera pulls back a little from a very close position over about 1.25 seconds. One second after the patch begins to grow, the handwritten CLICK TO START pops up with a speaker icon, wobbling like jelly a few times before it settles. When the cursor moves over the patch, its brightness rises by about a fifth in 0.2 seconds to tell visitors it can be clicked.

When the visitor clicks to start, the round patch keeps spreading, this time until it covers the whole island. CLICK TO START first shrinks away in 0.3 seconds. The patch pulls in slightly, then spreads outward faster and faster until the whole island is revealed after about 2 seconds, while the camera keeps pulling back over about 1.75 seconds to its normal driving distance. The edge of the patch is always a thin glowing line of pink-violet, so what the visitor sees is a ring of light pushing outward and lighting up the island bit by bit.

After the opening, driving is the main thing visitors do. The jeep picks up speed quickly, reaching top speed in about 0.6 seconds, and comes to rest about 1 second after the visitor lets go of the keys, so it feels light and responsive without stopping dead the moment the key is released. Each of its four wheels has its own suspension, so the body rocks over bumps, and driving too hard can flip it over. The title in the browser tab also follows the jeep's speed, with the jeep emoji in it driving faster and the trees behind it rushing past.

The camera follows the jeep with a little give. Each frame the camera closes only a small part of the remaining distance, so the jeep always stays slightly ahead of it and turns and acceleration carry a slight drag. On desktop, the faster the jeep goes, the further the camera pulls back, so visitors see more of the island when driving fast. When the visitor holds the left mouse button and drags, the camera leaves the jeep and pans in the direction of the drag. The camera behaves as if it were tied to the jeep with a rubber band, pulling back harder the further it is dragged, and once the visitor lets go, it returns to the jeep on its own.

Most things on the island can be knocked over. Benches, lanterns, bricks and the giant letters all fly when the jeep hits them, and several red explosive crates are scattered around the island. When the jeep touches a crate, there is a click, and about 0.4 seconds later the crate goes off. A cartoon fireball swells to full size in 0.6 seconds, fast at first and then slower, and then burns through from the inside over about 2 seconds, with a dark outline along the edge of the burned-out part. The blast throws everything within about 5 metres upward and outward, harder the closer it is, while the camera tilts to one side, more steeply the closer it is to the blast, and the leaves on the ground scatter. When a blast goes off very close to the jeep, the whole game slows to half speed for about 1.5 seconds, sliding into the slowdown in a third of a second and takes about 3 seconds to recover, like a slow-motion shot in a film.

The moment an explosive crate goes off, with a yellow and red cartoon fireball at the top centre, the O and N of BRUNO SIMON blown into the air, the M lying beside a skull altar with a red sword stuck in it, a bench and several pink and yellow trees on the left, a sculpture made of a keyboard, a gamepad and a joystick at the top right, and a pile of white bricks with a lantern by the water at the lower right
The moment an explosive crate goes off, with a yellow and red cartoon fireball at the top centre, the O and N of BRUNO SIMON blown into the air, the M lying beside a skull altar with a red sword stuck in it, a bench and several pink and yellow trees on the left, a sculpture made of a keyboard, a gamepad and a joystick at the top right, and a pile of white bricks with a lantern by the water at the lower right

Even when the visitor stops the jeep, the island keeps moving. Leaves and grass sway in the wind, harder as the wind picks up. Fallen leaves swirl along the ground and get swept up and pushed aside when the jeep drives through them. A full day-night cycle lasts 4 minutes, with day and night each taking about a minute and dusk and dawn in between. The light and colour fade gradually from one phase to the next, so while the visitor drives, the surroundings turn from day to dusk and then to night. The seasons follow the real calendar, with the most fallen leaves in autumn, snow and frozen water in winter when the temperature drops low enough, and rain and lightning whenever humidity and cloud cover run high.

On phones, driving switches to a method that needs only one finger. When the visitor holds the screen, a white ring appears on the ground around the jeep. The jeep drives toward whichever side of the ring the finger is on, the further the finger is from the jeep the more throttle it gives, and the fill inside the ring grows to match. With the finger behind the jeep, the jeep reverses. Two fingers drag and pinch to pan and zoom the camera.

Whether the jeep is standing still or boosting across the island, Bruno's Portfolio holds the picture at about 60 frames per second while the grass, trees and weather keep moving. When a visitor turns on the reduced-motion setting in the operating system, the site ignores it, and the leaves, wind, sky and opening animation all play as usual.

04Engineering

Bruno's Portfolio draws the whole island with the WebGPURenderer of three.js r183. Every shader is written in TSL, the node language of three.js. The same code compiles to WGSL in browsers that support WebGPU and falls back to WebGL in those that do not, and the options page in the menu shows which one is in use.

The whole game runs on one loop, driven by the renderer's setAnimationLoop, and every system in the loop runs in a fixed numbered order. The loop reads input first, then lets the player and the jeep apply forces before physics, and then steps the Rapier physics engine. Only after physics do the camera, the day cycle, the weather and the island's many systems update. The instanced models, sound and interface follow, and rendering comes last. As a result, the camera always reads the jeep's position after this frame's physics, and the picture never jitters.

The whole island is built in Blender, whose file doubles as the level editor, and Bruno Simon writes in the case study and the GitHub readme that an object's name decides how it behaves in the game. Objects whose names contain Physical or Fixed become physics bodies that can be knocked around or stay fixed, and colliders, respawn points and area boundaries are all marked with empties in Blender. Every model takes its colour from the same palette texture, with the UVs of each face pointing at one square of the palette. On export, the palette node used for previews in Blender is muted, and the site swaps in its own materials. Models are compressed with Draco and quantised vertices, and textures are packed into KTX with gltf-transform and toktx, mostly as ETC1S with UASTC for the few that need detail. The visitor's browser uses the Basis transcoder to turn these KTX textures into a format the GPU reads directly, which on desktop is BC7.

The jeep runs on Rapier's vehicle controller, with the body as a dynamic rigid body and the four wheels as raycasts pointing down, each with its own suspension spring and damping, so the jeep rises and falls over uneven ground. The site also checks whether the jeep is stuck, flipped or upside down, and pressing R or the I'm stuck button in the options brings it back to a respawn point. The explosive crates on the island are light rigid bodies that start asleep, and a collision callback sets off the blast. The impulse of a blast falls off linearly with distance and points outward with an upward component added. When a blast lands too close to the jeep, the site sets the time scale of both the game loop and the GSAP global timeline to 0.5 at once. Physics, particles and every tween therefore slow down together, and no single system needs its own slow-motion code.

The grass on the island is drawn in a single draw call. About 78,400 blades, each a single triangle, sit in one geometry laid out as a 280 by 280 grid. The grid does not cover the whole island but surrounds the camera's focus point. The shader wraps each blade's position modulo the grid size, so as the jeep drives forward, the blades that fall behind wrap around to the front, which reads as an endless field. Each blade gets a little random height, and its colour comes from the terrain texture, so the grass always matches the ground beneath it.

The same savings apply to the other large or repeated things on the island. The water, terrain and rain loop the same way, drawing only a patch around the camera. Repeated objects such as trees, foliage, benches, lanterns and bricks all use instanced drawing, with 24 instanced meshes drawing about 2,950 objects across the scene, and together with frustum culling this keeps each frame to about 250 to 275 draw calls.

The tree crowns and the fallen leaves each have their own shader that lets them move with the wind and the jeep. Each clump of foliage is a camera-facing plane, and the fragment shader cuts out the outline with a leaf-shaped texture at a threshold of 0.3. The texture lookup rotates with the wind, so the leaf outlines shiver in the breeze, and the shader also knows where the jeep is on screen and cuts away more of the foliage the closer it is to the jeep, which is why tree crowns turn see-through when they cover the car. The fallen leaves on the ground are compute particles on the GPU, numbering between 128 and 2,048 depending on the season. Each frame the site passes the jeep's position and velocity to the compute shader, which pushes and lifts the leaves, and blasts add an impulse to the leaves through the same shader. This is the one compute pass in each frame.

The day cycle and the seasons need no server, yet they stay in sync for every visitor. Both cycles compute their progress straight from Date.now() divided by the cycle length, which is 240 seconds for a day and a real 365 days for the year. Visitors anywhere in the world therefore get the same time of day and the same season at the same moment. Each time of day and each season is a set of keyframes, and when progress falls between two sets, colours and values are interpolated proportionally.

The weather adds another layer of change on top of the season and stays in sync for every visitor as well, because the noise it uses also takes the clock-based day progress as its input. The temperature is the season's temperature plus the daily swing plus a noise made by multiplying three sines of different frequencies, so it drifts up and down irregularly. Rain starts once humidity passes 0.65, scaled by the cloud cover, and when the temperature drops below 0 degrees the rain turns to snow.

The only things in Bruno's Portfolio that actually talk to a server are the whispers, the race leaderboard and the two global counters, all over the same WebSocket connection. When the server is offline, the page carries an offline flag and the island still plays as usual, except that race times cannot be saved. The case study says every whisper passes through OpenAI's moderation before it is shown.

The island is drawn into several buffers and post-processed every frame before it reaches the screen, taking about 19 render passes in all. The shadow map is 2048 by 2048, and the scene is first drawn into four full-resolution half-float buffers. Bloom runs at half resolution with a threshold of 1, so only things brighter than white, such as lanterns, fireballs and the ring of the opening, glow. On high quality, a cheap depth-of-field pass before the bloom softly blurs the edges of the picture. On screens with a pixel ratio below 2, the site also turns on multisample anti-aliasing.

The circular reveal of the opening belongs to the same material system. All materials share one radius uniform and discard any pixel whose horizontal distance from the start point exceeds it. A very narrow band at the edge is painted pink-violet at 5.5 times normal brightness, so the bloom turns it into a ring of light. The black grid floor does the opposite and draws only outside the radius, so during the opening the grid and the island meet along that edge.

The site detects the device from the browser's UA string and switches every phone and tablet to low quality. On low quality the bloom uses two blur levels where desktop uses five, and both the depth of field and the speed-based camera pull-back are off. The shadow map drops from 2048 to 512, and physics moves to a fixed step of one sixtieth of a second. On phones the canvas also caps the pixel ratio at 2, so a phone with a pixel ratio of 3 draws only four ninths of its pixels. The options page has a High and Low switch so visitors can change it themselves. However, every device downloads exactly the same assets, so phones get the same models and textures as desktops and simply draw less with them.

These assets add up to about 7.56 MB. The largest single file is the Rapier physics engine at about 1.66 MB, compiled to WebAssembly, followed by the main script at about 1 MB, then the area models at about 625 KB and the Basis transcoder at about 515 KB. The 42 mp3 sound files total about 1.93 MB, the largest category of asset. The server starts returning the page in about 0.12 seconds, the loading arc first appears between 3.0 and 3.3 seconds, and the round patch of ground and CLICK TO START are fully in place only at about 8.5 to 9 seconds. During loading the page freezes for at most about 0.85 seconds, and nothing on screen jumps.

Sound plays through Howler and starts only after the visitor clicks to start. The background music is three tracks the musician Kounine wrote for this site, now released under a CC0 license. Most sounds on the island are positional, so the explosion of a crate, for example, gets quieter the further it is from the jeep and goes silent past a certain distance. Each sound plays at a slightly random pitch every time, between 0.9 and 1.2 times the original speed for the explosions, so several crashes in a row never sound identical.

Bruno's Portfolio can be played entirely with the keyboard and also supports gamepads and touch, but screen reader users can hardly use it at all. The site intercepts the Tab key and keeps focus on the menu button at the top right, and neither the menu nor the map button has a name, so a screen reader only knows there is a button. All of the island's content is drawn in the canvas, so a screen reader cannot read a single project.

05Scores and Team

Award Source Date Score
FWA of the Day The FWA 2025-12-13 93 POINTS, DAYS 2
FWA of the Month The FWA December 2025 Monthly award, no separate score
FWA of the Year The FWA 2025 Yearly award, no separate score
People's Choice Award The FWA 2025 Visitor-voted award of the year
Site of the Day Awwwards 2026-01-21 8.11. Design 8.05 / Usability 7.83 / Creativity 8.62 / Content 8.18
Developer Award Awwwards 2026-01-21 7.65
Site of the Month Awwwards January 2026 Monthly award, no separate score

The FWA named Bruno's Portfolio its FWA of the Year for 2025, and the visitor-voted People's Choice Award for the same year also went to it. Its FWA of the Day scored 93 points and was filed under fun and games, games, and personal and portfolio. On Awwwards, Bruno's Portfolio won Site of the Day, the Developer Award and Site of the Month for January 2026.

Of its four Awwwards scores, Creativity was highest at 8.62, most likely because the portfolio became an island where visitors can drive, race and leave messages. Usability scored lowest at 7.83, probably because visitors must learn to drive and find their way before they reach any project. The five developer jurors gave 7.65, with Animations highest at 8.60. Accessibility was lowest at 6.60, which matches the intercepted Tab key and the unnamed buttons described in the Engineering section.

Credit Role Record
Bruno Simon Creative developer in Paris, France, freelance, formerly lead developer at Immersive Garden Awwwards works 10, SOTY 1, SOTM 2, SOTD 7, HM 10. FWA 16

The modelling, level design and code of this site all come from Bruno Simon alone, with the background music written by Kounine. Bruno Simon writes in the case study that this version took a little over a year and launched at the end of 2025. Its predecessor is the 2019 portfolio, which also let visitors drive around and now hides inside the time machine on the island. As of this report, Bruno Simon has won 16 awards on the FWA, and four of them, the day, month and year awards and the People's Choice Award, come from this site.

06Archive

Award date
2026-01-21
Awards
Awwwards SOTD 2026-01-21, Awwwards DEV 2026-01-21, Awwwards SOTM 2026-01, The FWA FOTD 2025-12-13, The FWA FOTM 2025-12, The FWA FOTY 2025
Site
https://bruno-simon.com/
Credits
Bruno Simon
Design
spatial
Build
realtime
Awwwards
8.11 / 10. Design 8.05 / Usability 7.83 / Creativity 8.62 / Content 8.18. Developer Award 7.65. https://www.awwwards.com/sites/brunos-portfolio
The FWA
93 POINTS, DAYS 2. https://thefwa.com/cases/brunos-portfolio
Stack
three.js r183 WebGPURenderer, TSL, Rapier, GSAP, Howler.js, Draco, KTX (Basis), WebSocket
Total assets
About 7.56 MB, of which sound is about 1.93 MB and the Rapier physics engine about 1.66 MB
Speed
FCP 2996 to 3344 ms, opening screen complete at about 8.5 to 9 seconds, CLS 0. 60 fps, including driving with boost