For AI agents: the complete documentation index is available at https://rspack.rs/llms.txt, the full documentation bundle is available at https://rspack.rs/llms-full.txt, and this page is available as Markdown at https://rspack.rs/plugins/subresource-integrity-plugin.md.
close

SubresourceIntegrityPlugin

Added in v1.7.0Rspack only

The rspack.SubresourceIntegrityPlugin is a plugin for enabling Subresource Integrity in Rspack.

In versions 1.2.4 to 1.6.8, you can use rspack.experiments.SubresourceIntegrityPlugin.

What is SRI

Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

For <script> tags, the result is to refuse to execute the code; for CSS links, the result is not to load the styles.

For more on subresource integrity, see Subresource Integrity - MDN.

Features

Support for HTML plugin

The plugin supports integration with HtmlRspackPlugin and html-webpack-plugin. It will automatically set the integrity and crossorigin attributes for the injected tags.

Support for code splitting

The plugin supports code splitting. When you use dynamic imports, the plugin will automatically set the integrity and crossorigin attributes for the generated chunk loading tags.

Examples

You can use the plugin by importing it from @rspack/core:

rspack.config.mjs
import { SubresourceIntegrityPlugin } from '@rspack/core';

Or:

rspack.config.cjs
const { SubresourceIntegrityPlugin } = require('@rspack/core');

The output.crossOriginLoading option is required for SRI to work:

rspack.config.mjs
import { SubresourceIntegrityPlugin } from '@rspack/core';

export default {
  output: {
    crossOriginLoading: 'anonymous',
  },
  plugins: [new SubresourceIntegrityPlugin()],
};

With HTML plugin

When the HTML plugin(HtmlRspackPlugin or html-webpack-plugin) is used, the integrity and crossorigin attributes will be set automatically.

The SubresourceIntegrityPlugin will interact with HtmlRspackPlugin by default:

rspack.config.mjs
import { SubresourceIntegrityPlugin, HtmlRspackPlugin } from '@rspack/core';

export default {
  plugins: [new SubresourceIntegrityPlugin(), new HtmlRspackPlugin()],
};

If html-webpack-plugin is used, the htmlPlugin option should be specified to the path of it:

rspack.config.mjs
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { SubresourceIntegrityPlugin } from '@rspack/core';

export default {
  plugins: [
    new SubresourceIntegrityPlugin({
      // the path to the html-webpack-plugin
      htmlPlugin: import.meta.resolve('html-webpack-plugin'),
    }),
    new HtmlWebpackPlugin(),
  ],
};

With HTML plugin and inject: false

If you use the HTML plugin with inject: false, you need to set the integrity and crossorigin attributes in your template manually.

With HtmlRspackPlugin, the grammar of the template is a bit different with .ejs(see here), you can inject them like this:

index.ejs
<% for src in htmlRspackPlugin.files.js { %>
  <script src="<%= src %>"
    integrity="<%= htmlRspackPlugin.files.jsIntegrity[index] %>"
    crossorigin="<%= rspackConfig.output.crossOriginLoading %>"
  ></script>
<% } %>

<% for _ in htmlRspackPlugin.files.css { %>
  <link href="<%= htmlRspackPlugin.files.css[index] %>"
    integrity="<%= htmlRspackPlugin.files.cssIntegrity[index] %>"
    crossorigin="<%= rspackConfig.output.crossOriginLoading %>"
    rel="stylesheet"
  />
<% } %>

With html-webpack-plugin, you can inject them like this:

index.ejs
<% for (let index in htmlWebpackPlugin.files.js) { %>
  <script
    src="<%= htmlWebpackPlugin.files.js[index] %>"
    integrity="<%= htmlWebpackPlugin.files.jsIntegrity[index] %>"
    crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
  ></script>
<% } %>

<% for (let index in htmlWebpackPlugin.files.css) { %>
  <link
    rel="stylesheet"
    href="<%= htmlWebpackPlugin.files.css[index] %>"
    integrity="<%= htmlWebpackPlugin.files.cssIntegrity[index] %>"
    crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
  />
<% } %>

Without HTML plugin

The integrity can also be obtained from stats.assets. For example:

compiler.hooks.done.tap('MyPlugin', (stats) => {
  const integrityValues = stats
    .toJson()
    .assets.map((asset) => [asset.name, asset.integrity]);
});
Tip

Note that when you add the integrity attribute on your link and script tags, you're also required to set the crossorigin attribute. It is recommended to set this attribute to the same value as the Rspack output.crossOriginLoading configuration option.

Options

hashFuncNames

  • Type: Array<"sha256" | "sha384" | "sha512">
  • Default: ["sha384"]

An array of strings, each specifying the name of a hash function to be used for calculating integrity hash values. Only supports sha256, sha384, and sha512 yet.

See SRI: Cryptographic hash functions for more details.

enabled

  • Type: "auto" | boolean

  • Default: "auto"

  • auto is the default value, which means the plugin is enabled when Rspack mode is production or none, and disabled when it is development.

  • true means the plugin is enabled in any mode.

  • false means the plugin is disabled in any mode.

htmlPlugin

  • Type: string
  • Default: "HtmlRspackPlugin"

The path to the HTML plugin, defaults to "HtmlRspackPlugin" which means the native HTML plugin of Rspack. If you are using the html-webpack-plugin, you can set this option to the path of it. It is recommended to set the absolute path to make sure the plugin can be found.

hashLoading

  • Type: "eager" | "lazy"
  • Default: "eager"

Determines whether SRI hashes for async chunks are stored together in the Rspack runtime chunk or distributed across parent chunks.

  • eager puts the hash of every async chunk in the Rspack runtime chunk, so its size grows with the number of async chunks.
  • lazy puts the hashes of the async chunks that a chunk's import() calls request in that chunk, and adds them to the Rspack runtime when the chunk loads. A hash that every parent of a chunk already provides is left out. This keeps the Rspack runtime chunk small in applications with many async chunks. A chunk that splitChunks shares between chunk groups carries the hashes for the calls in its own modules, not for every group that includes it.

Only JavaScript hashes are loaded lazily; CSS chunk hashes stay in the Rspack runtime chunk. This option matches the hashLoading option of webpack-subresource-integrity.

More information

You can find more information about Subresource Integrity in the following resources: