Protect Members renames object member names across the files in a project. It is the cross-file counterpart to simpler member-hiding options such as Move Members.
What it protects
This feature targets member names such as value in myobj.value or Start in helper.Start(). Unlike Move Members, which only hides access syntax, Protect Members actually changes the member names themselves.
Because member names often form part of a public API, this mode is stricter than Replace Globals. You should explicitly decide which members are safe to rename.
Recommended workflow
- Mark private members with a naming rule, such as a double-underscore prefix.
- Configure Rename by rules or Custom Identities so only those private members are eligible.
- Keep every related file in the same JavaScript Obfuscator project so the renamed members stay consistent everywhere.
Example across files
Using a rule such as ^__, the member names that start with a double underscore can be renamed everywhere they appear in the project.
Configuration
{
"options": {
"RenameMembers": true
}
}
From the open-source javascript-obfuscator package, renameProperties maps to RenameMembers. Its renamePropertiesMode is accepted for migration review — see npm migration.
Why this option needs more care than the others
Every other transform on this site is contained: it changes a file and the file still presents the same interface to the world. This one changes an interface. A renamed property is a different property, and anything that reads it by its original name stops working — usually at runtime, on one code path, with no build error.
The places a member name escapes your JavaScript are easy to overlook:
- JSON boundaries. A field name in a request body or a response your code reads is a contract with a server.
JSON.parse produces the server's names, not your renamed ones.
- Storage. Anything already written to
localStorage, IndexedDB, or a cookie by a previous release carries the old names. Renaming makes existing user data unreadable.
- Templates and markup. A framework binding such as
{{item.total}} is text in a template, and a data- attribute read by name is text in your HTML.
- Framework conventions. Lifecycle hooks, component prop names, and anything a library resolves by string.
- Reflection.
Object.keys, for...in, and destructuring by name all see the new names.
This is why the recommended workflow inverts the default: rather than renaming everything and excluding what breaks, mark what is private with a naming convention and rename only that. Opting in is recoverable; opting out means discovering each contract by breaking it.
Related options
- Move Members hides member access without renaming anything, so it carries none of the risk above. Start there if you are unsure.
- Replace Globals renames global identifiers — the same class of cross-file decision, one scope up.
- Protect Object Declaration hides object structure without changing key names.
- Variable Exclusion List covers identifiers rather than members; the two lists are separate.
- Because renaming is project-wide, keep every related file in one project and one build. A file protected in a separate run gets its own naming decisions and will not agree with the rest — see release workflows.
Best practice: only rename members that are truly private to your own code. If third-party scripts, templates, or external callers depend on a member name, leave it out of the protection rules. When protected output throws an undefined-property error, this is the first option to suspect —
the six causes of broken protected output walks the diagnosis in order.