Integrate WebAssembly WASM in React and Vue
This article provides a straightforward guide on how to integrate a WebAssembly (WASM) module into modern React and Vue applications. You will learn how to configure your build tools, import your compiled WASM code, and execute high-performance functions within both frontend frameworks.
1. Configure the Bundler (Vite)
Modern React and Vue templates rely primarily on Vite. Because Vite does not support WebAssembly out of the box in the same way Webpack does, you need to configure plugins to handle WASM files and enable top-level await support.
First, install the necessary plugins in your project:
npm install vite-plugin-wasm vite-plugin-top-level-await --save-devNext, update your vite.config.js or
vite.config.ts file to include these plugins:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react'; // Or @vitejs/plugin-vue for Vue
import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
export default defineConfig({
plugins: [
react(), // Use vue() if you are in a Vue project
wasm(),
topLevelAwait()
]
});2. Prepare the WebAssembly Module
Assume you have a compiled WASM module (e.g., compiled from Rust
using wasm-pack with the target set to bundler
or web). The output folder contains a .js
wrapper and a .wasm file.
For this guide, assume the package exports an add
function:
export function add(a: number, b: number): number;Place this generated package inside your project (e.g., in
src/wasm) or install it via npm.
3. Integrate in a React Application
With Vite configured, you can import and call your WebAssembly functions directly within your React components.
Here is how to implement it using a functional component and React state:
import { useState } from 'react';
import { add } from './wasm/my_wasm_module';
function App() {
const [result, setResult] = useState(null);
const handleCalculation = () => {
const sum = add(15, 27);
setResult(sum);
};
return (
<div style={{ padding: '20px' }}>
<h1>React + WebAssembly</h1>
<button onClick={handleCalculation}>Calculate 15 + 27</button>
{result !== null && <p>Result from WASM: {result}</p>}
</div>
);
}
export default App;4. Integrate in a Vue Application
For Vue 3, you can import and use the WASM module inside the
<script setup> block. The top-level await plugin
allows you to treat the WASM import as a standard synchronous
import.
Here is the Vue Single File Component (SFC) implementation:
<script setup>
import { ref } from 'vue';
import { add } from './wasm/my_wasm_module';
const result = ref(null);
function handleCalculation() {
result.value = add(15, 27);
}
</script>
<template>
<div style="padding: 20px;">
<h1>Vue + WebAssembly</h1>
<button @click="handleCalculation">Calculate 15 + 27</button>
<p v-if="result !== null">Result from WASM: {{ result }}</p>
</div>
</template>Alternative: Dynamic Loading (Without Plugins)
If you prefer not to use Vite plugins, you can load the
.wasm file dynamically using the native browser
WebAssembly.instantiateStreaming API.
import { useState, useEffect } from 'react';
function App() {
const [wasmInstance, setWasmInstance] = useState(null);
useEffect(() => {
WebAssembly.instantiateStreaming(fetch('/my_wasm_module.wasm'))
.then((obj) => {
setWasmInstance(obj.instance.exports);
})
.catch((err) => console.error('Failed to load WASM', err));
}, []);
const calculate = () => {
if (wasmInstance) {
alert(wasmInstance.add(15, 27));
}
};
return (
<button onClick={calculate} disabled={!wasmInstance}>
Run Native WASM Add
</button>
);
}