Preview state.
The
UseVMProtection flag is plumbed end-to-end and tier-validated today. The virtualizer itself activates in v3.2. Until then, requests with the flag set on Corporate or Enterprise tiers run successfully, return your standard Maximum-mode protected output, and include an engine warning in the response so you know the virtualizer did not run on this build.
See the
roadmap article for the full design and tradeoffs.
VM bytecode protection compiles selected functions to a per-build virtual-machine instruction set and ships a small JS interpreter to execute them at runtime. This is a different protection class from the static transforms in Maximum mode (encrypted constants, flat control flow, polymorphic decoder) — the virtualizer's output has no source-level structure left to recover, only opcodes that an attacker would have to reimplement the VM to follow.
What it changes
Functions you mark with the // @virtualize comment are removed from the output as readable JavaScript. They are replaced with bytecode (the opcode table is randomized per build) and a VM interpreter that loads, decodes, and dispatches those opcodes when the function is called. From the calling site, the function still has the same name and signature; from a static-analysis standpoint, the body is gone.
Functions you do not mark are processed normally by the rest of the Maximum-mode pipeline. You should not virtualize hot paths — see the When to use it guidance below.
API usage
Set the option on the obfuscation request:
{
"Items": [{ "FileName": "app.js", "FileCode": "..." }],
"EncryptStrings": true,
"FlatTransform": true,
"UseVMProtection": true
}
Mark functions to virtualize with a // @virtualize comment on the line above the function declaration:
// @virtualize
function validateLicense(userId, key) {
var hash = 0;
for (var i = 0; i < key.length; i++) {
hash = (hash * 31 + key.charCodeAt(i)) | 0;
}
return hash === userIdToHash(userId);
}
Functions without the marker are not virtualized. Auto-detection of license-validation patterns is on the roadmap but is not part of v3.2.
When to use it
- License validation, key derivation, anti-tamper checks — cold paths where the algorithm is the asset. The slowdown is irrelevant because they run rarely.
- Watermarking and fingerprinting routines — logic an attacker would otherwise lift wholesale.
- Small functions in the security perimeter — the VM cost is per-instruction; a 50-instruction function adds microseconds, not milliseconds.
When not to use it
- Rendering loops, animation tick handlers, hot network parsers — expect a roughly 80× per-instruction slowdown vs native execution. A virtualized 60-fps game loop will not stay at 60 fps.
- Functions called from
requestAnimationFrame or tight setTimeout loops — same reason.
async / await functions in v3.2 — the initial release skips async functions with a warning. Promise-chain transformation is a follow-up.
Per-build polymorphism
The VM interpreter is regenerated on every build. Opcode numbers are shuffled, dispatcher switch order is randomized, and the bytecode is XOR'd with a per-build key that the interpreter decodes inline. Two builds of the same source produce structurally different VM interpreters, so a deobfuscator that cracks one build does not get the second for free. This matches the per-build polymorphism the rest of Maximum mode already uses.
Honest limits
- VM protection raises the static reverse-engineering bar substantially. It does not stop runtime observation: a determined attacker can attach a debugger, log every dispatcher invocation, and reconstruct the bytecode-to-source mapping.
- VM-aware deobfuscators exist for some commercial obfuscators. Per-build polymorphism is the defense; but assume the technique is not a one-way function.
- Async/await is not supported in the v3.2 release. The pipeline detects async functions with the
// @virtualize marker and skips them with an engine warning rather than failing the build.
Tier availability
Available on Corporate ($49/mo) and Enterprise ($99/mo) plans. Free and Basic tier requests with UseVMProtection=true are rejected at validation time with a MissingPlanException identifying the required tier. The Free online tool is unaffected — the option is not exposed in the playground UI.
Choosing this vs alternatives
Three honest cases where another product is the right choice instead of (or alongside) UseVMProtection:
- You need runtime threat monitoring with live alerts. JSO does not collect runtime telemetry from your protected output. If active attackers are part of your threat model and you want a dashboard of attempted tampering events, pair Maximum mode with a runtime monitoring platform (Jscrambler, Verimatrix, Digital.ai). Their VM and your VM are not mutually exclusive — you can ship both.
- Your protected asset must survive determined professional reversers spending months on it. If you ship DRM keys for premium video, novel cryptographic constants, or anti-cheat heuristics that adversaries will burn weeks attacking, the heaviest enterprise VM products (WhiteCryption / Verimatrix Code Protection, Digital.ai Application Protection) are deeper than what JSO ships. They are sales-led, often six-figure annual contracts, but the depth is real.
- You only need free-tier obfuscation. The open-source
javascript-obfuscator npm package and its playground (obfuscator.io) cover name mangling, control-flow flattening, and string array encoding for free. They do not include bytecode VM, but if VM was not in your requirements, the free tool is the right baseline.
For the buyer-axis comparison (real opcode interpreter vs CFG flattening, per-build polymorphism, async support, pricing transparency), see VM Protection Across Vendors on the comparison page, and the named-vendor breakdown on the blog.
What you get today: the flag, the tier gate, and an engine warning in your response confirming the request reached the pipeline.
What ships in v3.2: the actual virtualizer, browser-bundled interpreter, polymorphic dispatcher, and async-skip behavior. If you would like to be in the v3.2 private beta, contact
[email protected].