VM · Bytecode Virtualization Protection Engine

Compile JavaScript into
unreadable VM bytecode

Layered JavaScript protection with string encryption, OLLVM-style control-flow flattening, and custom VM bytecode. Unsupported syntax is safely downgraded to strong obfuscation so runtime behavior stays compatible.

68+VM opcodes
3protection layers
0compatibility loss
$1per use, no subscription
Sourcelicense.js
function checkLicense(key) {
  if (key === "SK-PROD-2024") {
    return true;
  }
  return false;
}
VM compile
Protectedlicense.protected.js
var _0x4f2a=_0x8b91(0x1a);function _0x2c91(_0x3d){var _0x1e=[0x53,0x4b];while(!![]){switch(_0x4f2a(0x1a3)){case 0x7:if(_0x3d===_0xe4(0x2b1,0x7))return _0x4f2a(0xff);case 0x21:return _0x4f2a(0x100);}}}
Source file .js / .mjs / .cjs · free ≤ 10 KB · up to 50 MB for $1/use

Free: string encryption, control-flow flattening, identifier renaming, dead-code injection — files up to 10 KB, no bytecode VM. Max Security (bytecode VM , domain lock, files up to 50 MB) is $1 per use — no subscription, no bundles, no seat minimums.

Drop a file here or browse
Any JavaScript file is supported
Domain lock applies when a VM runtime is emitted. If no function can be virtualized, the result will show a warning.
Advanced options
Turn this off if the code only ever runs inside a controlled V8/Node environment (not a browser) — anti-debug and sandbox checks target browser DevTools and headless-browser signals, and can be unnecessary or overly strict outside a browser context.
Protected output
{ }
Protected code will appear here
Protection pipeline

Three layers, escalating resistance

01

String encryption

String literals are moved into an encrypted constant pool and decoded on demand. Original strings no longer appear as readable text.

02

Control-flow flattening

Function bodies are split into basic blocks and rebuilt as a switch(state) dispatcher with opaque flow noise.

03

Bytecode virtual machine

Eligible functions are compiled into custom opcodes and executed by a stack VM, hiding logic behind a randomized dispatcher.

Anti-debug response

Detects timing anomalies, headless automation, patched natives, and suspicious runtime environments.

Environment checks

Screens jsdom, Headless Chrome, Puppeteer, Selenium, and other analysis environments.

Domain lock

Bind protected output to approved hostnames. Fail-closed mode blocks unknown execution contexts.

Encrypted bytecode

Uses compact binary payloads, lazy function chunks, derived keys, and integrity checks instead of readable JSON IR.

HTML integration

Mixed HTML and annotation markers

Inline events such as onclick, external scripts, and global APIs often call functions by name. Use /* @public */ to preserve exported names and /* @VM */ to prioritize VM protection for sensitive functions.

index.html
html · javascript
Mark functions referenced by HTML attributes or external code with /* @public */. Add /* @VM */ to force a VM attempt for sensitive logic.
@public / @VM usage guide and examples
@public
/* @public */ function myFunction(){
  // Function name is preserved for onclick.
  return compute();
}

Preserves an exported name so renaming does not break onclick="myFunction()", external scripts, or window.x calls. Internal variables are still obfuscated.

@VM
/* @VM */ function score(a, b){
  return (a ^ b) + 123;
}

Forces a VM attempt for the marked function. csp-safe and compat still perform safety checks; unsafe cases are downgraded with a warning.

@public + @VM
/* @public @VM */ function submitForm(){
  return protectedSubmit();
}

They can be combined. @public preserves the name; @VM forces a VM attempt. The two rules do not conflict.

Recommended syntax

/* @public */ function exportedApi(){ return 1; }

/* @public */ const exportedFn = function(){ return 2; };
/* @public */ const exportedArrow = (x) => x + 1;

/* @VM */ const core = function(x){ return x * 7; };

/* @public @VM */ const publicCore = function(x){
  return core(x) + 1;
};

Place markers before function declarations or variable declarations. The recommended syntax is the same for @public and @VM.

Mixed HTML example

<button onclick="submitForm()">Submit</button>
<script>
/* @public @VM */ function submitForm(){
  var token = buildToken();
  console.log(token);
}

/* @VM */ function buildToken(){
  return Date.now() ^ 0x5a5a;
}
</script>

submitForm is referenced by an HTML string, so it needs @public; it can also use @VM. Internal algorithm buildToken is not called by HTML directly, so @VM is enough.

Notes

@public does not reduce protection strength; it only preserves an externally visible name. @VM forces an attempt, not an unsafe compile. In allowEval=false profiles, functions capturing outer local variables may be downgraded with a warning. Prefer declaration-level markers, not markers in the middle of return statements.