> For the complete documentation index, see [llms.txt](https://infinitode-docs.gitbook.io/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infinitode-docs.gitbook.io/documentation/package-documentation/cloakjs-package-documentation.md).

# CloakJS Package Documentation

Package documentation for CloakJS 1.3.0, a single-file, dependency-free JavaScript obfuscator for the browser and Node.js that mangles identifiers, hides strings behind a generated decoder, rewrites n

CloakJS is a **single-file, dependency-free JavaScript obfuscator** for the browser and Node.js. Give it JavaScript source code and it returns obfuscated JavaScript source **as a string**: bindings renamed, strings hidden behind a generated decoder, numeric literals rewritten, control flow flattened inside function bodies, opaque predicates and unreachable decoy code injected, identifiers escaped, and runtime guards added if you ask for them. It never executes your code — generation compiles the result once as a parse check, nothing more.

* **Version:** 1.3.0 (also available as `CloakJS.VERSION`)
* **License:** [MIT](https://github.com/Infinitode/CloakJS/blob/main/LICENSE)
* **Source:** [github.com/Infinitode/CloakJS](https://github.com/Infinitode/CloakJS)
* **Dependencies:** none — no package manifest, nothing to resolve, nothing to build
* **Runtime requirement of the output:** none — the generated decoder is self-contained

{% hint style="danger" %}
**Obfuscation makes source harder to read — it does not make it secure.** It can't protect secrets, credentials, licence keys or security-critical checks that ship to the client, and it doesn't resist an analyst who can instrument the running page. Everything CloakJS does is reversible, by hand or with tooling. Treat it as a speed bump and a deterrent, never as a security boundary.
{% endhint %}

```html
<script src="https://cdn.jsdelivr.net/gh/Infinitode/CloakJS@main/cloakjs.min.js"></script>
<script>
  const code = CloakJS.obfuscate('console.log("Hello from CloakJS!")', "extreme");
  console.log(CloakJS.obfuscateWithStats("var n = 21; console.log(n * 2);", "high").stats);
</script>
```

## Changelog

* **1.3.0 (Latest)**: `extreme` is a real mode instead of a relabelled `high` (identifier escaping, string splitting, decoy string-array entries, maximum flattening and decoy amounts, and a recurring `debugger` trap). Control-flow flattening now reaches inside function bodies, nested bodies first. The generated decoder is self-contained — no `atob`, `Uint8Array` or `TextDecoder` needed. Template literals are first-class: identifiers inside `` `${…}` `` are renamed and static templates are encrypted. Mangling is broader and scope-aware (parameters, `catch` bindings, class names, named function expressions) but only renames a spelling when every occurrence lies in a scope that declares it. New options (`stringSplitting`, `stringArrayShuffle`, `stringArrayDecoys`, `stringEncoding`, `stringAlphabet`, `identifierEscaping`, `preserveFunctionNames`, `controlFlowThreshold`, `deadCodeAmount`, `debugProtection`, `wrapInIife`, `disableConsoleOutput`, `seed`), typed option validation that rejects typos, reproducible output via `seed`, a richer `stats` object with the `techniques` actually applied, and an expanded test suite (40 tests).
* **1.2.0**: Identifier mangling, string encryption, number encoding, control-flow flattening, dead-code injection, a self-defending prelude, five presets, `obfuscateWithStats` and `measure`.

The repository has no tagged releases yet, so `1.3.0` describes `main` as it stands. Check the [repository README](https://github.com/Infinitode/CloakJS#readme) for changes as they land.

## Installation

CloakJS is a plain JavaScript file — there's no npm release to install, nothing to compile and nothing to bundle. Download [`cloakjs.js`](https://github.com/Infinitode/CloakJS/blob/main/cloakjs.js) (readable) or [`cloakjs.min.js`](https://github.com/Infinitode/CloakJS/blob/main/cloakjs.min.js) (minified), or load either from jsDelivr:

```html
<!-- Minified build -->
<script src="https://cdn.jsdelivr.net/gh/Infinitode/CloakJS@main/cloakjs.min.js"></script>

<!-- Development: use .../cloakjs.js instead -->
<script src="https://cdn.jsdelivr.net/gh/Infinitode/CloakJS@main/cloakjs.js"></script>
```

{% hint style="warning" %}
**Don't `npm install cloakjs`.** CloakJS isn't distributed through npm. There *is* a package named `cloakjs` on the registry, but it's an unrelated AOP/Proxy wrapper library (currently 1.0.1) maintained by somebody else — it isn't this obfuscator. Grab the file from the repository or jsDelivr instead.
{% endhint %}

In Node.js, require the file directly — it's UMD, so it also works as an AMD module or as the global `CloakJS` in a `<script>` tag. The examples on these pages were run on Node 22:

```js
const CloakJS = require("./cloakjs.js");

const result = CloakJS.obfuscateWithStats('const who = "world"; console.log(`hi ${who}`);', "extreme");
console.log(result.code);      // obfuscated source, as a string
console.log(result.stats);     // what the pipeline actually applied
console.log(result.warnings);  // anything it refused to do — check these

// reproducible output while you are building a pipeline
const first = CloakJS.obfuscate("var a = 1; console.log(a);", { seed: "build-42" });
```

The **obfuscated** script is self-contained: the generated decoder implements its own Base64, alphabet substitution, RC4 and UTF-8 handling, so it runs in a bare sandbox with no globals or polyfills. It uses `TextDecoder` and `Uint8Array` when the host provides them, purely as a fast path.

For reproducible deployments, replace `@main` in the jsDelivr URL with a tag or commit hash, so a new push to `main` can't change the file your site loads.

## Quick start

```html
<script src="https://cdn.jsdelivr.net/gh/Infinitode/CloakJS@main/cloakjs.min.js"></script>
<script>
  // A preset: 'off' | 'low' | 'medium' | 'high' | 'extreme'
  const output = CloakJS.obfuscate('console.log("Hello from CloakJS!")', "high");
  console.log(output); // JavaScript source code, as a string
</script>
```

That string is your new script. Write it to a file, or serve it as the response body — CloakJS never evaluates the input it is given.

**Check what happened** with `obfuscateWithStats`, which reports counters, the techniques applied and any warnings:

```js
const result = CloakJS.obfuscateWithStats(source, "high");

console.log(result.code);      // the obfuscated source
console.log(result.stats);     // counts, ratio, techniques, seed
console.log(result.warnings);  // read these before shipping
```

See the [API reference](/documentation/package-documentation/cloakjs-package-documentation/cloakjs-reference.md) for every method and field, and [Usage examples](/documentation/package-documentation/cloakjs-package-documentation/cloakjs-usage-examples.md) for browser, Node and build-pipeline walkthroughs.

## Presets

| Preset    | Identifier mangling | Identifier escaping |       String array      | String splitting / decoys | Number encoding | Control flow flattening | Dead code + opaque predicates | Self-defending | Debug protection |
| --------- | :-----------------: | :-----------------: | :---------------------: | :-----------------------: | :-------------: | :---------------------: | :---------------------------: | :------------: | :--------------: |
| `off`     |          –          |          –          |            –            |             –             |        –        |            –            |               –               |        –       |         –        |
| `low`     |         yes         |          –          |            –            |             –             |        –        |            –            |               –               |        –       |         –        |
| `medium`  |         yes         |          –          |     Base64, ordered     |             –             |       yes       |            –            |               –               |        –       |         –        |
| `high`    |         yes         |          –          | RC4 + shuffled alphabet |             –             |       yes       |           yes           |              yes              |       yes      |         –        |
| `extreme` |         yes         |         yes         | RC4 + shuffled alphabet |            yes            |       yes       |      yes (maximum)      |         yes (maximum)         |       yes      |        yes       |

`extreme` is a genuine mode, not a relabelled `high`: compared to `high` it turns on identifier escaping, string splitting (6-character minimum chunk, up to 5 parts), six decoy entries per string array, the maximum decoy amount and an anti-debugging timer. Every preset enables `compactOutput`, and omitting `options` uses the **default options, which are the `high` settings**.

{% hint style="info" %}
No preset enables `disableConsoleOutput` or `wrapInIife`, because both change what your program does. Ask for them explicitly if you want them — see [Options and presets](/documentation/package-documentation/cloakjs-package-documentation/cloakjs-reference/cloakjs-options.md).
{% endhint %}

A partial options object overrides only the keys you supply:

```js
const result = CloakJS.obfuscateWithStats(
  'var message = "hi"; for (var i = 0; i < 2; i++) { console.log(message, i); }',
  { identifierMangling: false, controlFlowFlattening: false, stringArrayDecoys: 12 }
);
```

## Techniques

`CloakJS.techniques` describes every transform it can apply, including whether the technique changes observable behaviour:

* **Identifier mangling** — renames declared bindings whose occurrences provably stay inside a scope that declares them.
* **Preserve function names** — keeps function and class names, so `Function#name` and `constructor.name` stay readable.
* **Identifier escaping** — rewrites identifiers with `\uXXXX` escapes; escapes normalise to the same name, so behaviour is unchanged while grep patterns stop matching.
* **String encryption** — moves string literals (and static template literals) into an encoded array read through a generated decoder.
* **String splitting** — breaks long strings into codepoint-safe chunks that are decoded separately and concatenated.
* **Alphabet substitution** — encodes the string array with a shuffled Base64 alphabet and/or RC4.
* **String array decoys** — adds unused, well-formed entries to the string array.
* **Number encoding** — rewrites numeric literals as arithmetic, hex, binary, octal or bit expressions.
* **Control flow flattening** — moves statement runs into a shuffled `switch` dispatcher, inside function bodies as well as at the top level.
* **Dead code injection** — inserts unreachable decoy statements, including never-selected dispatcher cases.
* **Opaque predicates** — wraps statements in conditions whose value is computed at obfuscation time.
* **Self-defending prelude** — hashes generated functions and throws when they have been patched (whitespace-only edits are tolerated). ⚠️ changes behaviour
* **Debug protection** — installs a recurring `debugger` trap through a guarded `setInterval`. ⚠️ changes behaviour
* **Console silencing** — replaces `console` methods with no-ops. ⚠️ changes behaviour
* **IIFE wrapper** — wraps the program so top-level declarations stop leaking globals. ⚠️ changes behaviour

{% hint style="warning" %}
The four techniques marked ⚠️ can change what your program does — which is why no preset turns the last two on. Read [Behaviour changes and limits](/documentation/package-documentation/cloakjs-package-documentation/cloakjs-reference.md#behaviour-that-may-surprise-you) before enabling them.
{% endhint %}

## What CloakJS is not

Being clear about this saves you from a bad surprise in production:

* **It isn't a security boundary.** The RC4 key, the alphabet substitution and the decoder all ship with the output. Patching the decoder, dumping the string array or attaching a debugger all still work.
* **It doesn't hide secrets.** If a value must stay secret, it must not be sent to the client at all.
* **It isn't a parser-based tool.** CloakJS uses a conservative lexer. It handles strings, template literals, regexes, comments, ASI-sensitive splitting, destructuring, classes — including private fields — generators and async functions, but it doesn't support JSX, TypeScript, decorators or stage-3 syntax, which may end up only partially obfuscated.
* **It can't guarantee identical behaviour.** Every output is checked with `new Function`, and syntax errors are reported through `warnings` rather than hidden — but always test the **generated** code.
* **It isn't a minifier.** Decoys, flattening and the decoder all add bytes. `measure` tells you how many.

{% hint style="danger" %}
**Don't run obfuscated output through a minifier.** If `selfDefending` is on (it is at `high` and `extreme`), renaming or rewriting the generated functions makes the guard throw `Error("Unexpected token")` at runtime. Pure re-indentation is tolerated. Disable `selfDefending`, or obfuscate *after* minifying.
{% endhint %}

## Testing and contributing

The repository ships a dependency-free test suite — no fixtures, no network — that compares the behaviour of the original and the obfuscated program across every preset and a matrix of option combinations, so a change that alters program semantics fails the run:

```bash
node --test
```

Bug reports and pull requests are welcome through [GitHub issues](https://github.com/Infinitode/CloakJS/issues) (there are templates for [bugs](https://github.com/Infinitode/CloakJS/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) and [feature requests](https://github.com/Infinitode/CloakJS/blob/main/.github/ISSUE_TEMPLATE/feature_request.md)). When reporting a transform problem, include the input snippet, the preset or options, the warning list and the observed output — that's usually enough to reproduce it.

Maintainers regenerate the minified build with Terser after changing `cloakjs.js`:

```bash
npm exec --yes --package=terser@5.44.0 -- terser cloakjs.js --compress --mangle --comments '/^!/' --output cloakjs.min.js
```

On pushes that change `cloakjs.js`, the test suite or the workflow, a GitHub Actions job runs the tests, rebuilds `cloakjs.min.js`, verifies that the minified build reproduces the readable build's output for the same seed (in both a full sandbox and a bare one), and commits the file back to the same branch if it changed. Branch protection rules can prevent that automated push, in which case the minified file needs committing manually.

## License

CloakJS is released under the [MIT License](https://github.com/Infinitode/CloakJS/blob/main/LICENSE). Copyright (c) 2026 Infinitode.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://infinitode-docs.gitbook.io/documentation/package-documentation/cloakjs-package-documentation.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
