{"_id":"@al007ex/jscvm","name":"@al007ex/jscvm","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@al007ex/jscvm","version":"1.0.0","description":"JavaScript-to-bytecode virtualizing obfuscator with a bundled emulator (VM).","publishConfig":{"access":"public"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":"./dist/index.js","./webpack":"./dist/webpack.js"},"engines":{"node":">=16"},"scripts":{"_test":"echo \"Error: no test specified\" && exit 1","dev":"nodemon","start":"node scripts/run-cli.js","clean":"rm -fr dist","compile":"node scripts/run-cli.js","transpile":"babel input/in.js --out-file input/in.js --presets babel-preset-es2015","build":"npm run clean && tsc && tsc --project tsconfig.EmulatorTemplate.json && npm run bundle:esm","bundle:esm":"rollup dist/EmulatorTemplate/Emulator.js --file dist/EmulatorTemplate/EmulatorTemplate.js --format iife --name bytecodeVm","prepublishOnly":"npm run build"},"keywords":["obfuscator","obfuscation","vm","virtual-machine","bytecode","webpack-plugin","javascript"],"repository":{"type":"git","url":"git+https://github.com/al007ex/jscvm.git"},"homepage":"https://github.com/al007ex/jscvm#readme","bugs":{"url":"https://github.com/al007ex/jscvm/issues"},"author":{"name":"al007ex"},"license":"ISC","dependencies":{"@babel/core":"^7.29.7","@babel/plugin-transform-block-scoping":"^7.29.7","acorn":"^8.4.1","babel-plugin-transform-async-to-promises":"^0.8.18","escodegen":"^2.0.0","estraverse":"^5.2.0","javascript-obfuscator":"^4.1.1","terser":"^5.7.2"},"peerDependencies":{"webpack":"^5.0.0"},"peerDependenciesMeta":{"webpack":{"optional":true}},"devDependencies":{"@types/acorn":"^4.0.6","@types/estraverse":"^5.1.1","@types/node":"^16.7.2","babel-cli":"^6.26.0","babel-preset-es2015":"^6.24.1","nodemon":"^2.0.12","rollup":"^2.56.3","ts-node":"^10.2.1","typescript":"^4.3.5"},"_id":"@al007ex/jscvm@1.0.0","gitHead":"6eb323ad1c2f1ac41f307ce83dd134be211be3f1","_nodeVersion":"23.11.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-GtjLzmWTJmt9zB5blgL+SQNW5E3MMNFi8+qACpKYZohNb1pqtmJe3N1OR4ZTS11M25vQMBJQRO7kTtDJuquhlg==","shasum":"5570b870c4bddf4b55eb185ef30d939742fd3254","tarball":"https://registry.npmjs.org/@al007ex/jscvm/-/jscvm-1.0.0.tgz","fileCount":37,"unpackedSize":295809,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAfzOrYreIPyJTwah/AejKYYufRqw/t9C+Q4shCXQ1/DAiBhRykCt8/c/6YbtivZ10ElAv/kWJST/wWodvUo8QUq3g=="}]},"_npmUser":{"name":"al007ex","email":"alex.arn2006@icloud.com"},"directories":{},"maintainers":[{"name":"al007ex","email":"alex.arn2006@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/jscvm_1.0.0_1785086720282_0.6221620897925619"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T17:25:20.034Z","1.0.0":"2026-07-26T17:25:20.424Z","modified":"2026-07-26T17:25:20.585Z"},"maintainers":[{"name":"al007ex","email":"alex.arn2006@icloud.com"}],"description":"JavaScript-to-bytecode virtualizing obfuscator with a bundled emulator (VM).","homepage":"https://github.com/al007ex/jscvm#readme","keywords":["obfuscator","obfuscation","vm","virtual-machine","bytecode","webpack-plugin","javascript"],"repository":{"type":"git","url":"git+https://github.com/al007ex/jscvm.git"},"author":{"name":"al007ex"},"bugs":{"url":"https://github.com/al007ex/jscvm/issues"},"license":"ISC","readme":"# jscvm\n\ntakes your javascript, compiles it down to bytecode, and ships it inside a tiny VM that runs it. so your actual logic never shows up as readable JS in the output, it's just encrypted bytecode that only the bundled interpreter knows how to run.\n\nheads up before anything else: this is obfuscation, not encryption. someone patient with devtools can still pull it apart at runtime. the whole point is just to make that really annoying.\n\n## how it works\n\n```\nsource -> lower (babel) -> parse (acorn) -> scope analysis -> bytecode\n       -> encrypt + base64 -> embed in the emulator -> terser + javascript-obfuscator\n```\n\na few things happen on every build:\n\n- your code gets compiled to bytecode for a custom stack machine\n- the whole bytecode blob (strings included) gets encrypted, and the key isn't stored anywhere. the VM rebuilds it at runtime from a hash of the payload, so if someone patches the bytecode or the handler table it just decrypts to garbage. there's no `if (tampered)` check to find and delete\n- opcodes get shuffled every build, then the emulator itself gets minified and run through javascript-obfuscator on top\n\n## install / build\n\n```bash\nnpm install\nnpm run build\n```\n\n## cli\n\n```bash\nnpm run compile -- --input path/to/source.js --out ./out\n```\n\nflags are `-i/--input`, `-o/--out`, `--no-minify` (skips the slow obfuscator pass) and `-h/--help`. you get back `<name>.bytecode.js`, plus `<name>.bytecode.min.js` unless you passed `--no-minify`.\n\n## node api\n\n```js\nconst { obfuscate } = require(\"@al007ex/jscvm\");\n\nconst code = await obfuscate(source, { minify: true });\n```\n\ngives you back a self-contained bundle. it exposes the program's return value on `globalThis.vm` and `module.exports`.\n\nif you want it fast, pass `minify: false`. that skips the heavy obfuscator pass but the bytecode is still encrypted.\n\n## webpack\n\n```js\nconst { JSCVMWebpackPlugin } = require(\"@al007ex/jscvm/webpack\");\n\nmodule.exports = {\n  plugins: [\n    new JSCVMWebpackPlugin({\n      test: /\\.js$/,       // which assets to hit\n      minify: true,\n      maxBytes: 512 * 1024,// skip anything bigger than this\n      cache: true          // don't recompile stuff that didn't change\n    })\n  ]\n};\n```\n\nit runs on the final built assets, does them in parallel, and caches by content hash so watch rebuilds aren't painful. if it hits something the VM can't compile, it leaves that asset alone and drops a build warning instead of blowing up your build.\n\nusing rollup / esbuild / vite instead? there's nothing special in the plugin, just call `require(\"@al007ex/jscvm\").obfuscate(code)` inside whatever transform hook they give you.\n\n## what actually works\n\n`var` / `let` / `const`, functions, arrow functions (with proper lexical `this`/`arguments`), closures, recursion, `if` / ternary, `for` / `while` / `do…while` / `switch`, `break` / `continue`, `try`/`catch`/`finally` (including `return`/`break` through a finally), `throw`, all the operators plus `++`/`--` and every compound assignment (`+=` through `**=`, `<<=`, etc), object/array literals with computed/string/number keys, shorthand, methods, getters/setters, member access, calls, `new`, `async`/`await`, regex, `typeof`/`delete`/`void`/`in`/`instanceof`, and `arguments`.\n\nanything it doesn't support yet just errors at compile time instead of silently doing the wrong thing. check the roadmap for what's still missing.\n\n## when to use it, and when not\n\nuse it for hiding small bits of client-side logic you'd rather people didn't read. protocol or codec internals, license checks, anti-cheat helpers, that kind of thing.\n\ndon't use it for:\n\n- anything that actually needs to be secure. this is obfuscation, not crypto\n- storing secrets or api keys, they're always recoverable at runtime\n- hot paths or tight loops, everything runs through an interpreter so it's slower than plain JS. wrap the boundaries, not your render loop\n- code that uses stuff it doesn't support yet, it'll just fail to compile\n\n## performance\n\nmost of the build time is the obfuscator pass, so `minify: false` is a lot faster when you don't need it. the webpack plugin caches, skips big files, and runs assets in parallel. runtime is slower than native since everything's interpreted, that's the tradeoff you're making.\n\n## roadmap\n\n**language, soon-ish**\n- [ ] template literals\n- [ ] optional chaining `?.`, nullish `??`, logical assignment `??=` / `&&=` / `||=`\n- [ ] spread (calls, arrays, objects)\n- [ ] rest & default params\n- [ ] `for…of` / `for…in`\n\n**language, later**\n- [ ] destructuring (declarations, params, assignment)\n- [ ] labeled statements + labeled `break`/`continue`\n- [ ] tagged templates, BigInt literals\n- [ ] classes / `extends` / `super`\n- [ ] generators (`yield`), async generators, `for await`\n- [ ] ES modules (`import`/`export`)\n\n**obfuscation hardening**\n- [x] per-build opcode shuffling\n- [x] position-keyed bytecode + string encryption\n- [x] checksum-as-key (tamper it and it decrypts to garbage, no branch to strip)\n- [x] native ref capture + frozen dispatch table\n- [ ] superinstructions / handler polymorphism\n- [ ] junk/dead bytecode + opaque predicates\n- [ ] branchless VM-level anti-debug\n- [ ] encoded value domain (transform values on the stack)\n\n**tooling**\n- [x] cli, node api, webpack 5 plugin\n- [ ] rollup / esbuild / vite adapters\n- [ ] worker threads for big builds\n\n## about the security\n\nsaying it one more time since it matters: obfuscation, not cryptography. anyone with the runtime can trace or step through the emulator if they really want to. all the per-build stuff raises the effort, it doesn't make extraction impossible. don't put long-lived secrets in here.\n\n## layout\n\n`src/` has the parser, scope analysis, codegen, emulator, transpile pass, cli and webpack plugin. `dist/` is the build output. `scripts/` has the cli runner and a little dev server.\n","readmeFilename":"README.md","_rev":"1-6a2da0d83f3b49a416c26781adf88b0c"}