vite-plugin-stable-sri

Vite plugin for stable, reproducible Subresource Integrity manifests.


The Idea

vite-plugin-stable-sri is a Vite plugin that generates stable, reproducible Subresource Integrity (SRI) hashes with deterministic, byte-for-byte build output.

Webpack gives you this for free with the "deterministic" build output optimization option. Vite and Rollup can produce different chunk contents across builds due to non-deterministic module ordering, vendor grouping, or internal export minification. Which means your SRI hashes change even when your source code hasn't. This plugin fixes that.


What It Offers

Deterministic Builds

Forces reproducibility at the bundle level:

  • Stable file naming patterns using hex hash characters
  • Consistent manual chunk strategies (default: one chunk per node_modules package)
  • Disabled internal-export minification for byte-for-byte reproducibility

SRI Hash Generation

Three output types from a single plugin:

  • sri-manifest.json — Sorted mapping of every output file to its integrity hash and byte size
  • Injected HTML — Adds integrity and crossorigin attributes directly to scripts and stylesheets
  • Augmented manifest — Enriches Vite's own manifest.json with integrity fields

Flexible Chunk Strategies

Four options to control vendor bundling:

  • per-package — Separate chunk per top-level package (optimal stability + caching balance)
  • single-vendor — All node_modules in one chunk
  • none — Rollup's default (less stable across upgrades)
  • Custom function — Return a chunk name per module ID for full control

Simple Configuration

Drop it into your Vite config and go:

import { stableSri } from "vite-plugin-stable-sri";
 
export default defineConfig({
  plugins: [
    stableSri({
      algorithm: "sha384",
      crossorigin: "anonymous",
      chunkStrategy: "per-package",
      injectHtml: true,
      manifest: true,
    }),
  ],
});

Key Features

  • Three hash algorithms: sha256, sha384, or sha512
  • Sorted manifest output: Deterministic JSON, safe to diff and commit
  • HTML injection: integrity and crossorigin attributes added at build time
  • Vite manifest augmentation: Integrity fields added alongside existing chunk metadata
  • Configurable file targeting: include regex to control which files get hashed
  • ESM-only: Clean, modern package with no CommonJS baggage

Why Choose vite-plugin-stable-sri

  • Fixes the root cause of unstable SRI—non-deterministic chunk layout—rather than just re-hashing at the end
  • Works with Vite 5, 6, and 7
  • Zero runtime overhead—all processing happens at build time
  • Commit your sri-manifest.json and trust it won't change unless your code does
  • Pairs well with CSP headers and CDN integrity verification workflows

FAQs

  • Why not just hash after build? Other plugins do this, but if chunk contents shift between builds, your hashes shift too. This plugin stabilizes the chunks first.
  • What about dynamic imports? Runtime-fetched chunks are recorded in the manifest but can't be browser-enforced via SRI.
  • What does it override in my Vite config? entryFileNames, chunkFileNames, assetFileNames, hashCharacters, and minifyInternalExports. It also sets build.manifest: true automatically.

Tech

Built for Node.js ≥ 18 with TypeScript, targeting Vite 5–7 as an ESM-only package. Uses Rollup's generateBundle hook to compute and inject integrity hashes after bundle finalization.