How to Use a SPFx Heft Patch for WebAssembly (SPFx 1.22+)
About a year ago, I had to integrate WebAssembly into the SharePoint Framework toolchain. It was quite a challenge then. Now that the SharePoint Framework release candidate, based on Heft, is out, I gave it another try. Full of curiosity to see how this would work in the new tool chain.
The key is to patch the webpack configuration.
What is a Heft patch in SPFx 1.22
A Heft patch, or as I jokingly call it, a “Heftpflaster” (the German word for adhesive bandage/patch), is a lightweight way to customise the built-in Webpack configuration without replacing the SPFx build rig.
In the gulp area, we did something like this.
build.configureWebpack.mergeConfig(...)
While most Webpack customisations previously used build.configureWebpack.mergeConfig() works directly as patches; more complex scenarios may require additional adjustments or, in rare cases, using eject-webpack to fully control the configuration.
How to create a Heft patch
The first step is to let the build rig know we want to use this patch. Therefore, the first thing is that we need to create a new file in the config folder. The filename needs to be webpack-patch.json and serves as our quasi-patch registration.
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/webpack-patch.schema.json",
"patchFiles": []
}
The content of this file needs to be like this. In there, we reference the schema. The patchFiles array, currently empty, will point to all the patch files we want to apply to the webpack configuration.
With that, we are all set for the next step: implementing the patch.
Implement the patch
Unlike webpack-patch.json, which must be stored in the config folder, the implementation files for your patches can be located wherever you like, as long as the file paths are correctly referenced in patchFiles.
The official documentation places them under config/webpack-patch/, but other locations, such as a dedicated patches folder, work fine.
They can be placed inside the config folder. Still, for better separation and easier future updates, I prefer to keep them in a dedicated folder, such as the top-level patches folder at the project root.

lower highlight box folder for various heft patches
In the folder, I created a dedicated webpack folder too, because it lets you see at first glance for which technology the patch is for.
module.exports = function (webpackConfig) {
// Ensure module/rules exists
webpackConfig.module = webpackConfig.module || {};
webpackConfig.module.rules = webpackConfig.module.rules || [];
// Add rule for .wasm
webpackConfig.module.rules.push({
test: /\.wasm$/,
type: 'webassembly/async' // Async WebAssembly handling
});
// Enable async WebAssembly experiments (merge with existing if any)
webpackConfig.experiments = {
...(webpackConfig.experiments || {}),
asyncWebAssembly: true
};
return webpackConfig;
};
The file above now contains all the configurations that have already been required for the gulp/webpack configuration. With that, only one last thing is left to do. Adding the Heft patch to our registration. The template file we used before now looks like this.
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/webpack-patch.schema.json",
"patchFiles": [
"./Heft-patches/webpack/enable-fontkit-wasm.js"
]
}
Now the fontkit WebAssembly will get picked up by the webpack configuration of the SharePoint Framework, and we can use it in our code like before.
// Import font kit
import * as fontkit from 'fontkit';
// ...
// Output the font options
const font = fontkit.create(Buffer.from(arrayBuffer));
console.debug('FONT::: ', font);
console.debug(`Font Family: ${font.familyName}`);
console.debug(`Font Subfamily: ${font.subfamilyName}`);
console.debug(`Number of Glyphs: ${font.numGlyphs}`);
This then created the following output in the console log of the SharePoint web part.

The fontkit WebAssembly works like before.
In comparison with gulp integration
The original code shown below does not look much different from the Heft integration. The original code shown below does not look much different from the new integration.
// Configuration for WebAssembly
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.rules.push({
test: /\.wasm$/,
type: 'webassembly/async', // Async WebAssembly handling
});
generatedConfiguration.experiments = {
asyncWebAssembly: true, // Enables async WebAssembly imports
}
return generatedConfiguration;
}
});
SPFx continues to use Webpack for bundling, just like in earlier versions. The difference is that Webpack is now orchestrated by Heft rather than by the Gulp build pipeline.
Verdict
I thought that in the case of webpack configuration, it would be a real pain. The configuration update for my old project took practically five minutes to apply the patch.
WebAssemblies are more of an outlier, and you might not apply them to all your projects.
While writing this blog post, I had the following idea. What if I had multiple Heft patches (HeftPLASTER) for my customisations, the ones that repeat in every customisation?
The solution to that is simple. Store them in a centralised repo, for example, and install them in your solutions via npm. If you like to go fancy, publish an NPM package that contains all your patches.
Further Reading
Customize the Webpack configuration using the Heft Webpack Patch Plugin
https://learn.microsoft.com/sharepoint/dev/spfx/toolchain/customize-heft-toolchain-customize-webpack-configOverview of the new Heft-based SPFx toolchain
https://learn.microsoft.com/sharepoint/dev/spfx/toolchain/customize-heft-toolchain-overviewSPFx Release 1.22 Notes
https://learn.microsoft.com/sharepoint/dev/spfx/release-1.22Official Heft documentation
https://heft.rushstack.io/FontKit (WebAssembly-enabled font engine)
https://github.com/rsms/fontkitCurious how to Upgrade to SPFx 1.22+? Let my show my AI-driven apporach