I’ve seen many gaming websites where games run directly in the browser, and the experience can be surprisingly smooth. Since the web has a huge audience, I realized that many users would prefer to play a game instantly without downloading or installing anything.
That got me thinking: why not bring my Unity games to the web using Unity WebGL?
I already knew how to build games in Unity, but when I wanted to integrate a Unity WebGL application into a modern React application, I ran into a different challenge:
How do two completely different environments—Unity/C# and React/TypeScript—communicate with each other?
At first, I thought this would be a simple task.
It wasn't.
After trying different approaches, testing the communication, and fixing a few issues along the way, I finally got a working setup.
In this article, I’ll share the approach I used to connect Unity WebGL + React + TypeScript, including how I send data in both directions.
What We Are Building
Before writing any code, let's understand what we want to achieve.
My basic setup looks like this:
React + TypeScript
↓
react-unity-webgl
↓
Unity WebGL
↓
Unity C# Scripts
The goal is simple.
I want React to be able to tell Unity something like:
"Start Level 5"
And I also want Unity to send information back to React:
"Level Completed"
So we need two-way communication:
React → Unity
React ← Unity
Once I understood this, the implementation became much easier.
Step 1: Create the Unity Project
I started with a normal Unity project.
For this example, let's assume I have a simple game with a GameManager object.
The important part is that the GameObject we want React to communicate with must have a C# script attached to it.
For example:
using UnityEngine;
public class GameManager : MonoBehaviour
{
public void SetPlayerName(string playerName)
{
Debug.Log("Player Name: " + playerName);
}
}
Here I created a public method called SetPlayerName.
This method will later be called from React.
The important thing to remember is:
React doesn't directly call a C# method.
React communicates with the Unity WebGL instance, and Unity then calls the method on the specified GameObject.
Step 2: Build Unity for WebGL
Next, I changed the Unity build platform to WebGL.
In Unity:
File
→ Build Settings
→ WebGL
→ Switch Platform
Then I created a WebGL build.
The output contains files required to run the Unity game in a browser.
For example:
WebGL_Build/
├── Build/
├── TemplateData/
└── index.html
I don't recommend manually modifying the generated Unity files unless you know exactly what you're changing.
Let Unity generate the build and let React handle displaying it.
Step 3: Create the React Application
For the frontend, I used React with TypeScript.
I created a Vite application:
npm create vite@latest react-unity-demo
Then selected:
React
TypeScript
After creating the project, I installed the package that handles Unity WebGL integration:
npm install react-unity-webgl
This package makes it much easier to load and communicate with a Unity WebGL application from React.
Step 4: Load Unity Inside React
Now we need to connect our Unity WebGL build with React.
I created a Unity component.
A simplified version looks like this:
import { Unity, useUnityContext } from "react-unity-webgl";
function App() {
const { unityProvider } = useUnityContext({
loaderUrl: "/WebGL_Build/Build/WebGL_Build.loader.js",
dataUrl: "/WebGL_Build/Build/WebGL_Build.data",
frameworkUrl: "/WebGL_Build/Build/WebGL_Build.framework.js",
codeUrl: "/WebGL_Build/Build/WebGL_Build.wasm",
});
return (
<Unity
unityProvider={unityProvider}
style={{
width: "100%",
height: "600px",
}}
/>
);
}
export default App;
The exact file names will depend on your Unity build.
This was one of the first places where I faced problems.
If the paths are incorrect, React may load successfully but Unity won't.
You might see errors such as:
404 Not Found
So always check the browser's developer console and Network tab when the Unity build doesn't load.
Step 5: The Interesting Part — React to Unity
Now let's make React communicate with Unity.
This is where things started getting interesting for me.
The react-unity-webgl package provides a way to send messages to Unity.
For example:
const { unityProvider, sendMessage } = useUnityContext({
loaderUrl: "...",
dataUrl: "...",
frameworkUrl: "...",
codeUrl: "...",
});
Then we can create a button:
<button
onClick={() =>
sendMessage(
"GameManager",
"SetPlayerName",
"Alok"
)
}
>
Send Name to Unity
</button>
Let's understand what is happening here.
"GameManager"
is the name of the GameObject in Unity.
"SetPlayerName"
is the C# method.
"Alok"
is the value we're sending.
So React is effectively saying:
Unity, find the GameObject called
GameManagerand callSetPlayerName()with this value.
Unity receives it through the WebGL communication layer and executes:
public void SetPlayerName(string playerName)
{
Debug.Log("Player Name: " + playerName);
}
And that's our first successful communication:
TypeScript
↓
Unity WebGL
↓
C#
Step 6: Sending Numbers and Other Data
Strings are easy.
But real applications usually need more than strings.
For example:
Player ID
Level Number
Score
Game Settings
User Information
Mission Data
For simple values, you can pass numbers or strings.
For more complex data, I prefer using JSON.
For example, React can send:
{
"playerName": "Alok",
"level": 5,
"score": 1200
}
On the Unity side, I can create a C# class:
[System.Serializable]
public class PlayerData
{
public string playerName;
public int level;
public int score;
}
Then deserialize the JSON inside Unity.
This approach becomes especially useful when the React application is acting as the main web interface and Unity is responsible mainly for the 3D/game experience.
Step 7: Unity to React
Now comes the other direction.
We have already done:
React → Unity
But in a real application, Unity also needs to send information back.
For example:
Level Started
Level Completed
Player Died
Score Changed
Mission Completed
Game Loaded
This is where a JavaScript bridge becomes useful.
The basic idea is:
Unity C#
↓
JavaScript
↓
React
Unity can call a JavaScript function exposed by the WebGL page.
For example, conceptually:
public void LevelCompleted()
{
// Notify the web application
}
The JavaScript side can then forward that event to React.
In React, I can listen for the event and update the UI.
For example:
Unity
↓
"LevelCompleted"
↓
React
↓
Show "Congratulations!"
This separation is useful because Unity doesn't need to know how the React UI works.
Unity only needs to say:
"The level has been completed."
React decides what to do with that information.
Step 8: A Real Example
This is where I found the architecture much more useful.
Imagine we're building an online game portal.
The React application contains:
Header
Login
Profile
Game List
Leaderboard
Game Screen
Unity handles:
3D Game
Player
Gameplay
Physics
Animations
Game Logic
Now imagine the user selects a game from React.
React tells Unity:
Load Level 10
Unity loads the level.
After the player finishes it, Unity sends:
Level Completed
Score: 2500
React receives the event and can:
Update the result screen
Save the score
Show leaderboard
Move to the next level
Now the architecture becomes much clearer:
React
┌──────────────┐
│ UI │
│ Login │
│ Profile │
│ Leaderboard │
└──────┬───────┘
│
Communication
│
┌──────▼───────┐
│ Unity WebGL │
│ │
│ Gameplay │
│ 3D │
│ Physics │
└──────────────┘
If we add a backend later:
React
↓
.NET Web API
↓
Database
React
↕
Unity WebGL
This is the architecture I am currently more interested in because it allows Unity to become part of a larger web application instead of being the entire website.
Step 9: Problems I Faced
The communication itself wasn't the only challenge.
I also faced a few common issues while putting everything together.
1. Unity WebGL files returning 404
Usually this was related to incorrect build paths.
I checked:
loaderUrl
dataUrl
frameworkUrl
codeUrl
and made sure the generated files were actually available to React.
2. Unity loading but communication not working
In this case, I checked three things:
GameObject name
↓
C# method name
↓
Parameter type
Even a small mismatch can cause problems.
3. React errors
I also ran into React-side issues such as incorrect hook usage and import/path problems.
My biggest lesson was simple:
Don't debug Unity and React at the same time.
First confirm that Unity WebGL works by itself.
Then confirm React can load Unity.
Finally, test communication.
Breaking the problem into these smaller steps saved me a lot of time.
What I Learned
The biggest lesson from this project was that Unity WebGL doesn't have to live alone.
Unity is very good at:
- 3D
- gameplay
- physics
- animations
- game systems
React is very good at:
- web UI
- authentication
- dashboards
- navigation
- forms
- application state
Instead of trying to make one technology do everything, we can let each technology do what it is good at.
The communication layer becomes the bridge between them.
React / TypeScript
↕
Communication Layer
↕
Unity WebGL / C#
And once this basic communication is working, there are many possibilities—online games, training applications, digital twins, interactive 3D websites, simulations, and much more.
Final Thoughts
When I started this project, my main question was:
How can React and Unity communicate with each other?
After working through it, I realized that the difficult part isn't actually sending a message.
The more important part is designing the boundary between the two applications.
React doesn't need to know how Unity moves a character.
Unity doesn't need to know how React renders a dashboard.
They just need a clean way to exchange the information they actually need.
That was the approach that finally made the whole setup click for me.
If you're also working with Unity WebGL + React, I'd genuinely like to know how you're handling communication.
Are you using [react-unity-webgl](https://www.npmjs.com/package/react-unity-webgl), your own JavaScript bridge, or a different approach?
If you found a better way, share it in the comments—I’d love to learn from it. And if you ran into an issue while implementing this, leave a comment below. I’ll be happy to discuss it.
Thanks for reading! 🚀
Suggested by Writer:
Top comments (0)