Documentation

Guides for protecting production JavaScript

Reference guides for release workflows, command-line usage, cross-file protections, and the desktop app.

Inside The Docs

Practical guides, not placeholder pages.

How-to guides Start with release sequencing and command-line usage, then move into feature-specific references.
Advanced protection Browse cross-file controls like Replace Globals and Protect Members when a build spans multiple scripts.

Migrating from javascript-obfuscator

  • npm CLI, Node API, Vite, Rollup, Webpack, esbuild

Use this guide when a project already knows the open-source javascript-obfuscator package and wants to move release protection to JavaScript Obfuscator account workflows, presets, and hosted HTTP API protection.

Choose the right workflow

Stay with local-only tooling
Use a local npm obfuscator when source code cannot leave the build machine and you only need local package transforms.
Use jso-protector
Use the hosted JavaScript Obfuscator API when you want dashboard credentials, shared presets, CI guardrails, release manifests, and the same account-backed protection features as the web workflow.

For regulated or sensitive projects, review Security and Processing before enabling hosted API protection.

Replace the package command

npm remove javascript-obfuscator
npm install --save-dev jso-protector
npx jso-protector --init

Set dashboard API credentials in CI or your local shell. The package reads both short and long environment names.

set JSO_API_KEY=base64-api-key
set JSO_API_PASSWORD=base64-api-password
set JAVASCRIPT_OBFUSCATOR_API_KEY=base64-api-key
set JAVASCRIPT_OBFUSCATOR_API_PASSWORD=base64-api-password

Map familiar options

String array and string encoding
stringArray, stringArrayEncoding, and related settings usually map to MoveStrings, EncodeStrings, and EncryptStrings.
Identifier renaming
identifierNamesGenerator and rename settings usually map to ReplaceNames, RenameGlobals, RenameMembers, and IdentityStyle.
Reserved names
reservedNames maps to reservedNames in config or repeatable --reserved-name flags. The value is sent as VariableExclusion.
Control-flow transforms
controlFlowFlattening, dead-code, and transformation options usually map to DeepObfuscate, ReorderCode, FlatTransform, AddDeadCode, and DeadcodeLevel.
Output compacting
compact and formatting choices usually map to SelfCompression, CompressionRatio, WriteFormats, and related formatting options.
Domain or time locks
Use LockDomain, LockDomainList, LockDate, and LockDateValue from the HTTP API options.

The names are not a one-to-one copy of the open-source package. Run jso-protector --list-options --json to inspect the supported API option names, jso-protector --list-migration-map --json to inspect migration coverage, and jso-protector --explain-compat self-defending --json to inspect one mapped or review-only option before porting a large config. The migration map includes mapped, direct, approximate, review-only, and total known option counts for migration tooling.

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, and protect commands.

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, and --compact. 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.

The CLI also accepts common review-only flags such as --source-map, --source-map-sources-mode, --identifier-names-cache, --identifier-names-cache-path, --self-defending, --debug-protection, --disable-console-output, --reserved-strings, --rename-properties-mode, --numbers-to-expressions, --seed, --split-strings, and string-array wrapper flags so older scripts do not fail immediately. These emit compatibility warnings when there is no one-to-one hosted API mapping.

Port a config gradually

{
  "$schema": "./node_modules/jso-protector/jso.config.schema.json",
  "apiKey": "$JSO_API_KEY",
  "apiPassword": "$JSO_API_PASSWORD",
  "input": "dist",
  "output": "dist-protected",
  "preset": "balanced",
  "exclude": ["**/*.map", "**/vendor/**", "**/polyfills-*.js"],
  "parseHtml": false,
  "honorConditionalComments": false,
  "reservedNames": ["^PublicApi$", "^renderWidget$"],
  "manifest": "dist-protected/jso-manifest.json",
  "maxGrowthRatio": 8,
  "options": {
    "OptimizationMode": "Web",
    "LockDomain": false
  }
}

Start with preset: "balanced", protect only first-party build output, then add API options one group at a time.

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.

Replace bundler plugins

const jsoProtector = require("jso-protector/vite");

module.exports = {
  plugins: [
    jsoProtector({
      apiKey: process.env.JSO_API_KEY,
      apiPassword: process.env.JSO_API_PASSWORD,
      preset: "balanced",
      include: ["assets/*.js"],
      exclude: ["**/vendor/**"],
      manifest: "dist/jso-manifest.json",
      maxGrowthRatio: 8
    })
  ]
};

Equivalent entrypoints are available for jso-protector/rollup, jso-protector/webpack, jso-protector/webpack-loader, jso-protector/browserify, jso-protector/esbuild, jso-protector/gulp, and jso-protector/grunt.

Migration checklist

  1. Run jso-protector --dry-run --json and confirm the file list.
  2. Exclude vendor bundles, polyfills, generated framework runtime files, and source maps.
  3. Add reservedNames for public globals, framework entry points, and names called by external code.
  4. Protect into a separate output folder first, then run browser smoke tests against that folder.
  5. Add manifest, maxOutputBytes, or maxGrowthRatio once the protected output is stable.
Next: read the npm CLI workflow and npm presets and options references for the complete command surface.