Deep Obfuscation is an advanced form of Name Mangling that pushes identifier reuse further. Rather than giving every identifier in the file a distinct short name, it reuses the same names in different scopes wherever the language permits, so a name stops being a unique handle on a value.
What it does
Plain name mangling assigns each identifier its own generated name, which means the output is still a one-to-one relabelling of your source. Rename them back and you have your program. Deep Obfuscation removes that one-to-one property: after it runs, seeing a tells you nothing, because a in one scope and a two frames down are unrelated values.
Without Deep Obfuscation:
function a(b, c) {
function(d, e) {
}
}
With Deep Obfuscation enabled:
function a(a, b) {
function(a, b) {
}
}
Note the outer function is now called a and its own first parameter is also a — legal JavaScript, since the parameter shadows the function name inside the body.
Why the ambiguity matters
Shadowing attacks the technique that makes obfuscated code tractable: building a mental — or scripted — symbol table. A reader tracing a through a call chain has to re-derive which a they are looking at at every scope boundary, and a script that renames identifiers back to readable names has nothing consistent to rename, because the same token legitimately means different things in different places.
It also shrinks output. Reusing a small pool of names means shorter names overall, which is why the transform tends to pay for itself in bytes even before compression.
The honest boundary: this raises the cost of reading, and it does not change what the code does. Tooling that works on scopes rather than names — which includes any serious analysis, and increasingly includes LLM-assisted review — handles shadowing correctly, because a real scope analysis never confused the two as in the first place. Treat this as raising the floor against manual and scripted reading, and see AI resistance evidence for how we describe the limits of that claim.
Configuration
{
"options": {
"ReplaceNames": true,
"DeepObfuscate": true
}
}
If you are migrating from the open-source javascript-obfuscator package, its controlFlowFlattening option maps to DeepObfuscate together with FlatTransform — that single upstream flag covers two options here. See npm migration.
Test more carefully than usual
Deep Obfuscation is a scope-sensitive transform, which makes it more demanding on the engine's scope analysis than plain renaming. That analysis has to get several JavaScript details exactly right — var hoisting out of blocks, function declarations in loop bodies, class bodies as nested scopes, and the arguments object inside a function whose parameters have been renamed. Each of those is a place where an incorrect rename produces code that parses cleanly and behaves differently.
- Run your full test suite against protected output, not a smoke test. A shadowing bug typically surfaces as a wrong value, not a crash.
- Pay attention to closures. Code that captures a loop variable, or relies on a named function expression referring to itself, is the highest-risk shape.
- Enable it on its own first. Turn on
DeepObfuscate with name mangling and nothing else, confirm green, then layer structural transforms.
- Use compatibility validation to catch the mechanical cases before you run anything.
Related options
- Flat Transform rewrites control flow into state-machine dispatch — structure rather than names, and the natural partner to this option.
- Code Transposition reorders statements so source order stops implying execution order.
- Move Nested Function relocates nested functions away from their call sites.
- Variable Exclusion List holds specific names out of every renaming transform, including this one.
Use it when: you already want Name Mangling, you need a stronger result, and you are prepared to test the output more carefully before release. If you cannot run a real test suite against protected output, stay on plain name mangling — an untested strong transform is a worse outcome than a tested weak one.