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 for real release work.

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.

Runtime Defense

  • HTTP API, npm CLI, build plugins, desktop projects
  • tamper response, code locks, debugger friction, and release attestation

Runtime defense adds active checks around protected code. These options do not replace obfuscation; they add policy checks that can recover a post-startup function mutation, throw, blank or reload the page, redirect, degrade through an application event, call a local handler, or POST a small beacon when a protected release is run in the wrong environment or appears to be under analysis.

Choose the response action

Use RuntimeDefenseAction to choose what happens when a runtime check fails and recovery is disabled or exhausted. Supported values are throw, blank, redirect, reload, callback, and degrade. Use RuntimeDefenseRedirectUrl with redirect. callback reports and returns; degrade also sets globalThis.__jsoDefenseDegraded=true and dispatches jso:defense-degraded so the host can disable a sensitive feature, invalidate a session, or require step-up authentication.

{
  "Options": {
    "RuntimeDefenseAction": "throw",
    "RuntimeDefenseCallback": "window.jsoDefenseEvent",
    "RuntimeDefenseBeaconUrl": "https://example.com/jso-defense",
    "RuntimeDefenseBeaconToken": "jso_..."
  }
}

RuntimeDefenseCallback is a global function path that receives { code, message }. RuntimeDefenseBeaconUrl sends the event body with navigator.sendBeacon or fetch in browsers, and an HTTP(S) request in Node-compatible targets. Set RuntimeDefenseBeaconToken to put a collector token in that JSON body; the hosted intake removes it before an incident is stored or exported. Point the URL at your own collector or at the hosted dashboard intake at /v1/runtime/beacon.ashx after creating a collector token in Dashboard Monitoring. The jso-beacon-slack forwarder is planned and is not yet a public package.

Debugger and tamper checks

DebugProtection
Adds browser debugger timing checks and debugger-trigger friction.
DisableConsoleOutput
Suppresses common console methods in protected browser output.
SelfDefending
Wraps output with integrity checks that fail when the generated function body changes.
SelfDefendingIntervalSeconds
Runs recurring integrity heartbeats when set to a positive number.
SelfHealing
Reconstructs a mutated function from the reference source held inside the running closure before the configured failure action runs.
SelfHealingMaxAttempts
Bounds local reconstruction attempts from 1 to 10; the default is 1.
AntiMonkeyPatching
Snapshots selected browser APIs and detects replacements made after protected output starts.
AntiMonkeyPatchingMsg
Optional message emitted when the API-integrity check trips.
RuntimeIntegrityAlgorithm
Uses Web Crypto digest checks with SelfDefending, for example SHA-256.
BlockDevToolsKeys
Blocks common browser keyboard shortcuts used to open developer tools.
{
  "Options": {
    "SelfDefending": true,
    "SelfHealing": true,
    "SelfHealingMaxAttempts": 2,
    "SelfDefendingIntervalSeconds": 15,
    "RuntimeIntegrityAlgorithm": "SHA-256",
    "RuntimeDefenseAction": "degrade",
    "RuntimeDefenseCallback": "window.onJsoDefense"
  }
}

SelfHealing is bounded, local, and browser-only. It repairs mutations that happen after the protected wrapper has started by rebuilding from its closure-held protected source. It makes no network request and does not claim to repair a bundle that was modified before startup, recover server authority, or replace signed release verification. A successful repair emits a self-healed-* callback/beacon event for incident review.

AntiMonkeyPatching is opt-in and browser-only. It snapshots Function.prototype.toString, JSON helpers, selected Array/Object methods, timers, Fetch, and XMLHttpRequest, then routes detected replacements through the configured Runtime Defense action. It is intended to detect changes made after the protected bundle starts; it deliberately tolerates APIs that were already polyfilled at startup. Test it with your telemetry, browser extensions, and instrumentation stack before release.

Browser-only checks are skipped for OptimizationMode=NodeJS with a warning where they do not make sense.

Code locks

Domain and date locks are the simple distribution controls. Runtime defense adds stronger release-specific checks for applications that can provide expected state at startup.

Session lock
RuntimeSessionToken and RuntimeSessionVariable require a global value to match the token embedded in the protected build.
Fingerprint lock
RuntimeFingerprint locks to an exact collected browser fingerprint. RuntimeFingerprintAllow supports partial allow-list matching.
Challenge lock
RuntimeChallengeSecret, RuntimeChallengeVariable, and RuntimeChallengeWindowSeconds require a fresh runtime challenge response.
Headless detection
DetectHeadlessBrowser detects common automated browser signals before running protected logic.
{
  "Options": {
    "RuntimeDefenseAction": "blank",
    "RuntimeFingerprintAllow": [
      "platform:Win32",
      "language:en-US",
      "timezone:300"
    ],
    "RuntimeFingerprintMinMatch": 2,
    "RuntimeTimezoneToleranceMinutes": 60,
    "DetectHeadlessBrowser": true
  }
}

Fingerprint tokens can use userAgent, platform, language, screen, colorDepth, and timezone. Use partial matching for real user traffic; exact fingerprints are brittle across browser and OS updates.

Signed release envelopes

Signed envelopes let a protected build verify that a runtime-provided payload was signed by your release system. Configure RuntimeSignedEnvelopeVariable, RuntimeSigningPublicKey, RuntimeSignatureAlgorithm, and RuntimeSignedEnvelopeWindowSeconds. Optional expected claims include RuntimeExpectedChallengeID, RuntimeExpectedReleaseID, RuntimeExpectedWorkspaceKey, and RuntimeExpectedProjectName.

{
  "Options": {
    "RuntimeSignedEnvelopeVariable": "window.jsoReleaseEnvelope",
    "RuntimeSigningPublicKey": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
    "RuntimeSignatureAlgorithm": "RSASSA-PKCS1-v1_5",
    "RuntimeSignedEnvelopeWindowSeconds": 300,
    "RuntimeExpectedReleaseID": "web-2026.05.14"
  }
}

Set RuntimeSignatureBindEnvironment=true when the signature should also bind to the current user agent and platform. Signed envelope verification requires browser Web Crypto support and is skipped for NodeJS-targeted builds.

Where results appear

The HTTP API response and release audit metadata include runtime-defense summaries: enabled defenses, callback/beacon presence, lock types, integrity heartbeat status, signed-envelope status, and the selected action. Use these summaries in CI when reviewing whether a release candidate has the expected runtime policy.

Hosted incident intake

The dashboard can accept Runtime Defense and third-party inventory events when the runtime incident schema is provisioned. Create a collector token under Dashboard Monitoring, then set the beacon URL in your release config. Use one token per production app or release channel so a single collector can be disabled without affecting the rest of the account.

{
  "Options": {
    "RuntimeDefenseBeaconUrl": "https://www.javascriptobfuscator.com/v1/runtime/beacon.ashx",
    "RuntimeDefenseBeaconToken": "jso_..."
  }
}

For browser-generated builds, use RuntimeDefenseBeaconToken; it is sent in the JSON body and removed at intake before payload storage and export. It is still a bearer credential embedded in the client build, so scope one token per app or release channel and disable it on exposure. Server-side or proxy collectors can send X-JSO-Beacon-Token. The legacy ?token= form remains supported for compatibility, but exposes a bearer token to URL logs and must not be used in new deployments. Hosted beacon payloads are limited to 256 KB. The dashboard stores event time, severity, kind, reason, BuildID, fingerprint, URL, user agent, remote IP, and the raw JSON payload.

Deployment verification: after provisioning the incident schema in a staging environment, set JSO_RUNTIME_BEACON_TOKEN in the test process and run tools/Test-RuntimeBeaconIntake.ps1 -Endpoint https://staging.example.com/v1/runtime/beacon.ashx. The script sends a body-authenticated smoke event, prints only its incident ID and BuildID, and fails if intake does not create an incident. Locate that BuildID in Dashboard Monitoring, change its status, and export its evidence packet before enabling the collector for a release. Do not put a collector token in the command line or endpoint URL.

Use the hosted view for first triage: filter the list to all recent, active, high/critical, active high/critical, or a specific BuildID; mark events as Reviewing, Resolved, Ignored, or reopen them when more review is needed. Each row now carries a source-free per-incident action plan with next owner, response due state, status move, evidence packet, and next action so account owners can sort the queue without opening raw payloads. Use Move open in view to Reviewing when a filtered queue has been acknowledged; it only changes Open incidents in the current account and filter, leaving resolved, ignored, and already-reviewing rows untouched. Use Resolve reviewing in view only after the filtered review is complete; it changes Reviewing incidents to Resolved while leaving Open, Ignored, and already-resolved rows untouched. The page shows a source-free routing recommendation for the current filter: escalation level, recommended queue, evidence packet, response target, response window, status action, repeated-signal correlation by fingerprint and reason, active incident counts, and customer-owned destinations for confirmed incidents.

The dashboard also shows an alert routing playbook with security-response, customer-owned alerting, support-handoff, and reviewer-packet lanes so account owners can hand the same packet to the right owner without treating JSO as a managed SOC console. Export the incident CSV or JSON from the same filtered view when a reviewer needs source-free evidence tied to a release, or use a row's Evidence JSON link when support needs one incident packet with payload SHA-256 metadata instead of the full event history. Add runtime_status=active, runtime_severity=high-critical, and runtime_build=checkout-2026-06-07 when support automation only needs unresolved high-risk events for one release.

The JSON export includes summary counts for status, severity, active incidents, active high/critical incidents, payload-hash coverage, BuildIDs, event/received date ranges, per-incident action plan owner/due/status metadata, repeated-signal correlation groups, the same routing recommendation, source-free dashboard action metadata, the alert routing playbook, a response window with due time and overdue state, and a source-free response checklist before the individual incident rows. Correlation groups list repeated fingerprints and repeated reasons with counts, status totals, BuildIDs, first/last received timestamps, and a recommended review action; they do not include raw payloads or source code. Use CSV for audit handoff and JSON for support automation, dashboard action handoffs, action-plan owner assignment, response-window decisions, routing decisions, alert-routing handoffs, correlation triage, or reviewer packets. The CLI runtime incident evidence report also includes a source-free Review Assistant Packet for BYO AI or internal reviewers, turning urgent response, overdue incident owners, repeated-signal correlation, dashboard status actions, response-window, and alert-routing handoff questions into owner actions without sharing source code, raw incident payloads, collector tokens, customer data, or secrets.

The Runtime evidence handoff panel in Dashboard Monitoring gives account owners the exact export-and-command path for a standalone Markdown or JSON packet. Export the filtered JSON view, then run jso-protector --runtime-incident-evidence reports/runtime-incidents.json --runtime-incident-evidence-output reports/runtime-incident-evidence.md. Active high/critical packets fail the CLI gate until the incident is acknowledged and routed. Share the dashboard JSON export and generated packet only; do not attach source code, payment-card data, customer personal data, provider keys, collector tokens, or secrets. Keep routing confirmed incidents to Splunk, Elasticsearch, Slack, or a signed webhook for long-term operations.

Try this in the online obfuscator

Paste your own code and see this option applied, or compare plans for larger projects and the desktop app.

Try It Free See Pricing