{"id":35162421,"url":"https://github.com/codingjoe/esupgrade","last_synced_at":"2026-01-18T02:35:30.531Z","repository":{"id":330853710,"uuid":"1123722167","full_name":"codingjoe/esupgrade","owner":"codingjoe","description":"Auto-upgrade your JavaScript syntax","archived":false,"fork":false,"pushed_at":"2026-01-10T17:05:42.000Z","size":253,"stargazers_count":7,"open_issues_count":15,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-11T15:17:28.356Z","etag":null,"topics":["ecmascript","es6","javascript","linter","typescript","upgrade-tool"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codingjoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"codingjoe","buy_me_a_coffee":"codingjoe","custom":"https://www.paypal.me/codingjoe"}},"created_at":"2025-12-27T13:33:32.000Z","updated_at":"2026-01-10T17:05:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/codingjoe/esupgrade","commit_stats":null,"previous_names":["codingjoe/esupgrade"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/codingjoe/esupgrade","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingjoe%2Fesupgrade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingjoe%2Fesupgrade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingjoe%2Fesupgrade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingjoe%2Fesupgrade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codingjoe","download_url":"https://codeload.github.com/codingjoe/esupgrade/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingjoe%2Fesupgrade/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28400778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecmascript","es6","javascript","linter","typescript","upgrade-tool"],"created_at":"2025-12-28T18:45:34.703Z","updated_at":"2026-01-13T22:05:32.399Z","avatar_url":"https://github.com/codingjoe.png","language":"JavaScript","funding_links":["https://github.com/sponsors/codingjoe","https://buymeacoffee.com/codingjoe","https://www.paypal.me/codingjoe"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./images/logo-dark.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./images/logo-light.svg\"\u003e\n    \u003cimg alt=\"esupgrade: Auto-upgrade your JavaScript syntax\" src=\"./images/logo-light.svg\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n# esupgrade [![npm version](https://img.shields.io/npm/v/esupgrade.svg?style=flat-square)](https://www.npmjs.com/package/esupgrade) [![coverage status](https://img.shields.io/codecov/c/github/codingjoe/esupgrade/main.svg?style=flat-square)](https://codecov.io/gh/codingjoe/esupgrade) [![license](https://img.shields.io/npm/l/esupgrade.svg?style=flat-square)](https://github.com/codingjoe/esupgrade/blob/main/LICENSE)\n\nKeeping your JavaScript and TypeScript code up to date with full browser compatibility.\n\n## Usage\n\nesupgrade is safe and meant to be used automatically on your codebase.\nWe recommend integrating it into your development workflow using [pre-commit].\n\n### pre-commit\n\n```bash\nuvx pre-commit install\n```\n\n```yaml\n# .pre-commit-config.yaml\nrepos:\n  - repo: https://github.com/codingjoe/esupgrade\n    rev: 2025.0.2 # Use the latest version\n    hooks:\n      - id: esupgrade\n```\n\n```bash\npre-commit run esupgrade --all-files\n```\n\n### CLI\n\n```bash\nnpx esupgrade --help\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-wordmark-dark.svg\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-wordmark.svg\"\u003e\n  \u003cimg alt=\"Baseline: widely available\" src=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-wordmark.svg\" height=\"32\" align=\"right\"\u003e\n\u003c/picture\u003e\n\n## Browser Support \u0026 Baseline\n\nAll transformations are based on [Web Platform Baseline][baseline] features. Baseline tracks which web platform features are safe to use across browsers.\n\nBy default, `esupgrade` uses **widely available** features, meaning they work in all major browsers (Chrome, Edge, Safari, Firefox) for at least 30 months. This ensures full compatibility while keeping your code modern.\n\nYou can opt into **newly available** features (available in all browsers for 0-30 months) with:\n\n```bash\nnpx esupgrade --baseline newly-available \u003cfiles\u003e\n```\n\nFor more information about Baseline browser support, visit [web.dev/baseline][baseline].\n\n## Supported File Types \u0026 Languages\n\n- `.js` - JavaScript\n- `.jsx` - React/JSX\n- `.ts` - TypeScript\n- `.tsx` - TypeScript with JSX\n- `.mjs` - ES Modules\n- `.cjs` - CommonJS\n\n## Transformations\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-widely-word-dark.svg\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-widely-word.svg\"\u003e\n  \u003cimg alt=\"Baseline: widely available\" src=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-widely-word.svg\" height=\"32\" align=\"right\"\u003e\n\u003c/picture\u003e\n\n### Widely available\n\n#### `var` → [const][mdn-const] \u0026 [let][mdn-let]\n\n```diff\n-var x = 1;\n-var y = 2;\n-y = 3;\n+const x = 1;\n+let y = 2;\n+y = 3;\n```\n\n#### String concatenation → [Template literals][mdn-template-literals]\n\n```diff\n-const greeting = 'Hello ' + name + '!';\n-const message = 'You have ' + count + ' items';\n+const greeting = `Hello ${name}!`;\n+const message = `You have ${count} items`;\n```\n\nSpecial handling for escape sequences and formatting:\n\n- **Escape sequences**: `\\r` (carriage return) is preserved, while `\\n` (newline) is converted to actual newlines\n\n  ```diff\n  -const text = \"Line 1\\n\" + \"Line 2\";\n  +const text = `Line 1\n  +Line 2`;\n  ```\n\n- **Multiline concatenation**: Visual structure is preserved with line continuation backslashes\n\n  ```diff\n  -const longText = \"First part \" +\n  -                 \"second part\";\n  +const longText = `First part \\\n  +second part`;\n  ```\n\n#### Traditional `for` loops → [`for...of` loops][mdn-for-of]\n\n```diff\n-for (let i = 0; i \u003c items.length; i++) {\n-  const item = items[i];\n-  console.log(item);\n-}\n+for (const item of items) {\n+  console.log(item);\n+}\n```\n\nTransformations are limited to loops that start at 0, increment by 1, and where the index variable is not used in the loop body.\n\n#### `Array.from().forEach()` → [`for...of` loops][mdn-for-of]\n\n```diff\n-Array.from(items).forEach(item =\u003e {\n-  console.log(item);\n-});\n+for (const item of items) {\n+  console.log(item);\n+}\n```\n\n#### DOM `forEach()` → [`for...of` loops][mdn-for-of]\n\n```diff\n-document.querySelectorAll('.item').forEach(item =\u003e {\n-  item.classList.add('active');\n-});\n+for (const item of document.querySelectorAll('.item')) {\n+  item.classList.add('active');\n+}\n```\n\nSupports:\n\n- `document.querySelectorAll()`\n\n- `document.getElementsByTagName()`\n\n- `document.getElementsByClassName()`\n\n- `document.getElementsByName()`\n\n- `window.frames`\n\n- Transformations limited to inline arrow or function expressions with block statement bodies.\n  Callbacks with index parameters or expression bodies are not transformed.\n\n#### `Array.from()` → [Array spread [...]][mdn-spread]\n\n```diff\n-const doubled = Array.from(numbers).map(n =\u003e n * 2);\n-const filtered = Array.from(items).filter(x =\u003e x \u003e 5);\n-const arr = Array.from(iterable);\n+const doubled = [...numbers].map(n =\u003e n * 2);\n+const filtered = [...items].filter(x =\u003e x \u003e 5);\n+const arr = [...iterable];\n```\n\n`Array.from()` with a mapping function or thisArg is not converted.\n\n#### `Object.assign({}, ...)` → [Object spread {...}][mdn-spread]\n\n```diff\n-const obj = Object.assign({}, obj1, obj2);\n-const copy = Object.assign({}, original);\n+const obj = { ...obj1, ...obj2 };\n+const copy = { ...original };\n```\n\n\u003e [!NOTE]\n\u003e TypeScript does not support generic object spread yet:\n\u003e https://github.com/Microsoft/TypeScript/issues/10727\n\u003e You might need to manually adjust the type after transformation:\n\u003e\n\u003e ```ts\n\u003e const object_with_generic_type: object = { ...(myGenericObject as object) }\n\u003e ```\n\n#### `Array.concat()` → [Array spread [...]][mdn-spread]\n\n```diff\n-const combined = arr1.concat(arr2, arr3);\n-const withItem = array.concat([item]);\n+const combined = [...arr1, ...arr2, ...arr3];\n+const withItem = [...array, item];\n```\n\n#### `Array.slice(0)` → [Array spread [...]][mdn-spread]\n\n```diff\n-const copy = [1, 2, 3].slice(0);\n-const clone = Array.from(items).slice();\n+const copy = [...[1, 2, 3]];\n+const clone = [...Array.from(items)];\n```\n\n#### `Math.pow()` → [Exponentiation operator \\*\\*][mdn-exponentiation]\n\n```diff\n-const result = Math.pow(2, 3);\n-const area = Math.PI * Math.pow(radius, 2);\n+const result = 2 ** 3;\n+const area = Math.PI * radius ** 2;\n```\n\n#### Named function assignments → [Function declarations][mdn-functions]\n\n```diff\n-const myFunc = () =\u003e { return 42; };\n-const add = (a, b) =\u003e a + b;\n-const greet = function(name) { return \"Hello \" + name; };\n+function myFunc() { return 42; }\n+function add(a, b) { return a + b; }\n+function greet(name) { return \"Hello \" + name; }\n```\n\nTransforms arrow functions and anonymous function expressions assigned to variables into proper named function declarations. This provides better structure and semantics for top-level functions.\n\nFunctions using `this` or `arguments` are not converted to preserve semantics.\n\nTypeScript parameter and return type annotations are preserved:\n\n```diff\n-let myAdd = function (x: number, y: number): number {\n-  return x + y;\n-};\n+function myAdd(x: number, y: number): number {\n+  return x + y;\n+}\n```\n\nGeneric type parameters are also preserved:\n\n```diff\n-export const useHook = \u003cT extends object\u003e(props: T): T =\u003e {\n-  return props;\n-};\n+export function useHook\u003cT extends object\u003e(props: T): T {\n+  return props;\n+}\n```\n\nVariables with TypeScript type annotations but no function return type are skipped:\n\n```typescript\n// Not transformed - variable type annotation cannot be transferred\nconst Template: StoryFn\u003cMyType\u003e = () =\u003e { return \u003cdiv\u003eHello\u003c/div\u003e; };\n```\n\n#### Anonymous function expressions → [Arrow functions][mdn-arrow-functions]\n\n```diff\n-items.map(function(item) { return item.name; });\n-button.addEventListener('click', function(event) { process(event); });\n+items.map(item =\u003e { return item.name; });\n+button.addEventListener('click', event =\u003e { process(event); });\n```\n\nAnonymous function expressions not in variable declarations (like callbacks and event handlers) are converted to arrow functions.\n\nFunctions using `this`, `arguments`, or `super` are not converted to preserve semantics.\n\n#### Constructor functions → [Classes][mdn-classes]\n\n```diff\n-function Person(name, age) {\n-  this.name = name;\n-  this.age = age;\n-}\n-\n-Person.prototype.greet = function() {\n-  return 'Hello, I am ' + this.name;\n-};\n-\n-Person.prototype.getAge = function() {\n-  return this.age;\n-};\n+class Person {\n+  constructor(name, age) {\n+    this.name = name;\n+    this.age = age;\n+  }\n+\n+  greet() {\n+    return 'Hello, I am ' + this.name;\n+  }\n+\n+  getAge() {\n+    return this.age;\n+  }\n+}\n```\n\nTransforms constructor functions (both function declarations and variable declarations) that meet these criteria:\n\n- Function name starts with an uppercase letter\n- At least one prototype method is defined\n- Prototype methods using `this` in arrow functions are skipped\n- Prototype object literals with getters, setters, or computed properties are skipped\n\n#### `console.log()` → [console.info()][mdn-console]\n\n```diff\n-console.log('User logged in:', username);\n-console.log({ userId, action: 'login' });\n+console.info('User logged in:', username);\n+console.info({ userId, action: 'login' });\n```\n\nWhile `console.log` and `console.info` are functionally identical in browsers.\nThis transformation provides semantic clarity by using an explicit log level, but review your logging infrastructure before applying.\n\n#### Remove redundant `'use strict'` from [modules][mdn-strict-mode]\n\n```diff\n-'use strict';\n import { helper } from './utils';\n\n export function main() {\n   return helper();\n }\n```\n\nES6 modules are automatically in strict mode, making explicit `'use strict'` directives redundant. This transformation applies to files with `import` or `export` statements.\n\n#### Global context → [globalThis][mdn-globalthis]\n\n```diff\n-const global = window;\n-const loc = window.location.href;\n+const global = globalThis;\n+const loc = globalThis.location.href;\n```\n\n```diff\n-const global = self;\n-const nav = self.navigator;\n+const global = globalThis;\n+const nav = globalThis.navigator;\n```\n\n```diff\n-const global = Function('return this')();\n+const global = globalThis;\n```\n\n#### Null/undefined checks → [Nullish coalescing operator (??)][mdn-nullish-coalescing]\n\n```diff\n-const value = x !== null \u0026\u0026 x !== undefined ? x : defaultValue;\n+const value = x ?? defaultValue;\n```\n\n```diff\n-const result = obj.prop !== null \u0026\u0026 obj.prop !== undefined ? obj.prop : 0;\n+const result = obj.prop ?? 0;\n```\n\n#### `indexOf()` → [includes()][mdn-includes]\n\n```diff\n-const found = [1, 2, 3].indexOf(item) !== -1;\n-const exists = \"hello\".indexOf(substr) \u003e -1;\n-const hasValue = [\"a\", \"b\", \"c\"].indexOf(value) \u003e= 0;\n+const found = [1, 2, 3].includes(item);\n+const exists = \"hello\".includes(substr);\n+const hasValue = [\"a\", \"b\", \"c\"].includes(value);\n```\n\n```diff\n-if ([1, 2, 3].indexOf(item) === -1) {\n-  console.log('not found');\n-}\n+if (![1, 2, 3].includes(item)) {\n+  console.log('not found');\n+}\n```\n\nTransforms `indexOf()` calls with a single argument (search value) when it can statically verify that the receiver is an array or string (for example, array literals, string literals, or safe method chains).\nCalls with a fromIndex parameter are not transformed as they have different semantics than `includes()`. As a result, patterns such as `[1, 2, 3].indexOf(item) !== -1` are upgraded, while `arr.indexOf(item) !== -1` may be left unchanged if the transformer cannot prove that `arr` is an array.\n\n#### `String.substr()` → [String.slice()][mdn-slice]\n\n```diff\n-const result = \"hello world\".substr(0, 5);\n-const end = \"example\".substr(3);\n+const result = \"hello world\".slice(0, 0 + 5);\n+const end = \"example\".slice(3);\n```\n\nTransforms the deprecated `substr()` method to `slice()`:\n\n- `str.substr(start, length)` becomes `str.slice(start, start + length)`\n- `str.substr(start)` becomes `str.slice(start)`\n- `str.substr()` becomes `str.slice()`\n\nTransformations are limited to when the receiver can be verified as a string (string literals, template literals, or string method chains).\n\n#### `Object.keys().forEach()` → [Object.entries()][mdn-object-entries]\n\n```diff\n-Object.keys(obj).forEach(key =\u003e {\n-  const value = obj[key];\n-  console.log(key, value);\n-});\n+Object.entries(obj).forEach(([key, value]) =\u003e {\n+  console.log(key, value);\n+});\n```\n\nTransforms Object.keys() iteration patterns where the value is accessed from the same object into Object.entries() with array destructuring. This eliminates duplicate property lookups and makes the code more concise.\n\nTransforms when:\n\n- The callback has one parameter (the key)\n- The first statement in the callback assigns `obj[key]` to a variable\n- The object being accessed matches the object passed to Object.keys()\n\n#### `indexOf()` prefix check → [String.startsWith()][mdn-startswith]\n\n```diff\n-const isPrefix = \"hello world\".indexOf(\"hello\") === 0;\n-const notPrefix = str.indexOf(prefix) !== 0;\n+const isPrefix = \"hello world\".startsWith(\"hello\");\n+const notPrefix = !str.startsWith(prefix);\n```\n\nTransforms `indexOf()` prefix checks to the more explicit `startsWith()` method. Transforms when the receiver can be verified as a string and `indexOf()` is compared to `0`.\n\n#### `substring()` prefix check → [String.startsWith()][mdn-startswith]\n\n```diff\n-const matches = \"hello world\".substring(0, prefix.length) === prefix;\n-const noMatch = str.substring(0, prefix.length) !== prefix;\n+const matches = \"hello world\".startsWith(prefix);\n+const noMatch = !str.startsWith(prefix);\n```\n\nTransforms `substring()` prefix comparisons to `startsWith()`. Transforms patterns where `substring(0, prefix.length)` is compared to `prefix`.\n\n#### `lastIndexOf()` suffix check → [String.endsWith()][mdn-endswith]\n\n```diff\n-const isSuffix = str.lastIndexOf(suffix) === str.length - suffix.length;\n-const notSuffix = \"hello world\".lastIndexOf(\"world\") !== \"hello world\".length - \"world\".length;\n+const isSuffix = str.endsWith(suffix);\n+const notSuffix = !\"hello world\".endsWith(\"world\");\n```\n\nTransforms `lastIndexOf()` suffix checks to the more explicit `endsWith()` method. Transforms when the receiver can be verified as a string and the pattern matches `lastIndexOf(suffix) === str.length - suffix.length`.\n\n#### `arguments` object → [Rest parameters ...][mdn-rest-parameters]\n\n```diff\n-function fn() {\n-  const args = Array.from(arguments);\n-  // use args\n-}\n+function fn(...args) {\n+  // use args\n+}\n```\n\n```diff\n-function fn() {\n-  const args = [].slice.call(arguments);\n-  // use args\n-}\n+function fn(...args) {\n+  // use args\n+}\n```\n\nTransforms the `arguments` object to rest parameters when:\n\n- Function is a regular function (not arrow function)\n- Function doesn't already have rest parameters\n- `arguments` is used in the conversion pattern (`Array.from(arguments)` or `[].slice.call(arguments)`)\n- `arguments` is not used elsewhere in the function\n\nThe transformer handles cases where `Array.from(arguments)` has already been converted to `[...arguments]` by other transformers.\n\n#### Manual default values → [Default parameters][mdn-default-parameters]\n\n```diff\n-function fn(x) {\n-  if (x === undefined) x = defaultValue;\n-  // use x\n-}\n+function fn(x = defaultValue) {\n+  // use x\n+}\n```\n\nNote: The `x = x || defaultValue` pattern is NOT transformed as it has different semantics (triggers on any falsy value, instead of `undefined`).\n\n#### Promise chains → [async/await][mdn-async-await]\n\n```diff\n-function getData() {\n-  return fetch('/api/data')\n-    .then(result =\u003e {\n-      // handle result\n-    })\n-    .catch(err =\u003e {\n-      // handle error\n-    });\n-}\n+async function getData() {\n+  try {\n+    const result = await fetch('/api/data');\n+    // handle result\n+  } catch (err) {\n+    // handle error\n+  }\n+}\n```\n\n- The promise chain is returned from the function or used inside an already async function\n- The expression is a known promise (`fetch()`, `new Promise()`, or promise methods)\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-newly-word-dark.svg\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-newly-word.svg\"\u003e\n  \u003cimg alt=\"Baseline: Newly available\" src=\"https://web-platform-dx.github.io/web-features/assets/img/baseline-newly-word.svg\" height=\"32\" align=\"right\"\u003e\n\u003c/picture\u003e\n\n### Newly available\n\nThese transformations are mainly to harden code for future releases and should be used with caution.\n\n#### `new Promise((resolve) =\u003e { ... })` → [Promise.try][mdn-promise-try]\n\n```diff\n-new Promise((resolve) =\u003e {\n-  const result = doSomething();\n-  resolve(result);\n-});\n+Promise.try(() =\u003e {\n+  return doSomething();\n+});\n```\n\n## Versioning\n\nesupgrade uses the [calver] `YYYY.MINOR.PATCH` versioning scheme.\n\nThe year indicates the baseline version. New transformations are added in minor releases, while patches are reserved for bug fixes.\n\n## Related Projects\n\nThanks to these projects for inspiring esupgrade:\n\n- @asottile's [pyupgrade] for Python\n- @adamchainz' [django-upgrade] for Django\n\n### Distinction\n\nlebab is a similar project that focuses on ECMAScript 6+ transformations without considering browser support.\nesupgrade is distinct in that it applies transformations that are safe based on Baseline browser support.\nFurthermore, esupgrade supports JavaScript, TypeScript, and more, while lebab is limited to JavaScript.\n\n[baseline]: https://web.dev/baseline/\n[calver]: https://calver.org/\n[django-upgrade]: https://github.com/adamchainz/django-upgrade\n[mdn-arrow-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions\n[mdn-async-await]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function\n[mdn-classes]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes\n[mdn-console]: https://developer.mozilla.org/en-US/docs/Web/API/console\n[mdn-const]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\n[mdn-default-parameters]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters\n[mdn-endswith]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\n[mdn-exponentiation]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation\n[mdn-for-of]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of\n[mdn-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions\n[mdn-globalthis]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis\n[mdn-includes]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes\n[mdn-let]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\n[mdn-nullish-coalescing]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing\n[mdn-object-entries]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n[mdn-promise-try]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try\n[mdn-rest-parameters]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters\n[mdn-slice]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice\n[mdn-spread]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax\n[mdn-startswith]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith\n[mdn-strict-mode]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#strict_mode_for_modules\n[mdn-template-literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals\n[pre-commit]: https://pre-commit.com/\n[pyupgrade]: https://github.com/asottile/pyupgrade\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingjoe%2Fesupgrade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodingjoe%2Fesupgrade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingjoe%2Fesupgrade/lists"}