@afterpack/next
v0.2.2
Published
Next.js integration for AfterPack: obfuscate the client JavaScript of a Next.js build inside next build
Maintainers
Readme
@afterpack/next
Obfuscate a Next.js build with one config wrapper. @afterpack/next protects the client JavaScript
that next build produces, using the AfterPack JavaScript obfuscator.
It needs Next.js 15.4 or later and works with Turbopack or webpack, the App Router or the Pages
Router, and static export.
Install
npm install --save-dev @afterpack/nextUsage
// next.config.ts
import type { NextConfig } from "next";
import { withAfterpack } from "@afterpack/next";
const nextConfig: NextConfig = {
/* your config */
};
export default withAfterpack(nextConfig);A function config works too: withAfterpack(async (phase, ctx) => ({ ... })). There is no
postbuild script: Next runs AfterPack itself, right after compiling and before prerendering and
export. A plain next build in CI produces obfuscated output,
and if obfuscation fails, next build fails.
AfterPack obfuscates the client chunks in .next/static/chunks. With output: "export", the
obfuscated chunks are what lands in out/. Server code in .next/server never reaches the browser
and is left as is. The plugin also removes the .js.map and .css.map files from .next/static, and
the comments that point at them, since a served source map gives your source away.
Check a deploy
Each build writes .next/.afterpack-protection.json, a receipt with a hash per obfuscated file.
Run npx afterpack verify . before you deploy. It fails when the receipt is missing, belongs to a
different build, or a file changed after obfuscation.
Options
Pass them as the second argument: withAfterpack(nextConfig, { preset: "hard", seed: "git" }).
| Option | What it does | Default |
| --- | --- | --- |
| preset | "minify", "light", "medium", "hard" or "extreme" | "light" |
| seed | a number or string; "git" uses the current commit | a new random seed per build |
| identifiers.reserved | names never to rename | none |
| paths.exclude | globs for files to leave untouched | none |
| sourceMap.enabled | write source maps for the obfuscated output | on in development when an input map exists, off in production |
| protectionMap.enabled | write the Protection Map | on when Next emits browser source maps |
| build.autorun | false turns AfterPack off | true |
Dotted names are nested objects: build.backup is { build: { backup: true } }. Every
other option is in the configuration reference.
/* @afterpack */ directives that raise protection for
a region are a Pro feature. They and a readable Protection
Map both need productionBrowserSourceMaps: true in
your Next config. The Protection Map is written to .afterpack/, which carries its own .gitignore
and self-ignores. It contains your original source, so never deploy or commit it.
Options can also live in afterpack.json or in AFTERPACK_* environment variables. The options
object wins over the environment, which wins over the file. An unknown or misspelled key fails the
build and names the right spelling.
Your own build hook
If your config already sets compiler.runAfterProductionCompile, it still runs, before AfterPack.
A hook that uploads source maps to an error tracker will upload maps of the code before
obfuscation.
Limitations
experimental.sri is not supported. Next computes integrity hashes before AfterPack runs, so the
browser would block the obfuscated chunks. The build stops with an error that says so.
Pro
Without a key, AfterPack runs on your machine with the full pipeline at any preset. Set
AFTERPACK_KEY in your environment and the same plugin
builds in AfterPack's cloud instead, which adds per-region
directives and two hardening transforms you can turn
on: self-integrity (anti-tamper) and comparison hardening. Keep the key out of next.config.ts: the
plugin rejects it there. See AfterPack Pro.
Links
- Next.js setup guide
- Presets and protection levels
- How AfterPack compares to other obfuscators
- Protecting paywall checks in client code
License
Apache-2.0. The engine it runs, @afterpack/core, has its own
license.
Feedback
Questions, suggestions and bug reports: afterpack.dev/contact. You can also file a bug on GitHub Issues.
