Generate a starter config
Use the migration command to convert a common javascript-obfuscator JSON or trusted CommonJS config file into a starter jso.config.json. The command maps familiar options where possible, lists review items for settings that are not one-to-one, reports source option, mapped, review-only, unmapped, and automatic coverage counts, then prints the next validate, dry-run, doctor, release-check, competitor-gap, and protect commands. When any review-only item is present, it also prints the migration-review next command. When source-map review items are present, it prints the post-protect source-map-evidence next command. When identifier cache, custom dictionary, or runtime-defense review items are present, it also prints the identifier-cache-review or runtime-defense-review next command so focused source-free replacement packets are not missed.
jso-protector --migrate-javascript-obfuscator javascript-obfuscator.json --output jso.config.json
jso-protector --migrate-javascript-obfuscator javascript-obfuscator.config.cjs --output jso.config.json
jso-protector --config jso.config.json --validate-config --json
Use JSON output when internal tooling needs the generated config plus the per-config summary, mapped options, review items, and unmapped option lists.
jso-protector --migrate-javascript-obfuscator javascript-obfuscator.json --json
CommonJS source configs execute as Node.js code, so only migrate configs from your own repository or another trusted source.
Simple package scripts can also keep familiar CLI flags while moving to the hosted API workflow.
jso-protector src/app.js
jso-protector dist --output dist-protected --options-preset high-obfuscation --control-flow-flattening --string-array-encoding rc4 --reserved-names "^PublicApi$"
For direct single-file scripts, jso-protector src/app.js writes src/app-obfuscated.js when no --output or config output is set. Folder and config-file workflows keep using the configured output folder, usually dist-protected.
Mapped compatibility flags include --options-preset, --parse-html, --string-array, --string-array-encoding, --unicode-escape-sequence, --control-flow-flattening, --dead-code-injection, --dead-code-injection-threshold, --identifier-names-generator, --rename-globals, --rename-properties, --reserved-names, --domain-lock, --target, --compact, --self-defending, and --debug-protection. The last two map to the hosted SelfDefending and DebugProtection runtime guards. parseHtml protects marked inline HTML scripts when paired with <script data-javascript-obfuscator>. --options-preset default and low-obfuscation map to standard, medium-obfuscation maps to balanced, and high-obfuscation maps to maximum.
stringArrayIndexShift maps approximately to native StringArrayIndexShift. Enabling it adds a deterministic nonzero one-slot offset to plain and encrypted string tables. It does not reproduce the competitor's randomized shift magnitude, so test the protected build in its target runtime.
stringArrayShuffle maps directly to native StringArrayShuffle. It randomizes unique moved-string order and rewrites every lookup before plain or encrypted table emission. Default builds use fresh entropy; supplying Seed makes the shuffled artifact reproducible.
stringArrayRotate maps directly to native StringArrayRotate. Multi-value tables receive a nonzero cyclic offset chosen per build, with every lookup rewritten. Rotation composes with shuffle, shifting, and encryption and is reproducible under Seed.
stringArrayIndexesType maps directly to native StringArrayIndexesType. Both hexadecimal-number and hexadecimal-numeric-string are supported, including mixed lists. Numeric strings are explicitly coerced before array access; mixed selection is reproducible under Seed.
stringArrayThreshold maps directly to native StringArrayThreshold. Values from 0 through 1 make one stable decision per unique eligible literal; zero moves none, one moves all, duplicate literals stay consistent, and partial selection is reproducible under Seed.
stringArrayCallsTransform and its 0-1 threshold map directly to native secondary index-table indirection. Selected calls become nested lookups, the enabled default is 0.5, and Seed makes per-call selection reproducible. It composes with shifting, shuffle, rotation, encryption, index representations, and compression.
Wrapper type, chaining, and parameter controls map directly to bounded native wrappers: variable aliases or functions, 2-5 function parameters, and optional predecessor chains. Count maps approximately to 0-10 root-level wrappers because JSO does not reproduce the competitor's per-function-scope placement. Seed makes wrapper selection and noise arguments reproducible.
transformObjectKeys maps approximately to native safe data-key transformation. Identifier and quoted data keys become computed moved-string lookups. Numeric keys, methods/accessors, shorthand-sensitive members, and __proto__ remain literal so property and prototype semantics do not change.
--debug-protection-interval, --disable-console-output, --domain-lock-redirect-url, --seed, --reserved-strings, --force-transform-strings, --split-strings, and --split-strings-chunk-length map directly. String splitting uses fixed chunks of 1-1024 characters (default 10) while preserving directives, reserved literals, object keys, template segments, import/require specifiers, mixed-server markers, and Unicode surrogate pairs. String-array shuffle, rotation, index representation, call indirection, wrapper type/chaining/parameter controls, and thresholds map to native controls; index shift, wrapper count, and safe object-key transformation retain documented approximation boundaries. --numbers-to-expressions maps approximately to native EncodeNumbers. Source-map, identifier-cache, rename-mode, simplify, and strict-mode workflow fields remain review-only and require release-policy review.
Quoted class method, accessor, and field names remain literal because class definition grammar does not accept concatenation expressions in those positions.
For JS-Confuser, lock.antiDebug, lock.integrity/lock.selfDefending, lock.startDate, and lock.tamperProtection map approximately to native DebugProtection, SelfDefending, LockStartDate, and AntiMonkeyPatching. Numeric probability values collapse to enabled/disabled switches, so protected-browser validation remains required. Arbitrary countermeasure functions and custom locks remain review-only and are never executed by migration tooling.
JS-Confuser stringSplitting maps approximately to native SplitStrings. Boolean values map directly; numeric probabilities greater than zero enable fixed-length splitting. Custom selector functions remain review-only and are never executed by migration tooling.
When the migration report lists any review-only items, run the all-up migration review first. It gives release owners one source-free checklist across source-map policy, identifier-cache replacement, runtime-defense behavior, CLI compatibility warnings, saved report/manifest readiness, follow-up commands, and protected-build smoke evidence.
jso-protector --config jso.config.json --migration-review \
--migration-review-output reports/migration-review.md
The migration review packet includes a Migration Review Assistant for BYO AI or internal reviewers. It turns manual review tracks, source-map policy, identifier-cache replacement, runtime-defense behavior, source-reading command boundaries, release metadata, and protected-build smoke into owner actions. The packet names field groups and actions, but omits source code, protected output, source-map contents, cache contents, dictionary values, prefixes, domains, URLs, dates, seed values, reserved expressions, raw config files, API credentials, provider keys, customer data, and secrets.
For projects that previously depended on deterministic identifier-name cache reuse or custom naming dictionaries, generate a source-free replacement packet before release approval. It turns the old cache assumption into review evidence: reserved-name rules, saved API report, release manifest, and protected-build smoke results.
jso-protector --config jso.config.json --identifier-cache-review \
--identifier-cache-review-output reports/identifier-cache-review.md
The identifier-cache packet includes an Identifier Cache Review Assistant for BYO AI or internal reviewers. It names the review-only fields and counts but omits cache contents, dictionary values, prefixes, reserved-name expressions, source code, raw config files, API credentials, provider keys, customer data, and secrets.
For projects that previously generated or referenced source maps during protected releases, keep the post-protect source-map evidence packet beside the manifest. It proves the protected artifact still matches the manifest and does not expose .map files or sourceMappingURL comments.
jso-protector --source-map-evidence dist-protected/jso-manifest.json \
--source-map-evidence-output reports/source-map-evidence.md
The packet includes a Source Map Review Assistant for BYO AI or internal reviewers. It gives release owners questions for leak cleanup, manifest verification, secure debugging exceptions, bundler cleanup order, and clean handoff without sharing raw maps, source-map contents, original source paths, source code, protected output, customer data, or secrets.
For projects that previously depended on anti-debug, self-defending, runtime lock, console, and countermeasure behavior, generate a source-free runtime-defense packet before release approval. It turns those migration settings into monitoring target, customer-owned forwarding, countermeasure policy, domain/date lock, release metadata, compatibility scan, and protected-build smoke-test review tracks.
jso-protector --config jso.config.json --runtime-defense-review \
--runtime-defense-review-output reports/runtime-defense-review.md
The packet includes a Runtime Defense Review Assistant for BYO AI or internal reviewers. It turns runtime behavior scope, monitoring handoff, countermeasure policy, domain/date lock smoke, source-reading compatibility scan, release metadata, and protected-build smoke into owner actions without sharing domains, dates, redirect URLs, beacon URLs, countermeasure values, source code, protected output, compatibility-scan source snippets, raw config files, API credentials, provider keys, collector tokens, customer data, or secrets.
Replace direct Node usage
const { obfuscate, obfuscateMultiple, getOptionsByPreset, protectCode } = require("jso-protector");
const obfuscationResult = await obfuscate(sourceCode, {
apiKey: process.env.JSO_API_KEY,
apiPassword: process.env.JSO_API_PASSWORD,
controlFlowFlattening: true,
identifierNamesGenerator: "hexadecimal",
reservedNames: ["^PublicApi$"],
stringArrayEncoding: ["rc4"]
}, "app.js");
const protectedCode = obfuscationResult.getObfuscatedCode();
const alsoProtectedCode = obfuscationResult.toString();
const multipleResults = await obfuscateMultiple({
"foo.js": "var foo = 1;",
"bar.js": "var bar = 2;"
}, {
apiKey: process.env.JSO_API_KEY,
apiPassword: process.env.JSO_API_PASSWORD,
...getOptionsByPreset("balanced")
});
obfuscate(code, options, fileName) and obfuscateMultiple(sourceCodesObject, options) are the closest replacements for JavaScriptObfuscator.obfuscate(...) and JavaScriptObfuscator.obfuscateMultiple(...), but they return Promises because protection happens through the hosted HTTP API. They accept common javascript-obfuscator option names directly, including stringArray, stringArrayEncoding, controlFlowFlattening, deadCodeInjection, deadCodeInjectionThreshold, identifierNamesGenerator, renameGlobals, renameProperties, reservedNames, compact, and target.
Use getOptionsByPreset("standard" | "balanced" | "maximum") when replacing preset lookup helpers, and translateJavascriptObfuscatorOptions(sourceOptions, overrides) when migration tooling needs to inspect the mapped hosted API config before making the API call. Existing custom build scripts can also use protectCode(options, code, fileName) when they prefer the JavaScript Obfuscator API naming.
const { protectCode } = require("jso-protector");
const protectedCode = await protectCode({
apiKey: process.env.JSO_API_KEY,
apiPassword: process.env.JSO_API_PASSWORD,
preset: "balanced",
reservedNames: ["^PublicApi$"]
}, sourceCode, "app.js");
For complete build output, prefer the CLI or a bundle plugin because they can remove stale source maps, write release manifests, and enforce size budgets.