Behold, the buzzwords:
The main goal here: To use Rust + WASM in a react app, inside a monorepo.
TLDR: visit the final product! https://github.com/cmdcolin/rust_react_monorepo_template. It is also deployed live here https://cmdcolin.github.io/rust_react_monorepo_template
2025 update: While this article covers create-react-app, the Vite version is simpler and easier. I made a simple Vite app in https://github.com/cmdcolin/logistic_chaos_map
mkdir template
cd template
git init
package.jsonThen put this in the monorepo's root package.json
{
"private": true,
"workspaces": ["hello-wasm", "app"]
}
This sets our repo up as a "monorepo" with two "workspaces". one will be the
wasm code, in hello-wasm, one will be an instance of create-react-app
create-react-app instance inside the monoreponpx create-react-app --template typescript app
This will make an app subfolder inside our monorepo
wasm-bindgen example and put it in a folder named hello-wasmDownload https://github.com/rustwasm/wasm-bindgen/tree/main/examples/hello_world to the hello-wasm folder
This link can help https://download-directory.github.io/?url=https%3A%2F%2Fgithub.com%2Frustwasm%2Fwasm-bindgen%2Ftree%2Fmain%2Fexamples%2Fhello_world
package.json in the hello-wasm folder{
"name": "hello-wasm",
"version": "1.0.0",
"files": ["pkg"],
"main": "pkg/index.js"
... rest
}
hello-wasm example to return a value instead of making an alertI changed the rust code to return a String value instead of making an alert box
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello {}", name)
}
hello-wasm pkgGo into the hello-wasm folder and run yarn build. This creates a directory
named pkg which has .wasm files and .js files. Now, the hello-wasm
folder is effectively a node package. We could publish this to NPM (see
footnote 1)
hello-wasm package to the app dependenciesAdd "hello-wasm":"^1.0.0" to the dependencies array in app/package.json.
This will refer to our local monorepo's rust wasm package!
create-react-appAs of writing, with webpack v5/create-react-app v5, you have to customize
the create-react-app to add extra webpack flags.
So, yarn add @craco/craco in the app folder, then create this
craco.config.js
module.exports = {
webpack: {
configure: config => {
const wasmExtensionRegExp = /\.wasm$/
config.resolve.extensions.push('.wasm')
config.experiments = {
syncWebAssembly: true,
}
config.module.rules.forEach(rule => {
;(rule.oneOf || []).forEach(oneOf => {
if (oneOf.type === 'asset/resource') {
oneOf.exclude.push(wasmExtensionRegExp)
}
})
})
return config
},
},
}
Note: this thread helped me to create the craco config https://github.com/Emurgo/cardano-serialization-lib/issues/295
Also see footnote 2 for more info
import() to import the hello-wasm greetingWe use a useEffect hook to import the code asynchronously, and can call our
rust function, greet, from javascript!
function App() {
const [greeting, setGreeting] = useState<string>()
useEffect(() => {
;(async () => {
try {
const wasm = await import('hello-wasm')
const greeting = wasm.greet('Colin')
setGreeting(greeting)
} catch (e) {
console.error(e)
}
})()
}, [])
return (
<div>
<h1>rust monorepo wasm demo</h1>
<h2>Greeting from wasm: {!greeting ? 'Loading...' : greeting}</h2>
</div>
)
}
In order to greet an arbitrary person, I modified this slightly in the live demo. See https://github.com/cmdcolin/rust_react_monorepo_template/blob/master/app/src/App.tsx
Go into the app folder, and then run yarn start
A screenshot of the app, showing the string "Hello Colin" which is generated via rust and wasm

My main aim was to demonstrate creating a "simple" monorepo setup showing how you can integrate Rust+WASM and React. Feel free to ask me any questions and go check out the repo!
https://github.com/cmdcolin/rust_react_monorepo_template
This article is quite helpful also, but uses a file:/ reference in their
package.json while my approach uses a monorepo, it is fundamentally quite
similar though!
https://tkat0.github.io/posts/how-to-create-a-react-app-with-rust-and-wasm
hello-wasm folder IS a npm package with wasm filesThe hello-wasm folder can be published to NPM by itself. When consumers of the
package import the module, they would receive pkg/index.js from the main
field in package.json, and then pkg/index.js in turn imports the
index.wasm file. Then it is up to the consumers bundler to package that
correctly.
As of writing, I am using webpack v5 (part of create-react-app v5), which
has "native support" for wasm. Still, it is hidden behind a flag called
"experiments" (see first google result for webpack wasm here
https://webpack.js.org/configuration/experiments/) so I use @craco/craco to
modify the webpack config of create-react-app v5 to add this.
Note also: The first time I wrote this, I used webpack v4, which used a
slightly different workflow (used a special webpack loader called
wasm-loader)
You can also likely use similar techniques described in this article to
incorporate into next.js since it also uses webpack. If you have info on how
other bundlers use wasm, feel free to leave a comment.
Fundamentally, the .wasm file has to be fetched asynchronously before it can
be run (it is not in my experience e.g. embedded as binary data inside a js
file) which means it would be difficult to use the wasm code as a synchronous
import.
There are hints that this may be possible but it would rely on the bundler embedding the wasm code in the js itself, or maybe top-level-await. If anyone has more info, feel free to leave a comment!
The hello-wasm package does not automatically recompile when we are running
e.g. yarn start in the app folder. Therefore, changes to the rust requires
you to manually run yarn build in the hello-wasm folder. Just something to
be aware of
I first created an example of rust+wasm+react almost two years ago when creating a fractal viewer https://github.com/cmdcolin/logistic_chaos_map and it has some development notes on the stumbling blocks I faced https://github.com/cmdcolin/logistic_chaos_map/blob/master/NOTES.md
Yep! The hello-wasm example generates typescript .d.ts files! Check out the
hello-wasm/pkg/ folder after you build it! This was none of my doing, just a
built-in feature. PS: I highly recommend inspecting the pkg folder that is
produced in the hello-wasm build to help understand the details. I also
recommend reading the https://rustwasm.github.io/wasm-bindgen/ docs and if you
are getting started with rust, read the Rust Book along with doing rustlings
https://github.com/rust-lang/rustlings
This article was posted on reddit and is also a great resource especially about sync vs async webpack loading schemes for wasm
https://canvasapp.com/blog/building-modern-web-apps-with-rust-wasm-and-webpack/
2025 update: While this article covers create-react-app, the Vite version is simpler and easier. I made a simple Vite app in https://github.com/cmdcolin/logistic_chaos_map