JavaScript Obfuscator
Make JavaScript hard to read: renamed names, encoded strings, flattened control flow.
Options
Domain lock on
On any other site the script stops with an error. *.example.com also allows example.com itself. Leave empty for no lock. Not for Node.js code.
Obfuscation makes code hard to read, not secret: never put passwords or API keys in client-side code.
The input or options have changed since this result — obfuscate again to update it.
About the JavaScript Obfuscator
Paste JavaScript and get a version that runs the same but is much harder to read. The obfuscator renames local variables, functions and classes, moves string literals into an encoded array (Base64 or RC4), rewrites functions into a control-flow dispatcher, adds dead code that never runs and turns numbers into arithmetic — with Low, Medium and High presets, or each option on its own. A domain lock can stop the script on websites other than yours.
The transforms only change code they can rewrite without changing what it does: parts that call eval or use with, blocks with break or continue that leave them and similar cases are left as they are; top-level names of a classic script stay usable by other scripts; and the result is parsed again before you see it. TypeScript and JSX are compiled first. Everything runs in your browser, in a background thread — your code is never uploaded.
Obfuscation is not security. It deters casual reading and copying, but the browser must still be able to run the code, so a determined person can always work out what it does. Never put passwords, API keys or other secrets in client-side code, obfuscated or not.
How to use it
- Paste code, drop a file onto the box or press Open file (.js, .mjs, .cjs, .ts, .jsx, .tsx).
- Pick a preset — Low (new names and a plain string array), Medium (adds Base64 strings, flattening, dead code and number expressions) or High (RC4 strings and everything at full strength) — or open Options to set each transform.
- To lock the code to your sites, enter their host names under Domain lock (example.com, *.example.com).
- Press Obfuscate (Ctrl/⌘ + Enter), then copy or download the result — and test it before you ship it.
Examples
function greet(name) {
const message = 'Hello, ' + name;
return message;
}
console.log(greet('Asha'));function _0xc3a550(){var _0x1eff4b=["Asha","Hello, "];…}function _0x256b38(_0x1eff4b,_0xb0e282){…}function greet(_0x1eff4b){const _0xb0e282=_0x256b38(1022)+_0x1eff4b;return _0xb0e282}console.log(greet(_0x256b38(1023)));The strings now come from an array through a decoder function (shortened here). greet keeps its name because, in a classic script, top-level functions are globals other scripts may call. Medium and High also encode the array and flatten the function.
Common uses
- Making a widget, game or demo you publish on the web harder to copy and modify.
- Shipping a script to a client or a marketplace where you do not want the source to be read at a glance.
- Hiding string constants (messages, internal names) from casual reading of a bundle.
- Stopping a copied script from running on other websites with the domain lock.
What each option does
- Rename identifiers — local variables, parameters, functions, classes, private fields and labels get meaningless names (
_0x3f2a1c, or short letters), using Terser’s scope analysis. Object properties are never renamed, so your API, the DOM and libraries keep working. - String array — string literals move into one array and are read through a decoder function. Base64 and RC4 encode them (with an alphabet made for this file and a key per string), Rotate shifts the array, and Split strings first breaks long strings into pieces (at most 64 per string, so very long strings get longer pieces). Directives such as
'use strict', import paths, export names and object keys stay as they are. - Control-flow flattening — a function’s statements become cases of a
while/switchloop driven by a shuffled order string, so the order on the page no longer shows the order of execution. - Dead code —
ifblocks that can never run are added; they are copies of your own code with every name replaced, so they look real. - Numbers to expressions — integer literals become arithmetic such as
183*-12+2238. - Domain lock — a check at the top, and at the start of every top-level function, stops the script with an error (or first sends the visitor to an address you choose) unless the page’s host name is one you listed.
What changes and what stays the same
The obfuscated code does what the original does: each transform is tested on real programs and libraries (such as the Papa Parse CSV parser and jsdiff), which give the same results before and after. Some things change on purpose: function and class names (fn.name, constructor.name) unless you tick Keep function and class names; stack traces, which show the new names; and size and speed. On Papa Parse (51 KB) and jsdiff (111 KB), Low made the files smaller than the originals (comments and spaces go), Medium about 1.1–2.1× and High about 1.7–3.7× their size, depending on the seed; a short snippet grows more, because the decoder is added once.
Scripts, modules and global names
In a classic <script>, top-level functions and variables are globals that other scripts and HTML attributes (such as onclick) may call, so they keep their names unless you tick Rename global names. ES modules (code with import or export) keep their exported names, and everything else is renamed. Put names that must never change — for example a function called from HTML or by another file — under Names to keep.
Obfuscation is not security
Anything a browser can run, a person can study: the debugger, deobfuscation tools and patience undo every transform here. Use obfuscation to make reading and copying harder — not to hide secrets, licence checks you depend on or vulnerabilities. Keep API keys and logic that must stay private on a server, and keep your original source: obfuscated code cannot be turned back into it.
Limitations
- Obfuscated code is larger and slower. Avoid control-flow flattening for code in tight loops, animations or games, and measure before you ship.
- One file at a time, up to 3 MB: it does not bundle, so obfuscate the final file your build produces.
- No source maps: errors in obfuscated code point to the obfuscated lines.
- No anti-debugging, self-defending or console-blocking tricks — they make pages fragile and do not stop a determined person.
- Code that reads its own source (
Function.prototype.toString) or local names throughevalkeeps working only where the obfuscator leaves it unchanged; it skips flattening and dead code in files that calleval(…)directly or usewith. - Control-flow flattening declares a block’s
letandconstnames at its start. Blocks that assign to aconst, or read such a name before its declaration (directly or through one of the block’s functions), are left alone; in rarer cases — the function is reached another way, such as through an object or a callback — that early read givesundefinedinstead of the ReferenceError the original throws. - TypeScript and JSX are compiled with Sucrase first, without type checking.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
Is obfuscated JavaScript secure?
No. It is harder to read, not impossible: the browser has to be able to run it, so anyone can step through it in developer tools or run it through a deobfuscator. Never rely on it to protect passwords, API keys or licence checks.
Will the obfuscated code still work?
It is designed to do exactly what the original does, and the parts it cannot rewrite safely are left unchanged. Still test the output before you ship it and keep your original source — especially if your code uses eval, with or Function.prototype.toString, or reads function names.
What do Low, Medium and High change?
Low: new names and 75% of strings moved to a plain array. Medium: all strings in a Base64-encoded array (long ones split into 10-character pieces), 75% of blocks flattened, dead code in 40% of blocks and numbers as expressions. High: RC4-encoded strings split into 5-character pieces, every eligible block flattened, dead code in 60% of blocks and numbers as expressions.
Why are my top-level functions not renamed?
In a classic script they are global, and other scripts or HTML attributes may call them by name. Tick Rename global names if nothing outside the file uses them, or obfuscate the code as an ES module.
What does the domain lock do?
It adds a check that reads location.hostname when the script starts and again whenever one of its top-level functions is called, so other scripts on a copied page cannot use them either. On a host that is not on your list it throws an error — after sending the visitor to your redirect address, if you gave one. "*.example.com" also allows example.com and every subdomain. It cannot work outside a browser (Node.js), and someone who edits the code can remove it.
Can I get exactly the same output again?
Yes. The result shows the seed it used; enter that seed under Options with the same code and settings to reproduce the output exactly.
How is this different from minifying?
A minifier makes code smaller and renames local names on the way, but formatting it again makes it readable. Obfuscation adds transforms that keep the code hard to follow even when formatted, at a cost in size and speed. Use the JavaScript Minifier when you only want smaller files.
Is my code uploaded?
No. The obfuscator runs in your browser in a background thread, and the page works offline once it has loaded. Nothing you paste or open leaves your device.