# Complexity

The single dial behind every preset: what rises as the number climbs, the one threshold that flips at medium, and which transformations config can turn off but not force on.

Source: https://www.afterpack.dev/docs/complexity

`complexity` is the single dial that decides how much protection the engine applies. A [preset](https://www.afterpack.dev/docs/presets) is a named point on it: `light` is `2`, `hard` is `25`. Set [`complexity`](https://www.afterpack.dev/docs/config#complexity) directly for a value in between or beyond — it is an unbounded non-negative number.

## What rises with the number

Complexity is a budget, not a schedule. There is no fixed list of "this feature at this number". Above `0`, the engine spends a larger budget as the value climbs and negotiates which transformations to apply, per build — so two builds at the same complexity are different shapes, and no single transformation is guaranteed at a given level. That per-build variation is the point: see [how AfterPack works](https://www.afterpack.dev/docs/concepts) for why a fixed structure would be a fingerprint.

Three things are fixed:

| `complexity` | What is guaranteed |
|---|---|
| `0` (`minify`) | No obfuscation. Minification only; nothing below runs. |
| `> 0` | Every string literal the engine can rewrite goes through a runtime decoder — the [string floor](https://www.afterpack.dev/docs/presets#the-default-is-light). |
| `≥ 8` (`medium` and up) | Encoded strings and integers are keyed to a shared runtime value, and object literals are rebuilt in varied shapes. |

Everything else — control-flow reshaping, opaque predicates, integer-expression interpretation, and the rest — is drawn from the budget as it grows, not switched on at a line. Raising [`inflation.max`](https://www.afterpack.dev/docs/config#inflation-max) gives the engine more room and it applies more of them; lowering it applies fewer at the same complexity.

## Turning a transformation off, or on

You can turn any transformation kind off. You cannot force one on.

- **Off is reliable.** [`transforms.<kind>.enabled = false`](https://www.afterpack.dev/docs/config) removes that kind at any complexity.
- **On is a permission.** `true` lets the engine use a kind; it still decides per build whether the complexity and budget call for it. Some kinds appear only at `medium` and up, and the two Pro kinds need a [Pro](https://www.afterpack.dev/docs/pro) build.
- **At `0`, none of it applies.** `minify` runs no transformations, so every `transforms` flag is moot.

To make a transformation more likely, raise `complexity` (or [`inflation.max`](https://www.afterpack.dev/docs/config#inflation-max)) rather than toggling a flag.

## Next

- [Presets](https://www.afterpack.dev/docs/presets): the named levels and the size budget each one sets.
- [Configuration](https://www.afterpack.dev/docs/config): every key, including the `transforms.<kind>.enabled` flags.
- [How AfterPack works](https://www.afterpack.dev/docs/concepts): why the set of transformations changes every build.
- [Directives](https://www.afterpack.dev/docs/directives): a different complexity for one region (Pro).
