How to Make a Game With React

This ad is not shown to multipass and full ticket holders
JSNation US
JSNation US 2025
November 17 - 20, 2025
New York, US & Online
See JS stars in the US biggest planetarium
Learn More
In partnership with Focus Reactive
Upcoming event
JSNation US 2025
JSNation US 2025
November 17 - 20, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

We make websites with React. We make apps with React. But how do we make games with React? In this presentation I will build up show you how to build up a React game engine tecstack using Poimandres libraries, explain the core concepts and, yes, even build a game.

This talk has been presented at React Summit US 2024, check out the latest edition of this React Conference.

FAQ

The purpose of using React for game development is to leverage the tools and knowledge that web developers already have, making it easier to bring game development to a wider audience without having to learn new programming languages like C# or C++. React allows for quick iteration of ideas, which is a significant advantage in game development.

The key components used are React 3 Fiber, which allows for declarative building of 3D scenes in React, and Cota, a state management library efficient for updating high volumes of data quickly. The development also employs tools like Triplex for a visual IDE experience.

React 3 Fiber allows developers to build 3D scenes declaratively in React, similar to how DOM elements are managed. It integrates fully with HTML and the React ecosystem, enabling the use of familiar tools and libraries in a 3D environment. It is powered by 3JS, providing robust 3D capabilities.

Cota is a state management solution designed to efficiently update high volumes of data quickly. It acts as a local database that integrates with React to manage the dynamic and high-frequency updates required in game development, supporting thousands of objects and a dynamic structure.

Entities in the game are managed using traits and behaviors. Traits hold data and define entity characteristics, while behaviors are small, composable functions that dictate entity actions, updated every frame using a central frame loop. This setup allows for dynamic and interactive game environments.

Triplex provides a visual IDE that helps developers move and arrange elements within the 3D environment visually. It aids in saving configurations back to the code, enhancing the development workflow by providing a more intuitive interface for managing 3D objects.

Yes, the approach can be adapted for React Native since the state library Cota is agnostic and can be used with vanilla JavaScript or React Native. However, it may not be as fast on React Native due to limitations like the absence of JIT (Just-In-Time) compilation on Apple devices.

Composable behaviors allow for modular and manageable game logic, where each behavior represents a small, independent function that can be combined to create complex interactions. This modularity facilitates easier debugging and iteration, making it easier to refine and expand game functionality.

Kristopher  Baumgartner
Kristopher Baumgartner
22 min
19 Nov, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
I'm here with the Poimandris Open Source Dev Collective, and I'm going to show you how to make a game with React using patterns you know and probably a lot you don't. We'll use React, React 3 Fiber, Kota, and Triplex. Cota is a nimble state solution that creates a local database for efficient updates. Spawn entities with specific traits and update them accordingly. Learn about composable behavior in Kota and how to update entities every frame. Enhance the visual appearance of the game by adding a HiFi view, materials, lights, and post-processing for bloom. Understand the concepts of creating games in React, dynamically spawning entities, and giving them behavior. Learn about testing strategy, compatibility with React Native, and the advantages of using React for game development, including wider accessibility and quicker iteration.
Available in Español: How to Make a Game With React

1. Introduction to React Game Development

Short description:

I'm here with the Poimandris Open Source Dev Collective, and I'm going to show you how to make a game with React using patterns you know and probably a lot you don't. We're going to do this by talking about rendering, state management, spawning, and behavior. We'll use React, React 3 Fiber, Kota, and Triplex. React 3 Fiber lets you declaratively build 3D scenes in React, fully interactive with HTML and powered by 3JS. It looks like a regular React component with a mesh, geometry, and material. We update quickly with the useFrame hook.

Hello, hello, my name is Chris Baumgartner. I'm here with the Poimandris Open Source Dev Collective, and I'm going to show you how to make a game with React using patterns you know and probably a lot you don't.

In fact, it'll be this game right here. We're going to do this by talking about rendering, how we draw things in 3D with React. Then we're going to talk about state management, what's our strategy for updating data very quickly in React. We're going to talk about spawning, what's our patterns for dynamically creating and destroying entities, and we're going to talk about behavior, how we make our entities do things. Then we're going to give the whole thing a nice glow-up. To do that, we're going to use, of course, React. We're also going to use React 3 Fiber and Kota. Both of these are libraries created by Poimandris and worked on by myself. We're going to use this tool called Triplex. It's going to give us a visual IDE for moving stuff around and saving it back to code.

Let's start with rendering. React 3 Fiber probably does not need an introduction for a lot of people, but in case you're not familiar, it lets you declaratively build 3D scenes in React, just like you do with DOM. You get to do that with 3D. It's fully interactive with HTML. It participates in React's ecosystem, which means all the same tools and libraries you use, you can use in 3D. It's powered by 3JS, so if you're wondering how the magic happens, you can look up 3.

This is what it looks like. It looks a lot like a regular React component, except we have here a mesh. Inside the mesh is a geometry and a material. The geometry tells us the shape our mesh is going to have. The material tells us what it's going to look like. Here it's going to change color from red to blue when we click on it. Then in our app, we have a canvas. That canvas here is the 3D environment that we're going to draw into. This is what it looks like. Just a little bit of code, we get a 3D interactive piece. One additional difference with React components is that we often have a need to update in a frame loop very quickly. We have a hook called useFrame.

2. State Management and Entity Creation

Short description:

It is a callback that's going to happen in a request animation frame in our central frame loop. We had three entities: player, enemies, and bullets. Our player moves with the keyboard, shoots bullets, and enemies flock towards the player. Bullets collide with enemies. We start with wireframes for functionality. State management is crucial for games as current solutions are too slow for high-frequency updates and many objects.

It is a callback that's going to happen in a request animation frame in our central frame loop. Here we're just getting the ref for the mesh and we're rotating it each tick of the frame.

Our game, we had three entities that we're trying to create. We had a player, we had enemies, and then we had bullets. We wanted our player to move around with the keys, with our keyboard. We wanted to shoot bullets. We wanted our enemies to flock towards the player, and then we want them to disappear when shot. We want our bullets to move forward fast from wherever they're spawned, and we want them to collide with enemies so we know when to destroy them. We're going to start with wireframes just to make sure we're not worried about the visuals. We're going to worry at first with just how it works.

Here's a quick little video of me doing that. Here I am just taking a player view. It's a box geometry with a wireframe mesh, and I'm creating a view for the enemy and for the bullets, a dodecahedron for the enemy. Then our bullets are just going to be a sphere for now. We're making the bullets scale down. There's a prop there just like in CSS with a transform. We're going to add that to our scene. On the right is triplex, which is a nice little visual IDE. I'm just going to go in there real quick and move them so we can see them. They're not overlapped on top of each other. There's our first scene.

But now how do we make it do something? Now we talk about probably the most important part of this talk, state management. Current state solutions are too slow for what we want to do. They assume a low frequency of updates. They assume relatively few objects and usually also a rigid structure. Just think of your typical React app where you have a hierarchy. It's like a document. You're updating on user interaction or data fetching or an API call. You typically don't have thousands and thousands of objects. By contrast, games are much more demanding.

3. The Cota State Solution

Short description:

Games update multiple times a second with many dynamic objects. Cota is a nimble state solution that creates a local database for efficient updates. Entities in the state have different traits, like pink, green, and purple. Traits hold data, such as thrust and velocity.

They update multiple times a second, every frame. There's usually many objects, thousands sometimes, and there's a dynamic structure. We don't know ahead of time exactly how things should be ordered. Otherwise, it probably wouldn't be a very fun game.

So we need a state solution that's more nimble than what we're used to seeing. That's what I've been working on. This is something we're releasing at Poimandris alongside Zustand, Jotai, Valtio. It's called Cota. Cota, in essence, it creates a local database that is very efficient at updating high volumes of data very quickly. We query that data with React, and we use that data to draw a view. Then we use actions in React to mutate Cota. This is just like your pattern you're used to when you pull some data from the web to create some posts. You map over it, and then if you want to create a post, back to it, you post an action.

The concepts here are a little different, though. We have something that's more like a world of entities. I have a little circle there. That's our world. In it, we have entities, and each entity is going to have different traits. They're going to do different things, have different behavior. Here we have, we can imagine each of those entities has a pink, a green, and a purple trait.

A common thing we want to do is find all green entities. Traits hold data. They're like atoms of data. What it looks like is this. We define a trait. Here we have a movement trait. We have thrust. Thrust is acceleration for us. It has a velocity. Velocity describes in what direction and how fast something is going.

4. Entity Spawning and Updating

Short description:

Spawn entities with specific traits and update them accordingly. Use actions to mutate the state from React. Create entities and handle their destruction using the renderer pattern in React. Query entities, map them to view components, and link the view data back to Kota for updates. Use the useQuery hook to query for specific entities and sync their transforms with Kota in a layout effect inside the view.

Then we're going to spawn an entity with a movement trait. This is a movable entity. We now know this entity is something that should move. If we wanted a flying entity, we might spawn an entity with a flight trait. Then we've got to update all of those entities by trait. We're going to query the world. We're going to say, give me all entities that have the movement trait. Then we're going to loop over them with updateEach. Here we're just adding to the velocity with the thrust. Then we use an action to mutate from React.

We're creating an action here. It's a spawn entity action. Then we're using it inside of React. On click, we're spawning an entity with that div. Imagine this is a button. It's very fast. This is an in-body sim. With 3,000 bodies running at over 60 frames a second, that means it's doing 9 million iterations every frame. Let's talk about spawning. How are we going to create our entities and destroy them? We're going to start with our renderer pattern. This is how we're going to query entities and draw them in React. Step one is we want to query the entities we want to render. We're going to grab that data. Step two is we're going to map over it, just like a list, and map it to a view component. Step three is we're going to link that view data back to Kota so that we know how to update things in our loops.

This is what that looks like. We start with a use query hook. Here we're querying for enemies that have a transform. We're mapping over it to our enemy view we created before. Then in a layout effect inside our view, we are syncing the transform on the mesh with Kota.

5. Entity Spawning and Behavior

Short description:

Learn how to spawn entities with specific traits and handle their positioning. Create actions for spawning players and enemies. Ensure entities are placed randomly around the game level. Understand the importance of updating everything every frame.

If you've never used 3 before, don't worry. This is like in CSS when you have a transform, you have position, rotation, scale. We're just making sure that that data is linked with our traits. But that alone does not get us anything in our game.

We have to start spawning stuff. Now we need to write some game logic. We're going to create our first action. Our first actions here are going to be one for spawning players. We're going to spawn entities that have the player trait and transform. And then spawning enemies spawn entities that have the enemy trait and transform.

When we use it in React here on startup, on mount, we're just calling it in effect spawn player. Then we're setting an interval for spawning an enemy every second. We're adding startup to our app. And we get this. Now we have our player and we have our enemies, but they're all spawning bunched up on top of each other, so we want to do something about that.

We're going to go back to our enemy action. We're going to make sure that when we spawn our enemy, we are creating a random position and rotation. That way every time that action is called, we know that they're getting placed randomly around the map. And it's getting passed into the trait as a default prop.

All right. Now we get what we want. Every time that action is called in the interval, we are getting them placed randomly around our game level. Now let's talk about behavior. We've got them spawning, but we want them doing things. We want to make the game. Very important here is that we get the break, one of the most fundamental rules of React.

If you do a set state every frame, people would say your React app is broken, and it truly would be. With Kota, though, in order to get things to come alive so that every time you look at the screen, every frame, it's moving, it's doing something new, we need to make sure that we're updating everything every frame.

6. Composable Behavior and Entity Movement

Short description:

Learn about composable behavior in Kota and how to update entities every frame. Add input and movement traits to the player and convert input into velocity for movement. Create a frame loop component to update the game state continuously. Update the position of movable entities based on their velocity. Understand the concept of converting input into movement.

If you do a set state every frame, people would say your React app is broken, and it truly would be. With Kota, though, in order to get things to come alive so that every time you look at the screen, every frame, it's moving, it's doing something new, we need to make sure that we're updating everything every frame. That's why the fast volume of data transformation is important. That allows us to do something called composable behavior. That's where we split up all the game logic into little individual behaviors, a lot like we do with components. And then in a frame loop, we get to compose them. Here you can imagine you have a move right behavior, and then also move up behavior, and the composed behavior of calling them all in a frame loop is going to be move diagonal.

Let's recall that our player, we want them to move the keys, we want them to shoot. Here's the strategy we're going to do. We're going to add an input and movement trait to our player that's going to let our game know this is a movable entity that's receiving keyboard input. And then we're going to pull the input, the keyboard input in our frame loop. Then we're going to make a behavior for converting input into velocity, into a direction it's going to move. And then we're going to make behavior for moving the entities based on that velocity. Here we go. First step's pretty easy. We add the traits to our action. Second, we're going to be creating our frame loop component with our use frame hook, so that callback's going to be called every frame. And in it we're updating time, so we're keeping a clock, and then we're pulling the input of the keyboard. We add that to our app.

All right. Now the first update function, our behavior move entities, we grab a slice of time. How much time passed since the last time we called this function? That's our delta time. We're going to get query for all entities that are movable. And then we're going to loop over them, and we're going to update the position based off of how much it moved in that slice of time. You take the velocity multiplied by the delta time. You get the fraction of movement it would go in that slice of time. We add it to the position, and then it moves. We create our convert input movement behavior. This is a bit more complicated, so I'm going to go through a little bit high-level. What we're really doing here is...

7. Input Conversion and Composable Behavior

Short description:

Learn how to convert input into direction and rotation vectors for movement. Understand the concept of composable behavior in Kota and its impact on entity movement. See how removing and adding behavior affects entity movement in the frame loop.

This is some math for saying, okay, we got an input vector from our keys. We want to convert that into a direction vector, so we're multiplying our thrust, how fast it's moving, and then we're adding it to the previous velocity so that things speed up. And then here, we're just taking that same input vector, and we're converting it into a rotation.

All right. And then we add all that to our frame loop, and so we update time, we pull input, we convert the input to movement, and then we move the entities. Here we go. You see that we have the velocity running up there. I'm going to go to our frame loop and remove move entities. The velocity keeps updating, but we're no longer moving because that behavior is not running any longer. If we add it back, and once again, thank you, HMR, beautiful invention, now we're moving. That's composable behavior.

8. Flocking, Shooting, and Visual Enhancements

Short description:

Learn how to flock towards the player by adding flock behavior and avoid each other behavior. Understand the impact of adding and removing behaviors in entity movement. Enhance the visual appearance of the game by adding a HiFi view, materials, lights, and post-processing for bloom.

Now we want to flock towards the player. I'm going to skip here because I only have so much time. This is pre-made. I add the flock behavior, and now everything's moving towards the player, but now they're bunching up, so I'm going to add an avoid each other behavior. As soon as that's enabled, poof, now they no longer bunch up. If we remove it again, they're going to start bunching up. This makes debugging very easy.

And I'm going to cheat a little bit here too. We got a bunch of bullet shooting behavior we want to add. I pre-made those, and I'm just going to show you here, we have handle shooting, which handles pressing the keyboard and shooting, update bullets, moves the bullets forward, collide bullets with enemies' handles, calculating the collision. If I remove that, like I did here, the bullets still shoot, but it no longer collides with the enemies. If I add it back, it'll start working again.

So now, left, we got to do our glow. We got our behavior. We spawned all of our entities. We gave them some behavior composably, but it still looks like wireframes, right? So we need to make it look like a game. This is something else that I would love to go into more detail in, but it's a whole talk in itself. But here, you're going to see I'm going to be adding a HiFi view. So we have our renderer that maps on views. I'm switching it over to a pre-made HiFi one that has materials that are lit. It has a model that was made in Blender. And then I'm adding some lights. So the directional lights are going to point from a direction. I'm going into triplex here, and I'm going to try to dial in the lights. I copy a new directional light. I make it white. I make the other one red. Now I'm going to add some post-processing so we get some bloom. That's going to make everything glow. Ah, very nice.

9. Enhancing Gameplay and Credits

Short description:

Learn how to add a Nebula background, score tracker, push behavior, explosions, and lighting tweaks to enhance gameplay. Understand the concepts of creating games in React, dynamically spawning entities, and giving them behavior. Get quick credits and access to relevant links. Stay connected through the Poimandris Collective Discord.

And now I'm going to add a Nebula background. This is made by my friend Maxime Heckel. And now I'm going to add a score tracker. But I added the LoFi one, so I add the HiFi one. And now I want to juice up the gameplay a little bit, so I'm adding some push. So when I run into things, they get pushed around.

And now I want to add explosions. So when we shoot things, I want them to blow up. But first, I'm tweaking the lighting because I couldn't see things with the Nebula. All right. And so now I'm going to go and add an explosion render so we can render the explosions. And I'm going to add the tick explosion behavior so that they decay like that.

And that, in a nutshell, is our game. We did it. Yeah. So I know a lot of that was probably pretty technical at a glance, but I hope that we could follow along with the concepts. Importantly, we want to think about making games in React. We want to think about creating a world or spawning entities dynamically and giving them behavior. Right? And it's a bit different from a rigid app. But we get to use all of the same tools. We get to use all the same knowledge that all UI built directly in React, exactly how you do it, shares the same state. And then just some quick credits. This is everyone who helped me out here. And here's all of the links for React 3 Fiber, for Kota, for Triplex. And then this presentation right here, you can actually find on that GitHub. And then this QR code is to our Discord, the Poimandris Collective Discord, where we are developing all this technology. And that's what I got for you today. All right, so we got three questions right here. What's your testing strategy with games made in Canvas? Well, what you saw there is a lot of my dev cycle where I have Triplex open inside my browser. As I make changes, HMR is in there.

10. Testing, Compatibility, and Advantages

Short description:

Learn about testing strategy, compatibility with React Native, and the advantages of using React for game development, including wider accessibility and quicker iteration. Connect with Chris in the Q&A room for further questions. Choose your next track or stay here.

I see if it works. Games are a lot about feel. And you know right away if something's not working. So a lot of it's me testing the feel. If something's not feeling right, then with the composable behavior, I can go in there and start commenting out each system or update function one at a time and be like, which one's going wrong? It's a big benefit of doing a setup like this.

Yeah, that makes sense. Okay. Does this work with React Native? So this all here is just plain JavaScript code that I showed here. Kota as a state library is completely agnostic. It's a vanilla library. It's like Zustand where there are React bindings that we're using here. And it's made with React in mind, but just like Zustand can be used in vanilla or with React Native, so can this. It won't be as fast though, because if you're familiar, Apple doesn't allow JIT on React Native. That's too bad.

Okay. Due to time constraint, I'm just going to quickly do one last one. Where are the main things React specifically is buying you? Why would you make the game with React? Yeah, I had this slide in there at first and I should have put it back. The very first reason is because we all program React. And I feel like I want to bring game development to a wider audience. A lot of us have a day job, right? We don't have time to learn C Sharp or C++ or Unity or Unreal. But we have all our tooling and we have all our knowledge that we have from doing what we're doing, and I want to show people that they know enough programming to make a game. And so I'm trying to bring game ideas and concepts into the React ecosystem where the developers are.

Yeah, so less onboarding time and something that we front-end developers are already familiar with. Yes. A lot of game development is about iteration. Something that I think web dev has done as a revolution for us is it's made iterating ideas very quick. Something that game developers and other platforms are very jealous of. Yeah. And so I think even though the game ideas might be a little smaller now than you would get with a regular game engine, a traditional game engine, you might have more fun making it. Yeah, for sure. Well, that's all the time we have on that note. If you have any questions, find Chris in the Q&A room. And now we have a little time for you to switch over track or stay here. Thank you so much. All right. Thank you. Thanks. ♪♪♪♪

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

The Whimsical Potential of JavaScript Frameworks
React Summit US 2023React Summit US 2023
28 min
The Whimsical Potential of JavaScript Frameworks
Top Content
Watch video: The Whimsical Potential of JavaScript Frameworks
The speaker discusses the whimsical and detailed work of Stripe, particularly their interactive and dynamic pages. They explain the use of React for building whimsical details and tracking mouse position. The speaker introduces React Spring for smooth animation and React3 Fiber for creating a 3D egg model. They also mention the use of Framer Motion and React server components for animating CSS properties.
Emotional & Functional UI Animations in React
React Day Berlin 2022React Day Berlin 2022
28 min
Emotional & Functional UI Animations in React
Today's Talk discussed the importance of UI animations in React, both functional and emotional. Examples were given using CSS and Framer Motion, with a focus on user feedback and accessibility. Design guidelines and animation usage were highlighted, as well as the consideration of negative emotions in animations. The Talk also touched on designing 404 error pages and concluded with gratitude to the audience and organizers.
JavaScript Haikus: My Adventures in Tiny Coding
JS GameDev Summit 2023JS GameDev Summit 2023
27 min
JavaScript Haikus: My Adventures in Tiny Coding
This Talk is about writing super tiny JavaScript programs, known as tiny code. It explores the concept of code golf and the use of a live editor for instant feedback. The Talk discusses various ways to share tiny code, including Twitter.net. It also covers creating graphics, games, and sound in a small space. The speaker highlights inspiring tweets and showcases examples of tiny code, including asemic writing. The future of tiny code includes new techniques, better browser support, and AI-assisted programming.
The Hitchiker's Guide to Event Driven Architectures
Node Congress 2025Node Congress 2025
30 min
The Hitchiker's Guide to Event Driven Architectures
Premium
Today's Talk introduced event-driven architectures with Node.js. The event loop in Node.js enables non-blocking interaction between components. The event emitter class is used to handle events synchronously. Redis and Apache Kafka are popular tools for event handling, with Kafka providing scalability and persistence. Kafka.js is a JavaScript library that supports transactions and compression. Server-sent events are used to send events to the client. A plugin and library are used to convert an event emitter to an async iterator. The client displays emojis and updates the vote count.
Hacking an e-Reader with React
React Advanced 2023React Advanced 2023
7 min
Hacking an e-Reader with React
Watch video: Hacking an e-Reader with React
React for eBooks? Learn how to hack an eReader to display a tea menu. Create images and write e-books using React. Use EPUB format to create chapters and include CSS. Use Pandoc and Dino to simplify the process and make quick updates.
Hacking an e-Reader to Show My Tea Menu With JSX
React Day Berlin 2023React Day Berlin 2023
7 min
Hacking an e-Reader to Show My Tea Menu With JSX
Watch video: Hacking an e-Reader to Show My Tea Menu With JSX
React can be used to create custom menus for e-readers, and the process involves creating an image and e-book with React and loading them onto the e-reader. Writing an EPUB e-book for e-readers involves converting an SVG file into a PNG image and writing the e-book in EPUB format using HTML, CSS, and images. EPUB generators like Pandoc and Dino simplify the process of generating EPUBs from markdown and running JavaScript on the desktop, respectively.