Obfuscation glossary

AfterPack's documentation vocabulary: polymorphism, non-materialization, reversal classes, and the rest, defined once.

AfterPack's documentation uses these terms with the meanings defined here.

The two axes

AfterPack's protection is described along two independent axes: how hard one build is to reverse, and how different builds are from each other. You can turn one up without the other.

Complexity

How hard a single build is to reverse: the depth of protection within one artifact. Set by complexity, directly or from a preset.

Per-build polymorphism

How different each build is from the last. Set by the seed: seed in the engine config, --seed on the command line. This is AfterPack's primary defense. Every build has a different shape, so tools written against one build's patterns break on the next. Someone who runs the code can still read the values it uses. See How AfterPack works.

Configuration

Preset

A named bundle of protection settings, selected with one flag: minify, light, medium, hard, extreme. Default is light. One preset name sets the complexity target. The target each rung sets is on Presets.

complexity

The degree of entanglement in the output; see Configuration. It has no upper bound. An explicit inflation.max that blocks it fails the build; left unset, the target alone decides how far the output grows. Per-preset values are on Presets.

Directives

In-source block comments that adjust protection on the construct they attach to. An inline /* @afterpack preset=extreme */ covers the literal right after it. A block form, /* @afterpack <key>=<value> */ … /* @afterpack end */, opens with the marker alone on its line and closes with the matching end, covering an explicit span. A // line comment is not scanned. skip reduces protection where you need compatibility; preset=hard or preset=extreme raise it. Only a Pro engine honors a region; see Free builds. A Free carve-out uses paths.exclude or identifiers.reserved instead. See Directives.

preset=hard

A directive (/* @afterpack preset=hard */) that raises a region to complexity 12, the hard rung, and forces the string floor on for that region regardless of the global preset. /* @afterpack preset=extreme */ does the same at target 25.

Reversal and the attacker model

Fixed structure

A shape that stays the same across builds: a string array (even an encrypted one), a VM interpreter, a decoder bootstrap that is identical in every build. That shape is what a tool like webcrack, or a model, learns once and reuses on every build that shares it. Any obfuscator can vary constants build to build; what matters is whether such a shape remains underneath. AfterPack draws its shapes, names, constants and layout fresh from each build's seed, so a recognizer written against one build's patterns breaks on the next. It does not hide values from someone who runs the code. See Why fixed obfuscation layers fail.

Reversal classes

Three static-attacker classes describing what a reader of the bytes, grep, AST tooling, or a blind LLM that doesn't execute the code, walks away with: renamed & encoded, flattened & fused, and destroyed & fused. A dynamic attacker who runs the code is a separate, stronger case. The class table and what each buys an attacker are on Reversal classes. Only the first, renamed & encoded, is produced by a shipped transform today; flattened & fused and destroyed & fused are reserved.

Non-materialization

The mechanism that protects a secret, separate from the reversal classes above, which recover structure rather than values. Delivered by transforms.comparisonHardening.enabled, which rewrites a string equality gate into a one-way digest check so the literal is absent from the artifact. This differs from the string floor, which encodes a literal but still reconstructs it at use. It defeats a static reader and a blind LLM. It does not defeat an attacker who runs the code under an instrumented runtime; no build-time obfuscator changes that. See How secrets survive.

Delivery, seed and tiers

Seed

The build parameter that selects which polymorphic output gets produced. Random by default. It is not a secret: the shipped artifact is public regardless, and knowing a build's seed doesn't help reverse it. Vary it per release in production. Pin it (--seed=git) only when you need byte-identical output, for CI caching or a reproducible audit. See seed and Builds & releases.

Source maps

Mappings that chain obfuscated output back to your original source. Useful for local debugging. A public .map hands an attacker a direct path to your source. Never ship one to production. AfterPack defaults source maps off on a production build, drops the sourceMappingURL comment and deletes the maps your bundler wrote.

Protection Map

The report that colours every token of your source by its complexity score and names the reversal class of each region. Engine-driven by default; user-directed once you mark regions on Pro. Controlled by protectionMap.enabled. See Protection Map, or open the live demo.

Tiers

Free, Extra MB, Indie, Team, Studio, Enterprise. Free applies full-strength protection uniformly across the bundle. Paid tiers apply it per region and per file. Prices, allowances, and project limits are on Plans & tiers.

Fail-closed

The rule that a Pro build never ships weaker protection than you asked for. If the Pro cloud is unreachable after retrying, or quota runs out mid-batch, AfterPack stops with a non-zero exit. It does not fall back to Free-tier or plaintext output. See Exit codes & fail-closed.

Next