JavaScript Deobfuscator

Unwrap eval("...") strings with hex and Unicode escapes to see the JavaScript underneath.

Obfuscated JavaScript
Decoded
Runs locally in your browser

About the JavaScript Deobfuscator

A common lightweight obfuscation wraps a script in eval() with every character escaped. Browsers decode it at runtime, and so can you: this tool recognises the wrapper, decodes the escape sequences, and shows the original source. It handles \xNN and \uNNNN escapes and standard string escapes such as \n.

Each run peels off one layer. Obfuscators regularly nest an eval inside the string the outer eval produces, so the first pass often reveals more escaped source rather than readable code; feed the output back in until the escapes stop appearing. The decoding is pure string manipulation and nothing is ever executed, so pasting a script pulled from a suspicious page or an email attachment to see what it would have done carries no risk.

What it does not do is undo real obfuscators that rename identifiers, hide every literal in a shuffled lookup array, or flatten control flow into a dispatch loop. Packed code of the p,a,c,k,e,d variety falls in the same category. Those need manual tracing or a dedicated deobfuscator, and no amount of unescaping will recover the original variable names, which are simply gone.

After decoding, the result is usually still minified onto one line. Run it through the JavaScript Formatter for readable layout, and use JavaScript Unescape when you have a bare escaped string with no eval wrapper around it.

How to use

  1. Paste the eval-wrapped code.
  2. Read the decoded source on the right.
  3. Format it with the JavaScript Formatter if it is minified.

Common questions

Does it run the code?
No. It only decodes the string inside eval. Nothing executes.
It says only eval wrappers are supported. What else can I do?
For packed code (p,a,c,k,e,d) or string-array obfuscation, format the code first and trace the decoding function by hand, or use a specialised deobfuscator.
Can it decode nested evals?
Run it again on the output; each pass removes one layer.