npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

afterpack

v0.2.2

Published

AfterPack CLI: obfuscate the JavaScript in any build output, verify a build before deploy, and scan a live site

Readme

afterpack

The command-line JavaScript obfuscator from AfterPack. Run it after your build, over the output directory, to protect JavaScript source code before you ship it. It works with any bundler, or none.

npx afterpack@latest dist                  # a build directory, walked recursively
npx afterpack@latest dist/bundle.js        # or one .js, .mjs or .cjs file
npx afterpack@latest dist --preset=hard --seed=git
npx afterpack@latest verify .              # check a build before you deploy it
npx afterpack@latest restore               # undo the last run
npx afterpack@latest audit example.com     # scan a live site

Use afterpack@latest so npx does not pick up an old cached copy. afterpack --help lists the common options and afterpack --help --all lists every one.

If your project uses a framework with an AfterPack plugin (Vite, Next.js, webpack, Nuxt, Astro and others), the plugin is the better fit. Most plugins obfuscate inside the build, so the readable bundle never reaches disk; the Next.js, esbuild and Angular integrations run right after the tool writes its output. Run afterpack with no path and it tells you which plugin to install.

afterpack [path]

Files are obfuscated in place. Build first, then run AfterPack once. A second run over the same output is refused, because AfterPack recognises its own output.

Nested node_modules/ folders are skipped. Pass --paths.include='**/node_modules/**' (quoted) to include them.

Each run writes:

  • .afterpack-protection.json in the output directory, the receipt that afterpack verify checks.
  • .afterpack/backup/, a copy of the original files, so afterpack restore can undo the run. Turn it off with --build.backup=false.
  • .afterpack/protectionMap.html, the Protection Map, when your build has source maps.
  • .map files next to the output, when your build has source maps and the run is not a production build.

The backup and the Protection Map contain your original source. .afterpack/ carries its own .gitignore and self-ignores. Never deploy or commit them.

With no path, afterpack looks at your project first. If it finds a framework, it prints the plugin to install (or tells you the one you have already covers the build) and exits 1. Otherwise it picks the build output (dist/, build/, out/, .output/ or .next/), says what it found and runs. It never prompts.

afterpack verify [dir]

Checks a build against its protection receipt. Run it in your deploy step.

npx afterpack@latest verify .        # looks in ./ and ./.next/
npx afterpack@latest verify dist

It exits 1 when the receipt is missing, belongs to a different build, or a file changed after it was obfuscated. The CLI and the plugins for Vite, Next.js, webpack, Rollup, esbuild and Angular all write a receipt.

afterpack restore [dir]

Puts back the original files from .afterpack/backup/. A file that changed since the run is skipped and named, and the command exits 1.

afterpack audit <url>

Scans a live site for leaked secrets, exposed source maps and unprotected JavaScript, and prints a link to the full report. It sends only the URL and writes nothing. A finished scan exits 0 however much it found. It is the free website security scanner in your terminal; see auditing a live site.

Options

Every option has one name, written the same way everywhere:

  • --preset=hard on the command line
  • AFTERPACK_preset=hard in the environment (dots become underscores)
  • "preset": "hard" in afterpack.json, the nearest one at or above the working directory

A flag wins over the environment, which wins over the file. A boolean flag on its own means true. An unknown or misspelled option fails the run and names the right spelling.

| Flag | What it does | Default | | --- | --- | --- | | --preset | minify, light, medium, hard or extreme | light | | --seed | fix the seed; git uses the current commit | a new random seed per build | | --paths.exclude | globs to leave untouched | none | | --paths.include | globs to add back to the walk | none | | --identifiers.reserved | names never to rename | none | | --build.backup | back up originals to .afterpack/backup/ | true | | --protectionMap.enabled | write the Protection Map | on when an input map exists |

Each flag is also a key in afterpack.json and an AFTERPACK_* variable. Every other option is in the configuration reference. The CLI reference covers the commands.

{
  "preset": "hard",
  "seed": "git",
  "paths": { "exclude": ["dist/vendor/**"] },
  "identifiers": { "reserved": ["Hls"] }
}

--diagnostics.format=json prints exactly one JSON document on stdout and sends everything else to stderr. Use it in CI and scripts. verify and audit support it too.

Pro

Without a key, AfterPack runs on your machine with the full pipeline at any preset. Set AFTERPACK_KEY in your environment (or key in afterpack.json) and the same command builds in AfterPack's cloud instead, which adds two hardening transforms you can turn on: self-integrity (anti-tamper) and comparison hardening. If the cloud cannot be reached, the run fails; it never falls back to a local build. Never commit the key. See AfterPack Pro.

Exit codes

| Code | Meaning | | --- | --- | | 0 | Success. | | 1 | Failure. Nothing was changed, or verify, restore or audit failed. | | 2 | Some files shipped unobfuscated. Only possible with allowUnobfuscated. | | 3 | The size limit (inflation.max) stopped AfterPack before it reached the protection level. | | 6 | An update is required. The CLI prints the install command to run. | | 64 | Misuse: an unknown option or command, or a malformed value. |

Every failure prints one line that says how to fix it. A failed run leaves your build output as your bundler wrote it.

Links

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.