Documentation

Encrypt Strings

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.

Encrypt Strings

  • EncryptStrings
  • Enterprise

Encrypt Strings stores string values in an encoded form and rebuilds them through generated logic when the script runs. Unlike Encode Strings, which is a fixed respelling any beautifier reverses, recovering these values means running or emulating the generated decoder.

What changes

Instead of leaving a readable literal in the file, the value is stored encoded and reconstructed at the point it is needed. A readable string such as:

"license-expired"

may become a generated representation similar to:

"nsf%y%tlcrludli%eBeolvrrs%..."

The decoder that turns that back into your string is itself generated per build and is subject to the other transforms you have enabled, so it does not appear as a recognisable, reusable helper across releases.

How it differs from Encode Strings

EncodeStringsEncryptStrings
MechanismEscape-sequence respellingEncoded value plus generated runtime decoder
Recovered by a beautifierYes, automaticallyNo — requires running or emulating the decoder
Runtime costNone (resolved at parse time)Work per string read
PlanFreeEnterprise

They are not exclusive, and there is no benefit to reaching for the weaker one when you have the stronger available for the strings that matter.

Be precise about the attacker model

The option name says "encrypt", and it is worth being exact about what that does and does not mean here. The decoder ships in the same file as the data it decodes. Anyone who can run your code can run the decoder, and a determined analyst can extract every string by instrumenting the decode function and collecting its return values.

So what this option raises is cost, not certainty. It removes static extraction from the table of cheap attacks and replaces it with dynamic extraction, which needs a working harness, a runtime, and time. For most commercial threats — a competitor copying a pricing rule, a scraper looking for endpoints, a cheater looking for a validation message — that difference matters. Against an attacker willing to instrument your bundle, it does not.

The corollary: a value that must stay unknown to the user does not belong in shipped JavaScript under any option. Move it behind an API call. See you cannot hide an API key in JavaScript for the reasoning, and obfuscation vs encryption for why client-side "encryption" of shipped code is a different thing from encryption in transit or at rest.

Configuration

{
  "options": {
    "MoveStrings": true,
    "EncryptStrings": true
  }
}

From the open-source javascript-obfuscator package, the stronger values of stringArrayEncoding map to EncryptStrings rather than EncodeStrings. See npm migration.

Use reservedStrings to hold specific literals out. Anything another system matches on byte-for-byte — a protocol constant, a selector, a webhook path — must be reserved, because a reconstructed value is only equal at runtime, not in the source text other tools read.

Runtime cost and where to spend it

Because values are reconstructed rather than parsed, every read does work. That is invisible in ordinary UI code and very visible in a hot loop that touches strings per frame or per row.

  • Profile before and after on the paths that matter: render loops, per-row formatters, game update ticks, large-list virtualisation.
  • Scope it rather than applying it everywhere. Named configuration sets let you run maximum protection over src/licensing/** and a lighter preset over the rest; inline directives narrow it further to regions within a file.
  • Hoist hot reads in your own source. A string read once into a local and reused in a loop pays the decode cost once.
  • The measured cost of each transform family is discussed in does obfuscation slow down JavaScript.
Tip: this option earns its cost on strings whose content is the asset — licence states, rule names, internal endpoints, gating messages. It earns nothing on UI copy a user reads on screen anyway. Apply it narrowly and measure; blanket application is the usual reason a protected build feels slower than it needs to.

Frequently asked questions

How does this differ from encoding strings?

Encoding rewrites a literal into an equivalent respelling, which is a fixed transformation any reader can undo by looking at it. This option rebuilds the literal through generated runtime logic instead, so recovering it means running or emulating that logic rather than reading a table. The practical consequence is that a static extraction pass gets less from it, at the cost of work performed while your program runs.

What does it cost at run time?

Enough that where you apply it matters more than whether you apply it. Every protected literal is reconstructed by executing code rather than by being read from the source text, so a blanket application across a large bundle of user-facing copy pays that cost repeatedly for no benefit. Applied to the strings whose content is the asset, the cost is negligible against the value. Measure a real build rather than reasoning about it.

Which strings are worth protecting this way?

The ones whose content is the thing you care about: licence and entitlement states, internal endpoint paths, rule and feature names, gating messages, anything that tells a reader how a decision is made. Interface copy that a user reads on screen is not in that category, because the text is visible in the rendered page whatever you do to the literal in the source.

Does this make a shipped secret safe?

No, and it is worth being blunt because this is the most common reason people enable it. A value your program uses at run time is a value your program reconstructs at run time, which means anyone who can run the program can observe the result. This option raises the cost of extracting a literal by reading the file; it does not change where the value ends up. Credentials belong on a server that answers requests, not in a bundle.

Does it work with non-Latin text?

Yes, and the mechanism makes it a non-event. The writer escapes characters outside the basic range into escape sequences, so protected output is plain ASCII even when the original literals are Chinese, Arabic or Cyrillic, and characters outside the basic multilingual plane round-trip as a surrogate pair. A comparison, a hash or a serialisation of the reconstructed string produces exactly what the original would have.

Can we keep specific literals out of it?

Yes, through the reserved strings mechanism, which takes a list of patterns whose matching literals stay verbatim and outside both this option and the string table. It is capped at a hundred patterns of moderate length, which is a fair signal that the intended use is a short deliberate list rather than a blanket exclusion. Keep it next to your name exclusions so the two are reviewed together.

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