crates/oxc_minifier/docs/ASSUMPTIONS.md
The Oxc minifier makes certain assumptions about JavaScript code to achieve optimal compression. These assumptions are standard for typical JavaScript but may not hold for unusual code patterns.
These assumptions are validated using ECMAScript operations from oxc_ecmascript, which implements spec-compliant behavior for type conversions, side effect analysis, and constant evaluation.
These assumptions are held regardless of the options.
Built-in objects and their methods and properties behave as specified in ECMAScript.
// The minifier assumes this never happens:
Array.prototype.push = function () {
console.log("hijacked!");
};
Object.defineProperty(Number.prototype, "toString", { value: () => "hijacked!" });
document.all UsageThe deprecated document.all with its special typeof behavior is not used.
// The minifier assumes this never happens:
typeof document.all === "undefined"; // true in browsers
document.all && console.log("exists but falsy");
with StatementCode does not use with statements which create ambiguous scope.
// The minifier assumes this never happens:
with (obj) {
x = 1; // Is this obj.x or a global x?
}
.toString(), .valueOf(), and [Symbol.toPrimitive]() have no side effects. The minifier uses oxc_ecmascript type conversion utilities that assume standard coercion behavior.
// The minifier assumes this never happens:
const obj = {
toString() {
console.log("side effect!");
return "";
},
};
String(obj); // Would trigger side effect
Code doesn't violate Temporal Dead Zones.
// The minifier assumes this never happens:
console.log(x); // TDZ violation
let x = 1;
Creating strings or arrays that exceed maximum length can be moved or removed.
// The minifier may change when this error occurs:
try {
new Array(2 ** 32); // RangeError
} catch {
console.log("caught");
}
Extending a class does not have a side effect.
const v = [];
class A extends v {} // TypeError
eval are not referenced outside the evalVariables declared in direct eval are not referenced outside the eval, which is only allowed in non-strict mode.
// The minifier assumes this never happens:
eval("var x = 1");
console.log(x); // 1
Accessing known global identifiers (e.g. Math, Array, Object, console, document, window, DOM classes, etc.) does not throw a ReferenceError and has no side effects. Reading their properties (e.g. Math.PI, Object.keys) and select 3-level chains (e.g. Object.prototype.hasOwnProperty) are also side-effect-free. This list is ported from Rolldown's GLOBAL_IDENT set, which mirrors Rollup's knownGlobals, and includes browser/host-specific APIs intentionally.
// The minifier assumes these are always available:
Math.PI; // side-effect-free
Array.isArray; // side-effect-free
console; // side-effect-free to access (calling methods may still have side effects)
argumentsAccessing a global variable named arguments does not have a side effect. We intend to change this assumption to optional in the future.
// The minifier assumes this never happens:
console.log(arguments); // ReferenceError: arguments is not defined
Function.prototype.toString is not relied onCode does not depend on Function.prototype.toString() returning specific source text. Minification renames variables and parameters, simplifies expressions (true → !0), restructures statements (fusing with the comma operator, converting while to for), removes whitespace, and may eliminate function bodies entirely (e.g. IIFE inlining). All of these change the string returned by .toString().
const serialize = (fn) => fn.toString();
serialize((x) => {
return x * 2;
}); // Relied on to contain "return"
Code doesn't depend on function names being preserved. This assumption is held by default. This can be changed by settings keepNames option.
// The minifier assumes this never happens:
function myFunc() {}
if (myFunc.name !== "myFunc") throw Error();
Optional assumptions can be configured in the minifier options if your code requires different behavior.
pub struct CompressOptions {
// Control optimization behavior
pub drop_console: bool,
pub drop_debugger: bool,
pub join_vars: bool,
pub sequences: bool,
pub unused: CompressOptionsUnused,
pub keep_names: CompressOptionsKeepNames,
// Tree-shaking options affect side effect analysis
pub treeshake: TreeShakeOptions,
}
pub struct TreeShakeOptions {
// Whether property reads have side effects
pub property_read_side_effects: PropertyReadSideEffects,
// Whether property writes have side effects
pub property_write_side_effects: bool,
// Whether accessing unknown globals has side effects
pub unknown_global_side_effects: bool,
// Respect pure annotations like /* @__PURE__ */
pub annotations: bool,
}
To ensure your code works with these assumptions:
cargo coverage runs test262, Babel, TypeScript testsThe minifier includes comprehensive validation against Node.js compatibility tables to ensure optimizations work correctly across different Node.js versions and environments.
If your code violates these assumptions, you may: