JavaScript Obfuscator
Obfuscate JavaScript locally with repeatable profiles, runtime targets, reserved names, and size checks while keeping secrets out of source.Current transform
{{ summaryLine }}
The chart renderer is unavailable. Exact byte counts remain available in the transformation ledger.
| Signal | Value | Meaning | Copy |
|---|---|---|---|
| {{ row.label }} | {{ row.display }} | {{ row.detail }} |
JavaScript delivered to a browser or application remains available to the person running it. Obfuscation can replace meaningful names, move strings into encoded arrays, rewrite numbers, split literals, and rearrange some control flow so casual reading takes more effort. It cannot turn client-side code into a secret.
That boundary matters for API keys, passwords, signing material, authorization rules, licensed data, and fraud controls. Anything that must remain confidential or authoritative belongs on a trusted server. An obfuscated file can still be formatted, traced while it runs, instrumented, or analyzed until its behavior becomes clear.
- Deterrence raises the cost of casual copying or inspection.
- Compatibility depends on the target runtime and on which names outside code expects to reach.
- Overhead appears in file size, parse time, execution cost, build time, and debugging difficulty.
- Reproducibility requires the same source, profile, target, reserved names, global-renaming choice, seed, and engine version.
Public names are the most common break point. An HTML event attribute, another script, a test harness, a plugin host, or a string-based lookup may call a function by name. Renaming that identifier preserves the internal syntax but breaks the external connection unless the name is reserved or every caller is transformed together.
Obfuscation belongs late in a reviewed build, after syntax checks and automated tests. Keep readable source and source control as the authority, and test the generated file in the exact browser, service worker, or Node.js environment that will execute it.
How to Use This Tool:
Start with a working JavaScript file and the lightest profile that meets the deterrence goal.
- Paste JavaScript or load one JS, MJS, CJS, or text file up to 128 KiB. Compile TypeScript, JSX, or other syntax extensions to JavaScript first.
- Choose Light, Balanced, or Strong. Higher settings add denser string transforms and, for Strong, partial control-flow flattening.
- Select the real Runtime target. Browser without eval is the default for stricter Content Security Policy compatibility; browser, service worker, and Node.js targets use their own global handling.
- Keep the Deterministic seed fixed for repeatable output. Enter externally reached names under Reserved identifiers, one exact JavaScript identifier per line.
- Leave Rename global identifiers off unless the file is closed and every external entry point has been reserved. Fix any syntax message before changing profiles.
- Review the generated JavaScript, size ratio, target, seed, and reserved-name count. Run the complete test suite and a production-like smoke test before replacing or publishing an artifact.
Interpreting Results:
An output artifact proves that the source parsed and the selected transform completed within the safety limits. It does not prove equivalent behavior. Dynamic property access, external global calls, reflection, serialization contracts, stack-trace expectations, or environment-specific globals can still fail at runtime.
The expansion ratio compares UTF-8 bytes before and after transformation. A larger file is normal because string tables, decoding wrappers, and rewritten control flow add code. Compare the ratio across builds only when the source, settings, seed, and engine version are unchanged.
Reserved-name count confirms how many distinct exact identifiers were excluded from renaming. It does not discover names that should have been reserved. Build that list from public APIs, HTML attributes, plugin hooks, test entry points, and other code that reaches the file by name.
Technical Details:
Obfuscation parses JavaScript into a syntax tree, applies a pinned set of name, literal, string-array, simplification, and optional control-flow transforms, then emits compact JavaScript. The supplied program is parsed but not evaluated during this process.
Formula Core:
Size reporting uses UTF-8 bytes. The output must stay under both a hard 1 MiB ceiling and a proportional ceiling equal to the larger of 24 KiB or twenty times the source size.
A 10 KiB source may grow to at most 200 KiB under the proportional rule. A 500-byte source may grow to 24 KiB. Every output must also remain at or below 1,048,576 bytes.
Transformation Core:
| Behavior | Light | Balanced | Strong |
|---|---|---|---|
| Compact output and simplify syntax | On | On | On |
| Hexadecimal identifier names | On | On | On |
| String-array threshold | 55% | 80% | 100% |
| String-array encoding | None | Base64 | Base64 |
| Transform string-array calls | Off | 50% threshold | 75% threshold |
| Split strings | Off | 8-character chunks | 5-character chunks |
| Rewrite numbers as expressions | Off | On | On |
| Control-flow flattening | Off | Off | 40% threshold |
All three profiles shift, rotate, and shuffle string-array indexes and use one variable-style wrapper. Dead-code injection, debug protection, console disabling, property renaming, self-defending code, source maps, and domain locking remain off. The optional global-renaming switch is separate from the profile.
Rule Core:
| Input | Accepted rule | Failure condition |
|---|---|---|
| Source | Non-empty JavaScript no larger than 131,072 UTF-8 bytes | Empty, oversized, or invalid syntax |
| Seed | Integer from 1 to 2,147,483,647 | Non-integer, zero, negative, or out of range |
| Reserved names | Up to 50 distinct exact identifiers and 4,096 input characters | Invalid JavaScript identifier or excess count/length |
| Target | Browser without eval, browser, service worker, or Node.js | Unrecognized target |
| Output | Non-empty and below both size ceilings | Excessive transform growth |
The deterministic seed controls the engine's pseudorandom choices. Repeatability applies only while every input, option, and pinned engine/parser version remains the same.
Security and Privacy Notes:
The source is transformed in the browser and is not uploaded or executed by the obfuscation step. Local processing does not make the generated code trustworthy, private, or safe to run.
- Obfuscation is not encryption, access control, tamper-proofing, malware detection, or a security audit.
- Never place secrets or authoritative authorization decisions in delivered JavaScript.
- Global renaming and control-flow changes can break working code; test all public entry points and target-specific behavior.
- Keep readable source, build settings, the deterministic seed, and tests so the artifact can be reproduced and diagnosed.
References:
- JavaScript Obfuscator 5.4.3, javascript-obfuscator.
- Acorn 8.15.0 JavaScript parser, Acorn.