Overview
Package @swmansion/smelter-web-wasm allows you to run the entire Smelter rendering
engine directly in the browser.
When using this approach, your React code runs inside the client’s browser, and any updates to the React component tree are handled by the WASM module running in a separate Web Worker. Since the engine is compiled to WebAssembly, it handles all media processing and output generation locally, eliminating the need for a separate Smelter server.
Check out Smelter documentation.
Compatibility
| SDK version | Supported browsers | React version |
|---|---|---|
v0.2.0v0.2.1 | Google Chrome and other Chromium based browsers | Recommended: Should work with any react version that is compatible with
|
v0.3.0 | Google Chrome and other Chromium based browsers | Recommended: Should work with any react version that is compatible with
|
Configuration
In the Smelter repository you can find few example projects with Smelter configured.
We are working on examples of other configurations, but here are steps you need to follow to configure that yourself:
@swmansion/smelter-browser-renderincludessmelter.wasmthat needs to hosted on your site.- You need to call
setWasmBundleUrlwith URL tosmelter.wasmbefore starting any Smelter instances. - Smelter code will be started in a Web Worker. Your project bundler needs to be able to handle following
syntax in a library code.
new Worker(new URL('../esm/runWorker.mjs', import.meta.url), {type: 'module'});
Configuring Next.js project
With below configuration, somewhere in your code you need to call:
import { setWasmBundleUrl } from "@swmansion/smelter-web-wasm";
setWasmBundleUrl('/smelter.wasm'){9 collapsed lines
"name": "nextjs-demo", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@swmansion/smelter": "0.2.1", "@swmansion/smelter-web-wasm": "0.2.1", "next": "14.2.24", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": {7 collapsed lines
"@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "14.2.24", "postcss": "^8", "tailwindcss": "^3.4.1", "typescript": "^5", "copy-webpack-plugin": "12.0.2", }}import path from 'node:path';import { createRequire } from 'node:module';import CopyPlugin from 'copy-webpack-plugin';
const require = createRequire(import.meta.url);
const nextConfig = { webpack: (config, { isServer }) => { config.plugins.push( new CopyPlugin({ patterns: [ { from: path.join( path.dirname(require.resolve('@swmansion/smelter-browser-render')), 'smelter.wasm' ), to: path.join(import.meta.dirname, "public"), }, ], }) ); config.resolve.fallback = { ...config.resolve.fallback, "compositor_web_bg.wasm": false, };
if (isServer) { config.externals = config.externals || []; config.externals.push('@swmansion/smelter-web-wasm'); }
return config; },};
export default nextConfig;Configuring Vite projects
With below configuration, somewhere in your code you need to call:
import { setWasmBundleUrl } from "@swmansion/smelter-web-wasm";
setWasmBundleUrl('/assets/smelter.wasm'){10 collapsed lines
"name": "vite-demo", "private": true, "version": "0.1.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" }, "dependencies": { "@swmansion/smelter": "0.2.0", "@swmansion/smelter-web-wasm": "0.2.0", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": {11 collapsed lines
"@eslint/js": "^9.19.0", "@types/node": "20", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react-swc": "^3.5.0", "eslint": "^9.19.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.18", "globals": "^15.14.0", "typescript": "~5.7.2", "typescript-eslint": "^8.22.0", "vite": "^6.1.0", "vite-plugin-static-copy": "^2.2.0" }}import { defineConfig } from 'vite'import react from '@vitejs/plugin-react-swc'import { viteStaticCopy } from 'vite-plugin-static-copy';import { createRequire } from 'node:module';import path from 'node:path';
const require = createRequire(import.meta.url);
export default defineConfig({ plugins: [ react(), viteStaticCopy({ targets: [ { src: path.join( path.dirname(require.resolve('@swmansion/smelter-browser-render')), 'smelter.wasm' ), dest: 'assets', }, ], }), ], optimizeDeps: { exclude: ['@swmansion/smelter-web-wasm'], include: ['@swmansion/smelter-web-wasm > pino'] },});