JavaScript Obfuscator

A customer opens DevTools, finds your licence check sitting in readable source on line 40, and deletes the branch. Obfuscation rewrites the file so nobody does that in a lunch break. Paste your code, pick how hard to push, and watch what the hardening costs in bytes.

  1. Paste the source you ship

    Use the built file, not the module you author. Obfuscating pre-bundle output leaves the bundler free to strip your protection.

  2. Choose how far to push

    Each profile trades readability for size and speed. Start low, raise the setting only when the code guards something worth the overhead.

    Controls how many eligible statements each transform touches. Level 5 rewrites nearly everything, which is where slow loops start to show.

    Individual transforms and what each one costs
  3. Check the cost, then take the file

    Parse check compiles the output without running it, which catches a transform that mangled your source into something the engine rejects.

    0 BSource size
    0 BOutput size
    1.0xGrowth
    0Transforms on

    Load the sample or paste your own code, then run the obfuscator.

Obfuscation raises the price of reading your code. It is not a lock.

Anything the browser runs, the browser can show. Obfuscation changes how long that takes and how much patience the reader needs. A student poking at your pricing widget gives up in ten minutes. Someone paid to break your licence check still gets there, with a debugger and an afternoon.

That split matters when you decide what to put in the file at all.

What the cost increase covers

  • Casual source reading by a curious user with view-source open.
  • Copying a scoring formula or pricing rule straight out of your bundle.
  • Deleting a licence branch by searching for the words in the error message.
  • Scrapers that pull endpoint paths out of thousands of sites by pattern match.

What stays exposed either way

  • Every network request your code makes, sitting in the Network tab with headers.
  • API keys inside the file. A breakpoint on the fetch call prints them decoded.
  • Runtime behaviour. Values pass through the console the moment a reader sets a watch.
  • Business logic worth real money, given a reader with the right tooling.

Rule of thumb: any secret that must stay secret belongs behind a server endpoint. Obfuscate the client to slow readers down, never to store something you cannot afford to lose.

What each transform costs you

The defaults on this page favour a small file. Turn things on deliberately, because the expensive transforms are also the ones users feel.

TransformEffect on the fileSizeRuntimeEffort to reverse
Compact outputRemoves whitespace and newlinesSmallerNoneSeconds
String arrayLiterals move into one indexed arraySlight growthNegligibleScriptable
Base64 encodingArray entries stop reading as textAround 33 percent on stringsSmall, cachedScriptable
RC4 encodingArray entries decrypt per lookupSimilar to base64Felt in hot loopsScriptable with effort
Control flow flatteningBlocks become a switch dispatcherUp to doubleAround 1.5x slowerHours by hand
Dead code injectionUnreachable branches interleave with yoursUp to 200 percentParse time onlyDetectable by tooling
Self defendingFormatting the output breaks itSmallNoneBlocks the lazy route
Debug protectionDevTools triggers a stall loopSmallTimer always runningBlocks the lazy route

Read the reverse effort column next to the size column before turning everything on. Compact output and the string array give most of the practical benefit for a fraction of the weight. Control flow flattening is where a 40 KB widget turns into 90 KB.

Picking a profile that matches what you are guarding

Light, for embeds and widgets
A chat bubble or analytics snippet loading on customer sites. You still need to read stack traces from bug reports, and every kilobyte lands on someone else's page budget. Renaming plus a string array is the ceiling here.
Balanced, for licence gates and paid features
The code checks a token and unlocks a feature. Base64 strings stop a text search for the flag name, and partial flattening makes the branch tedious to trace. Growth near 2x is acceptable on a file loaded once behind a login.
Hardened, for algorithms you sell
A pricing engine, a game client, a scoring model shipped to browsers. Take the 4x growth and the slower loops on purpose. Test on a mid-range phone before you accept it, since flattening plus RC4 shows up on weaker CPUs first.

One function, before and after

Light settings on a short check. Note what survives: the shape of the call is gone, the strings are gone from plain view, the network path is not.

Source
function hasLicence(user) {if (user.plan === "pro") {return true;}
console.log("upgrade required");return false;}
String array, base64
function _0x3f1a(_0x4c2e){var _0x1b=_0x2d7f;if(_0x4c2e[_0x1b(0x1a2)]===_0x1b(0x1a3))return!![];console[_0x1b(0x1a4)](_0x1b(0x1a5));return![];}

The identifiers are gone for good. The behaviour is identical, including the request that follows. A reader who sets a breakpoint on the return still learns the answer in one step, which is the honest limit of every client side check.

Checks to run before the output ships

  1. Parse the result. The button above compiles the output without executing it. A failure here means a transform hit syntax the obfuscator mishandled, usually decorators or unusual class fields.
  2. Click every path in a real page. Parsing proves nothing about behaviour. Code reading fn.name, comparing Function.prototype.toString output, or resolving a handler by string name breaks under renaming and stays quiet until a user hits it.
  3. Never obfuscate twice. Running output back through the tool compounds the size and occasionally produces code the engine rejects.
  4. Do not minify afterwards. Minify first, obfuscate second. Self defending exists to break exactly that reordering.
  5. Keep the original in version control. Obfuscated output is not editable. Your next patch starts from the source, always.
  6. Decide about source maps. Shipping one alongside obfuscated code hands back everything you removed. Generate maps for your error tracker, keep them off the public path.

Where obfuscating is the wrong call

Your source stays in this tab

The obfuscator library loads into the page and runs on your machine. No request carries the code anywhere, so proprietary logic, internal endpoints and half-finished work stay local. The text lives in the editor until you reload, so clear both panels when you finish on a shared machine.

Questions about obfuscating JavaScript

Limits, breakage, performance and what to run alongside this page.

Can obfuscated JavaScript be reversed?

Yes, with time. Public deobfuscators undo string arrays and simple renaming almost instantly. Control flow flattening resists automation and takes a person hours to unpick. Original variable names never come back, which is the one change nothing reverses.

Does obfuscation slow my page down?

Compact output and string arrays cost close to nothing. Control flow flattening runs around 1.5 times slower than the original per the library documentation, and RC4 string encoding adds work on every literal lookup. Both matter inside loops and barely register in event handlers.

Should I minify before or after obfuscating?

Minify first, then obfuscate. Running a minifier over obfuscated output can strip the protection and will break code built with self defending enabled.

Why did my code stop working after obfuscation?

Usual causes are renaming globals that outside scripts call by name, code reading a function name at runtime, string based lookups into your own objects, and eval on identifiers the tool renamed. Turn off rename globals first, then reintroduce transforms one at a time until the failure returns.

Is obfuscation enough to protect an API key?

No. A key in client code is readable through the Network tab regardless of how the file looks. Move the call to a server endpoint and keep the key there.

How much bigger will my file get?

Light settings land near 1.2 times the input. Adding control flow flattening pushes toward double. Dead code injection alone can add 200 percent. The growth readout on this page reports the exact figure for your file and settings.

Does the tool support ES6 modules and modern syntax?

Classes, arrow functions, async and await, optional chaining and template literals all process cleanly. Import and export statements pass through untouched, so bundle first if you want those inlined. TypeScript needs compiling to JavaScript before it comes here.

What does debug protection actually do?

It runs a timer that traps execution when DevTools is open, stalling the tab. Support engineers on your own team hit the same wall, and browser behaviour has varied across versions, so test in every browser you claim to support before enabling it.