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
| Framework | Package | How you wire it | Where it runs | Build output |
|---|---|---|---|---|
| Next.js | @afterpack/next | withAfterpack(config) | runAfterProductionCompile, inside next build | .next/static/chunks, out/ |
| Vite | @afterpack/vite | afterpackVite() in plugins | generateBundle, in the pipeline | build.outDir |
| Webpack | @afterpack/webpack | new AfterpackWebpackPlugin() | compilation.hooks.processAssets, in the pipeline | output.path |
| Rollup | @afterpack/rollup | afterpackRollup() in plugins | generateBundle, in the pipeline | output.dir or output.file |
| esbuild | @afterpack/esbuild | afterpackEsbuild() in plugins | onEnd, after esbuild writes | outdir or outfile |
| Astro | @afterpack/astro | afterpack() in integrations | @afterpack/vite inside Astro's Vite config | dist/ |
| Svelte | @afterpack/svelte | afterpackSvelte() in plugins | @afterpack/vite | dist/ |
| SvelteKit | @afterpack/sveltekit | afterpackSveltekit() after sveltekit() | @afterpack/vite | adapter output (build/) |
| Vue 3 | @afterpack/vue | afterpackVue() after vue() | @afterpack/vite | dist/ |
| Nuxt 3 | @afterpack/nuxt | modules: ["@afterpack/nuxt"] | @afterpack/vite on Nuxt's Vite config | .output/public/_nuxt/ |
| Angular v17+ | @afterpack/angular | afterpackAngular() in a postbuild script | a postbuild pass, after ng build writes | dist/<app>/browser |
| Electron | @afterpack/electron | withAfterpack(config) around electron-vite | @afterpack/vite on all three legs, one seed | each leg's out/ |
| Parcel | @afterpack/parcel-optimizer | an entry in .parcelrc optimizers | a Parcel 2 Optimizer, per bundle, in the pipeline | Parcel'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
| Stack | Path |
|---|---|
| Remix / React Router v7 | Builds on Vite: use @afterpack/vite, or the CLI. |
| Plain JS | No 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=productionorCI=trueselects production, which turns source-map emission off. A shipped map reverses the obfuscation. - The same artifacts. One combined
protectionMap.htmlin the gitignored.afterpack/, and a.mapnext to each file when maps are on. The guard globs are appended to your.gitignore.build.backuptakes 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: falsekeeps 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
- Quickstart: pick a stack and build.
- Builds and CI: seeds, dev versus production, promoting the same bytes.
- Configuration: every option and where to set it.