Documentation

Name Mangling

Reference guides for release workflows, command-line usage, cross-file protections, and the desktop app.

Inside the Docs

Practical guides for real release work.

How-to guides Start with release sequencing and command-line usage, then move into feature-specific references.
Advanced protection Browse cross-file controls like Replace Globals and Protect Members when a build spans multiple scripts.

Name Mangling

  • ReplaceNames
  • Free

Name Mangling is the base obfuscation option. It replaces local identifiers — variables, function parameters, and locally declared functions — with short generated names. Every other transform assumes it is on, so this is the first option to enable and the last one you would turn off.

What it covers

By default this option focuses on local identifiers: anything whose scope is contained inside the file. That is deliberate. Local names can be rewritten with no coordination, because nothing outside the file can refer to them. The public surface of the file — global names, exported members, property keys other code reads by name — is left alone so protected output stays a drop-in replacement.

When you also need the public surface renamed, move up to the cross-file features, which require you to think about the whole build rather than one file:

  • Replace Globals (RenameGlobals) renames identifiers declared at global scope.
  • Protect Members (RenameMembers) renames object property and method names.
  • Variable Exclusion List (VariableExclusion) is the escape hatch that keeps named identifiers verbatim when a rename would break a contract.

Output styles

Two generated naming styles are available, selected with IdentityStyle. The choice is cosmetic for security purposes but does affect output size.

IdentityStyleShapeNotes
v1hex _0x1D6E7, _$_51d7 Long hexadecimal-style names. Visually noisy and the style most readers associate with obfuscated JavaScript.
v2abcd ed, b, k Short alphabetic names. Smaller output, and compresses better over the wire.

Compact hexadecimal-style names (v1hex):

if (_0x1EBFF[_$_51d7[103]](_0x1D60F, _$_51d7[160])) {
    var _0x1D6E7 = _0x1D60F[_$_51d7[222]][_$_51d7[169]];
}

Short alphabetic-style names (v2abcd):

if (ed[_$_3485[103]](b, _$_3485[160])) {
    var k = b[_$_3485[222]][_$_3485[169]];
}

Neither style is harder to rename back than the other. An analyst who wants readable names will generate their own; what mangling removes is the information the original names carried, and that is gone either way. Prefer v2abcd unless you have a reason to want the noisier look.

Configuration

Name Mangling is on in every preset. To set it explicitly in jso.config.json:

{
  "options": {
    "ReplaceNames": true,
    "IdentityStyle": "v2abcd"
  }
}

If you are migrating from the open-source javascript-obfuscator package, its identifierNamesGenerator option maps to IdentityStyle. See npm migration for the full option table.

Per-build polymorphic names

By default the generated names differ from build to build, so two protected copies of the same source do not line up name-for-name. That costs an analyst the ability to diff two releases and read off what changed, and it defeats deobfuscation scripts that hard-code names seen in an earlier build.

The trade-off is that output is not byte-identical between builds, which breaks reproducible-build checks and makes your CI artifact hashes churn. When you need stable output, pass a seed: the same input, options, and seed produce byte-identical output.

npx jso-protector --config jso.config.json --seed 20260803

Use a seed for release artifacts you need to reproduce or attest to, and omit it when you want each build to look different. See configuration presets for where this sits relative to the preset options.

What it does not protect

Name Mangling changes names, not structure. After mangling, the control flow, the string literals, and the shape of every object are still exactly as you wrote them — only the labels are gone. That is enough to stop casual reading and copy-paste reuse, and it is not enough to stop a determined reader with time.

Layer structural transforms on top when the logic itself is the asset:

Debugging mangled output

Once names are generated, every production stack trace names them instead of your functions. Keep the identifier map that a protected build emits and demangle traces on the way in rather than reading them raw — see symbolication and the production debugging walkthrough.

Start here: if you are new to the product, enable Name Mangling alone first and confirm your test suite passes against the protected output. Once that baseline is green, add one transform at a time. A break introduced by three simultaneous changes takes far longer to attribute than three verified steps.

Try this in the online obfuscator

Paste your own code and see this option applied, or compare plans for larger projects and the desktop app.

Try It Free See Pricing