Paste JavaScript and copy an obfuscated version that runs with the same result: local names renamed, strings hex-escaped, member access in brackets, comments removed.
Runs locally in your browserPaste JavaScript and the tool returns the same program with local names renamed, string literals written as \xNN and \uNNNN escapes, dotted property access turned into bracket notation, and comments removed. The code keeps running with the same result; everything is processed in this browser tab and nothing is sent anywhere.
This is obfuscation to make casual reading harder, not encryption. The logic is still in there, so do not rely on it to hide API keys or business rules, and keep the readable original: debugging the output by hand is unpleasant.
Comments are removed but line breaks stay, so deleting a // note can never swallow the following line. Identifiers declared inside the pasted snippet — variables, functions, parameters, classes, catch bindings — are renamed to short generated names through the scope chain; names that come from outside, including globals, stay unchanged.
String literals are rewritten character by character as \xNN or \uNNNN escapes, and a "use strict" directive is left as written. Dotted member access turns into bracket access: console.log becomes console["\x6c\x6f\x67"], and optional chaining follows the same rule (a?.b becomes a?.["b"]). After new and import the syntax is left alone, and #private fields are not touched.
Not encryption, not minification. Obfuscated strings get longer rather than shorter, and a determined reader can still follow the logic — the point is to discourage skimming and copying, not to make reversal impossible.
It is a single pass over the code, not a bundler: imports are not resolved, modern syntax is not transpiled, and nothing about how the file is loaded changes. Pasting the same script twice produces different outputs because the generated names are seeded from the source; fine for distribution, unhelpful for comparing builds.
The output is tested to return the same values as the input: classes, arrow functions, template literals with nested ${} expressions, async/await, spread, optional chaining, nullish coalescing and regex literals all pass. Module code keeps its import and export names, so it still loads as a module.
Scripts that use eval or with are not renamed — skipping renaming is the only safe choice there — though escaping and bracket conversion still apply. A file of around 80 KB processes in a few tens of milliseconds, and an already obfuscated script can be obfuscated again if you want a second pass.