Skip to content

[Feature] Add ESLint plugin for js-toolkit best practices#727

Merged
titouanmathis merged 34 commits intomainfrom
feat/linting-plugin
May 7, 2026
Merged

[Feature] Add ESLint plugin for js-toolkit best practices#727
titouanmathis merged 34 commits intomainfrom
feat/linting-plugin

Conversation

@titouanmathis
Copy link
Copy Markdown
Contributor

🔗 Linked issue

N/A

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Adds a new @studiometa/eslint-plugin-js-toolkit package — an ESLint v9 / oxlint plugin that enforces best practices for projects using @studiometa/js-toolkit.

20 rules across 5 categories:

  • Class structure: require-config, require-config-name-pascal-case, refs-camel-case, refs-plural-multiple, options-camel-case, refs-no-bracket-access, require-refs-declared-in-config
  • Lifecycle: async-lifecycle-methods
  • Event handlers: on-handler-naming, on-global-handler-prefix, no-event-listener-methods
  • Forbidden patterns: no-deprecated-properties, no-dispatch-event, no-shadow-dom, no-create-app, no-deep-utils-import, no-shadow-dom
  • Preferred patterns: no-redundant-with-mount-when-in-view, no-manual-intersection-observer, no-manual-mutation-observer, prefer-ref-over-query-selector

The plugin ships a configs.recommended flat config entry with sane defaults. The .oxlintrc.json at the root is updated to use the plugin locally.

📝 Checklist

  • I have linked an issue or discussion.
  • I have added tests (if possible).
  • I have updated the documentation accordingly.
  • I have updated the changelog.

titouanmathis and others added 30 commits May 7, 2026 22:37
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…el-case and require-config-name-pascal-case rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…emoved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- no-deep-utils-import (error, fixable)
- refs-no-bracket-access (error, fixable)
- no-redundant-with-mount-when-in-view (warn)
- prefer-ref-over-query-selector (warn)
- require-refs-declared-in-config (error)
- no-manual-intersection-observer (warn)
- no-manual-mutation-observer (warn)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Export Size

Unchanged

@studiometa/js-toolkit

Name Size Diff
AbstractService 528 B -
addClass 226 B -
addStyle 238 B -
ALL 20.71 kB -
animate 3.27 kB -
Base 8.71 kB -
BASE 8.76 kB -
boundingRectToCircle 154 B -
cache 194 B -
camelCase 397 B -
clamp 67 B -
clamp01 87 B -
closestComponent 418 B -
collideCircleCircle 99 B -
collideCircleRect 159 B -
collidePointCircle 112 B -
collidePointRect 103 B -
collideRectRect 99 B -
createApp 893 B -
createEaseInOut 116 B -
createEaseOut 71 B -
createElement 592 B -
createLocalStorage 1.19 kB -
createLocalStorageProvider 264 B -
createMemoryStorageProvider 146 B -
createNoopProvider 96 B -
createRange 90 B -
createSessionStorage 1.23 kB -
createSessionStorageProvider 254 B -
createStorage 1.17 kB -
createUrlSearchParamsInHashProvider 413 B -
createUrlSearchParamsInHashStorage 1.21 kB -
createUrlSearchParamsProvider 386 B -
createUrlSearchParamsStorage 1.21 kB -
damp 78 B -
dashCase 372 B -
debounce 92 B -
DECORATORS 7.59 kB -
defineFeatures 322 B -
domScheduler 296 B -
DragService 1.94 kB -
ease 435 B -
easeInCirc 68 B -
easeInCubic 59 B -
easeInExpo 80 B -
easeInOutCirc 141 B -
easeInOutCubic 130 B -
easeInOutExpo 134 B -
easeInOutQuad 128 B -
easeInOutQuart 133 B -
easeInOutQuint 152 B -
easeInOutSine 151 B -
easeInQuad 63 B -
easeInQuart 61 B -
easeInQuint 62 B -
easeInSine 77 B -
easeLinear 49 B -
easeOutCirc 115 B -
easeOutCubic 103 B -
easeOutExpo 112 B -
easeOutQuad 103 B -
easeOutQuart 100 B -
easeOutQuint 103 B -
easeOutSine 121 B -
endsWith 88 B -
FRAMEWORK 13.63 kB -
getAncestorWhere 91 B -
getAncestorWhereUntil 119 B -
getClosestParent 182 B -
getComponentResolver 138 B -
getDirectChildren 201 B -
getInstanceFromElement 92 B -
getInstances 185 B -
getOffsetSizes 159 B -
hasWindow 62 B -
HELPERS 2.43 kB -
historyPush 499 B -
historyReplace 503 B -
importOnInteraction 887 B -
importOnMediaQuery 236 B -
importWhenIdle 223 B -
importWhenPrefersMotion 275 B -
importWhenVisible 912 B -
inertiaFinalValue 142 B -
isArray 70 B -
isBoolean 78 B -
isDefined 86 B -
isDev 72 B -
isDirectChild 219 B -
isEmpty 207 B -
isEmptyString 93 B -
isFunction 72 B -
isNull 72 B -
isNumber 84 B -
isObject 105 B -
isString 86 B -
keyCodes 97 B -
KeyService 854 B -
lerp 57 B -
loadElement 169 B -
loadIframe 189 B -
loadImage 188 B -
loadLink 186 B -
loadScript 197 B -
LoadService 593 B -
localStorageProvider 715 B -
logTree 510 B -
lowerCase 60 B -
map 71 B -
matrix 106 B -
mean 91 B -
memo 100 B -
memoize 189 B -
memoryStorageProvider 607 B -
MutationService 799 B -
nextFrame 162 B -
nextMicrotask 111 B -
nextTick 134 B -
noop 39 B -
noopValue 49 B -
objectToURLSearchParams 302 B -
pascalCase 374 B -
PointerService 1.07 kB -
queryComponent 485 B -
queryComponentAll 494 B -
Queue 226 B -
RafService 956 B -
random 64 B -
randomInt 77 B -
randomItem 211 B -
registerComponent 103 B -
removeClass 222 B -
removeStyle 238 B -
ResizeService 1.01 kB -
round 56 B -
saveActiveElement 56 B -
ScrollService 1.28 kB -
scrollTo 2.31 kB -
SERVICES 4.01 kB -
sessionStorageProvider 712 B -
SmartQueue 411 B -
smoothTo 473 B -
snakeCase 374 B -
spring 115 B -
startsWith 87 B -
throttle 101 B -
toggleClass 225 B -
transform 288 B -
transition 916 B -
trapFocus 363 B -
tween 1.72 kB -
untrapFocus 45 B -
upperCase 54 B -
urlSearchParamsInHashProvider 537 B -
urlSearchParamsProvider 539 B -
useDrag 1.98 kB -
useKey 871 B -
useLoad 610 B -
useMutation 829 B -
usePointer 1.09 kB -
useRaf 963 B -
useResize 1.02 kB -
useScheduler 290 B -
useScroll 1.29 kB -
UTILS 9.59 kB -
wait 79 B -
withBreakpointManager 1.42 kB -
withBreakpointObserver 1.61 kB -
withDrag 2.09 kB -
withExtraConfig 135 B -
withFreezedOptions 140 B -
withGroup 252 B -
withIntersectionObserver 260 B -
withLeadingCharacters 88 B -
withLeadingSlash 107 B -
withMountOnMediaQuery 322 B -
withMountWhenInView 286 B -
withMountWhenPrefersMotion 355 B -
withMutation 959 B -
withName 81 B -
withoutLeadingCharacters 86 B -
withoutLeadingCharactersRecursive 124 B -
withoutLeadingSlash 93 B -
withoutTrailingCharacters 98 B -
withoutTrailingCharactersRecursive 129 B -
withoutTrailingSlash 103 B -
withRelativePointer 1.23 kB -
withResponsiveOptions 2.26 kB -
withScrolledInView 2.93 kB -
withTrailingCharacters 96 B -
withTrailingSlash 120 B -
wrap 77 B -

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

❌ Patch coverage is 93.49241% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.99%. Comparing base (7d8e196) to head (0e2f337).

Files with missing lines Patch % Lines
packages/eslint-plugin-js-toolkit/src/utils/ast.ts 83.72% 5 Missing and 2 partials ⚠️
...olkit/src/rules/require-refs-declared-in-config.ts 88.00% 4 Missing and 2 partials ⚠️
...-plugin-js-toolkit/src/rules/options-camel-case.ts 92.59% 2 Missing ⚠️
...int-plugin-js-toolkit/src/rules/refs-camel-case.ts 92.59% 2 Missing ⚠️
...lugin-js-toolkit/src/rules/refs-plural-multiple.ts 92.30% 2 Missing ⚠️
...olkit/src/rules/require-config-name-pascal-case.ts 91.30% 2 Missing ⚠️
...lint-plugin-js-toolkit/src/rules/require-config.ts 91.30% 2 Missing ⚠️
...in-js-toolkit/src/rules/async-lifecycle-methods.ts 92.85% 1 Missing ⚠️
...n-js-toolkit/src/rules/no-deprecated-properties.ts 93.33% 1 Missing ⚠️
...t-plugin-js-toolkit/src/rules/no-dispatch-event.ts 93.75% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #727      +/-   ##
==========================================
- Coverage   98.51%   97.99%   -0.53%     
==========================================
  Files         131      153      +22     
  Lines        2965     3386     +421     
  Branches      727      898     +171     
==========================================
+ Hits         2921     3318     +397     
- Misses         42       62      +20     
- Partials        2        6       +4     
Flag Coverage Δ
eslint-plugin-js-toolkit 93.07% <93.07%> (?)
js-toolkit 97.99% <93.49%> (?)
unittests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 7, 2026

Merging this PR will not alter performance

✅ 115 untouched benchmarks


Comparing feat/linting-plugin (0e2f337) with main (7d8e196)

Open in CodSpeed

@titouanmathis titouanmathis merged commit d2d12fe into main May 7, 2026
10 checks passed
@titouanmathis titouanmathis deleted the feat/linting-plugin branch May 7, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant