JavaScript obfuscation for your framework

Which package to install for your stack, where it hooks, and what it writes.

AfterPack obfuscates the JavaScript your bundler produced. Install the package for your stack and your normal build emits obfuscated output. For anything else, run npx afterpack@latest over the build output.

Framework matrix

FrameworkPackageHow you wire itWhere it runsBuild output
Next.js@afterpack/nextwithAfterpack(config)runAfterProductionCompile, inside next build.next/static/chunks, out/
Vite@afterpack/viteafterpackVite() in pluginsgenerateBundle, in the pipelinebuild.outDir
Webpack@afterpack/webpacknew AfterpackWebpackPlugin()compilation.hooks.processAssets, in the pipelineoutput.path
Rollup@afterpack/rollupafterpackRollup() in pluginsgenerateBundle, in the pipelineoutput.dir or output.file
esbuild@afterpack/esbuildafterpackEsbuild() in pluginsonEnd, after esbuild writesoutdir or outfile
Astro@afterpack/astroafterpack() in integrations@afterpack/vite inside Astro's Vite configdist/
Svelte@afterpack/svelteafterpackSvelte() in plugins@afterpack/vitedist/
SvelteKit@afterpack/sveltekitafterpackSveltekit() after sveltekit()@afterpack/viteadapter output (build/)
Vue 3@afterpack/vueafterpackVue() after vue()@afterpack/vitedist/
Nuxt 3@afterpack/nuxtmodules: ["@afterpack/nuxt"]@afterpack/vite on Nuxt's Vite config.output/public/_nuxt/
Angular v17+@afterpack/angularafterpackAngular() in a postbuild scripta postbuild pass, after ng build writesdist/<app>/browser
Electron@afterpack/electronwithAfterpack(config) around electron-vite@afterpack/vite on all three legs, one seedeach leg's out/
Parcel@afterpack/parcel-optimizeran entry in .parcelrc optimizersa Parcel 2 Optimizer, per bundle, in the pipelineParcel's distDir

Astro, Svelte, SvelteKit, Vue, Nuxt and Angular install @afterpack/vite, or run the same shared pass, so you do not have to wire it by hand.

No plugin

StackPath
Remix / React Router v7Builds on Vite: use @afterpack/vite, or the CLI.
Plain JSNo bundler to hook: npx afterpack@latest <dir>.

What every integration does

The defaults are on the Quickstart. Beyond those, every plugin and the CLI share this behavior:

  • Build mode is detected. NODE_ENV=production or CI=true selects production, which turns source-map emission off. A shipped map reverses the obfuscation.
  • The same artifacts. One combined protectionMap.html in the gitignored .afterpack/, and a .map next to each file when maps are on. The guard globs are appended to your .gitignore. build.backup takes two shapes: the CLI mirrors your originals into .afterpack/backup/ on every run, and a plugin that obfuscates files on disk (@afterpack/next, @afterpack/esbuild, @afterpack/angular) writes a .backup.<hash> sibling beside the output when you ask for one. The in-pipeline plugins have no emitted file for a backup to sit beside, and warn when you ask.
  • One switch to skip a run. build.autorun: false keeps the plugin installed and skips the engine.
  • Directives are read from your source by the plugin — on every integration that has a hook to read them from. Angular refuses the key outright: its builder is sealed, so the pass only sees already-minified output.

Next