Roll out v3 (modern flat config) across consumer repos
Now that @playcanvas/eslint-config@3.0.0-beta.x is installable and published on the beta dist-tag, this tracks migrating every active public PlayCanvas repo that consumes the config onto v3 — plus bringing a couple of active repos that don't yet use it (create-playcanvas, react) onto the shared config. vscode-extension is the proof of concept (CommonJS + /typescript).
All open consumer PRs below pin 3.0.0-beta.6. Status legend: 🟢 ready (open · CI green) · 🟡 draft (open · held on strict-error triage) · 🟣 merged · 🔴 not started (no PR yet).
Tracking
The breaking change every consumer must make
In v3 the default export is an object { legacy, typescript, react }, not a spreadable array. So the v2 pattern breaks and must switch to a subpath import:
- import playcanvasConfig from '@playcanvas/eslint-config';
- export default [...playcanvasConfig, /* overrides */];
+ import typescript from '@playcanvas/eslint-config/typescript'; // or /javascript, /legacy
+ export default [...typescript, /* overrides */];
Notes:
- Tiers:
/typescript (modern strict), /javascript = /legacy (the v2 ruleset — ~drop-in, no new errors), /react.
/react is additive-only (JSX / a11y / hooks, no base rules) — React repos must compose /typescript + /react (in that order) or they end up silently under-linted.
- Prettier now runs as its own step via the shared
/prettier config + eslint-config-prettier (drop eslint-plugin-prettier).
esmScriptTags is re-exported from the package root so the engine can extend JSDoc definedTags without reaching into config internals.
/typescript bundles neither jsdoc nor regexp (they live in /legacy). Migrating a TS repo that had jsdoc/* or regexp/* rules or inline eslint-disable directives will surface "Definition for rule … was not found" — remove the stale references/directives as part of triage.
- Triage policy for the
/typescript drafts: keep the shared config strict and adapt the repos to pass (no rule weakening); no-explicit-any stays an error. Only planned config touches are eslint-plugin-chai-friendly (chai-assertion false-positives) and scoped inline-disables where TypeScript requires interface (declaration merging).
- Known config gap: subpath exports ship no type declarations (only
/prettier does), so eslint.config.mjs imports show as implicit any in TS-aware editors. Cosmetic; doesn't affect linting.
Skipped (intentionally out of scope)
playcanvas-spine — still on v1 (^1.7.1); needs an ESLint-9 flat-config migration before it can take v3 at all. Revisit when it modernizes.
playcanvas-inspector — on v1 (^1.0.16) and dormant (last commit 2022).
playcanvas-tween — dormant (last commit Jan 2025).
markdown-translator — dormant (last commit Jul 2025).
Promote 3.0.0 → latest
Target the end of Wave 2. Promotion is low-risk on its own — every consumer pins 2.1.0/^2.x, so flipping latest force-upgrades no one; it only changes what a bare install and the repo template resolve to. Before promoting:
Roll out v3 (modern flat config) across consumer repos
Now that
@playcanvas/eslint-config@3.0.0-beta.xis installable and published on thebetadist-tag, this tracks migrating every active public PlayCanvas repo that consumes the config onto v3 — plus bringing a couple of active repos that don't yet use it (create-playcanvas,react) onto the shared config.vscode-extensionis the proof of concept (CommonJS +/typescript).All open consumer PRs below pin
3.0.0-beta.6. Status legend: 🟢 ready (open · CI green) · 🟡 draft (open · held on strict-error triage) · 🟣 merged · 🔴 not started (no PR yet).Tracking
vscode-extension/typescriptobserver/typescriptcanvas-mock/javascriptpcui-graph/legacysupersplat-viewer/typescriptplaycanvas-sync/legacyattribute-parser/javascripteditor-mcp-server/typescripttexture-tool/typescriptmodel-viewer/typescript+/reactweb-components/typescriptsplat-transform/typescriptpcui/typescript+/reactsupersplat/typescripteditor/typescriptengine/javascript1create-playcanvas/typescriptreact/typescript+/reactThe breaking change every consumer must make
In v3 the default export is an object
{ legacy, typescript, react }, not a spreadable array. So the v2 pattern breaks and must switch to a subpath import:Notes:
/typescript(modern strict),/javascript=/legacy(the v2 ruleset — ~drop-in, no new errors),/react./reactis additive-only (JSX / a11y / hooks, no base rules) — React repos must compose/typescript+/react(in that order) or they end up silently under-linted./prettierconfig +eslint-config-prettier(dropeslint-plugin-prettier).esmScriptTagsis re-exported from the package root so the engine can extend JSDocdefinedTagswithout reaching into config internals./typescriptbundles neitherjsdocnorregexp(they live in/legacy). Migrating a TS repo that hadjsdoc/*orregexp/*rules or inlineeslint-disabledirectives will surface "Definition for rule … was not found" — remove the stale references/directives as part of triage./typescriptdrafts: keep the shared config strict and adapt the repos to pass (no rule weakening);no-explicit-anystays an error. Only planned config touches areeslint-plugin-chai-friendly(chai-assertion false-positives) and scoped inline-disables where TypeScript requiresinterface(declaration merging)./prettierdoes), soeslint.config.mjsimports show as implicitanyin TS-aware editors. Cosmetic; doesn't affect linting.Skipped (intentionally out of scope)
playcanvas-spine— still on v1 (^1.7.1); needs an ESLint-9 flat-config migration before it can take v3 at all. Revisit when it modernizes.playcanvas-inspector— on v1 (^1.0.16) and dormant (last commit 2022).playcanvas-tween— dormant (last commit Jan 2025).markdown-translator— dormant (last commit Jul 2025).Promote
3.0.0→latestTarget the end of Wave 2. Promotion is low-risk on its own — every consumer pins
2.1.0/^2.x, so flippinglatestforce-upgrades no one; it only changes what a bare install and the repotemplateresolve to. Before promoting:enginehas at least a green proof-of-concept branch3.0.0and move thelatestdist-tagtemplateto the v3 subpath import so new repos inherit v3npm dist-tag add @playcanvas/eslint-config@2.1.0 latestFootnotes
enginealso rewrites the v2playcanvasConfig.find(...)JSDocdefinedTagshack to the directimport { esmScriptTags }, and migrates theexamples/secondary config to/javascript+/react. Highest blast radius — done last. Theexamples//reactruleset still needs config-level tuning (react-in-jsx-scopeunder the React 19 JSX transform,prop-types,import/extensions) — tracked in the PR. ↩New adoptions, not v2→v3 migrations — these two don't currently consume
@playcanvas/eslint-config.create-playcanvashas no shared-config dependency today;reactruns its own flat config (eslint 9 + typescript-eslint + eslint-plugin-react + eslint-plugin-react-compiler, apackages/*monorepo). Adopting v3 here replaces their existing setup, so expect more than a drop-in. ↩ ↩2