One product, every build pipe

JavaScript Obfuscator's protection runs through one HTTP API. Everything below is a wrapper around that API tuned to a specific surface — IDEs, CI systems, error reporters, build tools. The wire format stays in lockstep; pick the integration that matches where your release lives.

The release flow at a glance

Build → protect → ship → symbolicate. Same shape regardless of which tools you choose at each step.

1. Your build emits JavaScript into dist/.
2. jso-protector (CLI, build plugin, or IDE action) POSTs dist/ to HttpApi.ashx. The API returns the protected code and the identifier map.
3. Your CI archives the API report (jso-report.json) alongside the protected dist. The build is tagged with --label "$COMMIT_SHA" so the audit log groups by commit.
4. Production runs the protected code. Crashes carry the build's BuildId back to your reporter (Sentry, Bugsnag, Rollbar, Datadog, etc).
5. jso-symbolicate — via npm or via the reporter's beforeSend hook — demangles the stack against the saved report. Done locally; the trace never uploads anywhere it wasn't already going.

Non-Node language clients

When your build pipeline isn't Node-native — Python / Bazel / scripted releases, Go-based DevOps tooling — use a same-shape client library that hits the same HTTP API. No need to drag Node into the build environment.

CLI

Python: jso-protector (PyPI)

Pure stdlib — urllib + json, zero deps. protect() returns a ProtectResult dataclass with files, build_id, polymorphism_fingerprint, report. Three presets, env-var-first credentials.

v0.1.0 · PyPI · Python ≥3.8
CLI

Go: jso-protector-go

Pure stdlib — net/http + encoding/json, zero deps. jso.Protect(ctx, req) returns a *Result with the same shape as the Python and Node surfaces. Mockable via Request.HTTPClient for tests.

v0.1.0 · Go ≥1.21
CLI

.NET: JsoProtector (NuGet)

HttpClient-injectable for IHttpClientFactory and Polly. System.Text.Json. ProtectOptions + OptionOverrides. JsoProtectorException with Type/ErrorCode. Built clean under TreatWarningsAsErrors=true.

v0.1.0 · .NET Standard 2.0
CLI

Ruby: jso_protector (RubyGems)

Pure stdlib — net/http + json, zero deps. JsoProtector.protect(files:, preset:, ...) kwargs API. Result object with files, build_id, polymorphism_fingerprint. Rails-shop integration.

v0.1.0 · Ruby ≥2.7
CLI

PHP: javascriptobfuscator/jso-protector

Composer package, PHP ≥7.4 with typed properties. ext-curl when present; stream-context fallback. Client + Result + Exception namespaced. Laravel/Symfony-friendly.

v0.1.0 · Packagist · PHP ≥7.4
CLI

Rust: jso-protector (crates.io)

Sync HTTP via ureq, no async runtime. Client::protect(ProtectRequest) returns Result<ProtectResult, Error> with typed error enum. thiserror-derived.

v0.1.0 · Rust ≥1.70
CLI

Java: jso-protector (Maven Central)

JDK 11+. Uses built-in java.net.http.HttpClient — no third-party HTTP dependency. ProtectOptions.builder() fluent API. Jackson for JSON. Constructor-injectable HttpClient.

v0.1.0 · Maven Central · JDK ≥11
Spec

Anything else: the wire format spec

Protocol-level documentation of the HTTP API. JSON request/response shape, preset constants, error model. Reference examples/curl/protect.sh included — the smallest possible compliant client (~100 lines bash + curl + jq).

Updated 2026-05-20 ·
Docs/WireFormat.aspx Docs

All seven clients in one place

Side-by-side matrix and "same protect() in seven languages" code examples. The reference doc when picking which client to bring into a polyglot pipeline.

Updated 2026-05-20
Hook

pre-commit hooks

jso-release-check and jso-dry-run run against staged JS before every commit. Catches config drift before CI. Deliberately doesn't POST source on every commit — that's CI's job.

v0.2.0 · .pre-commit-hooks.yaml