User Rating 0.0 โ˜…โ˜…โ˜…โ˜…โ˜…
Total Usage 0 times
ES5 Input
ES3 Output
Quoted keys: 0 Dot → bracket: 0 Trailing commas: 0 Time: 0ms
Presets:
Is this tool helpful?

Your feedback helps us improve.

โ˜… โ˜… โ˜… โ˜… โ˜…

About

Legacy JavaScript engines conforming to ECMA-262 3rd Edition (ES3) - notably Internet Explorer 8 and below - treat reserved words as syntax errors when used as bare property identifiers. Code like obj.class or {return: 1} will throw a parse error in these engines, silently breaking entire application bundles. This tool performs the three critical transformations required for ES3 compliance: quoting reserved-word property keys in object literals, converting reserved-word dot-access to bracket notation, and stripping trailing commas from arrays and objects. It processes against the full set of 38 reserved words defined in ECMA-262 ยง7.5.1 through ยง7.5.3.

The converter operates as a context-aware parser, not a naive regex replacement. It tracks string literals, comments, and regular expression contexts to avoid corrupting quoted content. This matters in production: a blind find-and-replace on the word class would destroy CSS class strings and comment documentation. Note: this tool handles syntactic downgrading only. It does not polyfill ES5 runtime methods such as Array.prototype.forEach or Object.keys. For full ES3 deployment you still need runtime shims like es5-shim.

es3 es5 javascript converter ie8 compatibility reserved words es3ify browserify legacy browser support

Formulas

The converter applies three transformation rules in sequence. Each rule operates only on tokens outside of string literals, comments, and regular expression literals.

Rule 1 - Quote Reserved Property Keys:

input: { reservedWord : value } โ†’ output: { "reservedWord" : value }

For each unquoted identifier k in an object literal key position, if k โˆˆ ReservedWords, replace k with "k".

Rule 2 - Convert Dot Access to Bracket Notation:

expr.reservedWord โ†’ expr["reservedWord"]

For each member expression obj.prop, if prop โˆˆ ReservedWords, rewrite as obj["prop"].

Rule 3 - Remove Trailing Commas:

[ a, b, ] โ†’ [ a, b ]

{ k: v, } โ†’ { k: v }

Match any comma followed by optional whitespace and a closing ] or }. Remove the comma while preserving whitespace structure.

Where ReservedWords = the union of all ES3 Keywords (ECMA-262 ยง7.5.2) and FutureReservedWords (ยง7.5.3), totalling 53 identifiers. The context tracker uses a finite state machine with states: NORMAL, STRING_SINGLE, STRING_DOUBLE, COMMENT_LINE, COMMENT_BLOCK, REGEX. Transitions are triggered by character sequences like //, /*, */, and quote characters, with escape sequence awareness via backslash tracking.

Reference Data

Reserved WordCategoryObject Key FixDot Access Fix
breakKeyword{"break": v}o["break"]
caseKeyword{"case": v}o["case"]
catchKeyword{"catch": v}o["catch"]
classFuture Reserved{"class": v}o["class"]
constFuture Reserved{"const": v}o["const"]
continueKeyword{"continue": v}o["continue"]
defaultKeyword{"default": v}o["default"]
deleteKeyword{"delete": v}o["delete"]
doKeyword{"do": v}o["do"]
elseKeyword{"else": v}o["else"]
enumFuture Reserved{"enum": v}o["enum"]
exportFuture Reserved{"export": v}o["export"]
extendsFuture Reserved{"extends": v}o["extends"]
finallyKeyword{"finally": v}o["finally"]
forKeyword{"for": v}o["for"]
functionKeyword{"function": v}o["function"]
ifKeyword{"if": v}o["if"]
importFuture Reserved{"import": v}o["import"]
inKeyword{"in": v}o["in"]
instanceofKeyword{"instanceof": v}o["instanceof"]
newKeyword{"new": v}o["new"]
returnKeyword{"return": v}o["return"]
superFuture Reserved{"super": v}o["super"]
switchKeyword{"switch": v}o["switch"]
thisKeyword{"this": v}o["this"]
throwKeyword{"throw": v}o["throw"]
tryKeyword{"try": v}o["try"]
typeofKeyword{"typeof": v}o["typeof"]
varKeyword{"var": v}o["var"]
voidKeyword{"void": v}o["void"]
whileKeyword{"while": v}o["while"]
withKeyword{"with": v}o["with"]
abstractFuture Reserved{"abstract": v}o["abstract"]
booleanFuture Reserved{"boolean": v}o["boolean"]
byteFuture Reserved{"byte": v}o["byte"]
charFuture Reserved{"char": v}o["char"]
doubleFuture Reserved{"double": v}o["double"]
finalFuture Reserved{"final": v}o["final"]
floatFuture Reserved{"float": v}o["float"]
gotoFuture Reserved{"goto": v}o["goto"]
implementsFuture Reserved{"implements": v}o["implements"]
intFuture Reserved{"int": v}o["int"]
interfaceFuture Reserved{"interface": v}o["interface"]
longFuture Reserved{"long": v}o["long"]
nativeFuture Reserved{"native": v}o["native"]
packageFuture Reserved{"package": v}o["package"]
privateFuture Reserved{"private": v}o["private"]
protectedFuture Reserved{"protected": v}o["protected"]
publicFuture Reserved{"public": v}o["public"]
shortFuture Reserved{"short": v}o["short"]
staticFuture Reserved{"static": v}o["static"]
synchronizedFuture Reserved{"synchronized": v}o["synchronized"]
throwsFuture Reserved{"throws": v}o["throws"]
transientFuture Reserved{"transient": v}o["transient"]
volatileFuture Reserved{"volatile": v}o["volatile"]

Frequently Asked Questions

The converter targets all 53 reserved identifiers from ECMA-262 3rd Edition. This includes 26 keywords (break, case, catch, continue, default, delete, do, else, finally, for, function, if, in, instanceof, new, return, switch, this, throw, try, typeof, var, void, while, with, debugger) and 27 future reserved words (abstract, boolean, byte, char, class, const, double, enum, export, extends, final, float, goto, implements, import, int, interface, long, native, package, private, protected, public, short, static, super, synchronized, throws, transient, volatile). Words like "get" and "set" are NOT reserved in ES3 and are left untouched.
No. The parser implements a context-tracking finite state machine that recognizes six states: normal code, single-quoted strings, double-quoted strings, single-line comments (//), multi-line comments (/* */), and regular expression literals. Transformations only apply in the NORMAL state. Escape sequences (backslash followed by any character) inside strings are handled correctly, so a string like 'it\'s a class' will not trigger a false context exit.
This tool is designed for ES5-to-ES3 downgrading, not ES6+ transpilation. Template literals (backtick strings), arrow functions, destructuring, and other ES6+ features are outside scope and may not be parsed correctly. If your source contains ES6+ syntax, run it through a transpiler like Babel first to produce ES5 output, then use this tool for the ES3 property-safety pass.
The ES3 specification (ECMA-262 3rd Edition, ยง11.1.4 and ยง11.1.5) does not include trailing commas in the grammar productions for ArrayLiteral and ObjectLiteral. IE8's JScript engine strictly follows this grammar. ES5 (ยง11.1.4) explicitly added an Elision production allowing trailing commas in arrays, and ยง11.1.5 added it for objects. Modern engines implement ES5+, so they accept trailing commas. The extra comma in ES3 engines either throws a SyntaxError or, in arrays, creates an undefined phantom element at the end.
Yes. The parser operates character-by-character and does not depend on whitespace, newlines, or formatting. Minified single-line code is handled identically to formatted code. However, extremely large files (over 1MB) may cause a brief processing delay in the browser. For production build pipelines processing very large bundles, consider using the original es3ify npm package as a Browserify transform instead.
No. In JavaScript, obj.foo and obj["foo"] are semantically identical. Similarly, {foo: 1} and {"foo": 1} produce the same object. The ES3 restriction is purely syntactic - the parser rejects reserved words as bare IdentifierName tokens in property positions, but accepts them as StringLiteral tokens. The runtime property access and object creation are unchanged. There is zero performance difference.