Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Oxlint JS plugins

Avatar for kazupon kazupon
February 06, 2026

Oxlint JS plugins

Avatar for kazupon

kazupon

February 06, 2026
Tweet

More Decks by kazupon

Other Decks in Programming

Transcript

  1. Vue Fes Japan Organizer Vue.js Japan User Group Organizer Vue.js

    Core Team Nuxt Ecosystem Team Vue I18n, Intlify and Gunshi author Plaid, inc. @kazu_pon kazupon kazupon
  2. Agenda • What’s Oxlint? • Features • Background • JS

    Plugins • Features • JS pluigins in Depth • Closing
  3. NOTICE • Oxlint JS Plugins is still Preview • Oxlint

    architecture that I'm talking contents might be changed
  4. Oxlint • A High-Performance Linter for JS / TS •

    Performance • 50 to 100x faster than ESLint • Built on the OXC project stack • oxc parser • oxc allocator • … and etc https://github.com/oxc-project/bench-linter?tab=readme-ov- fi le#macbook-pro-m4-max-64-gb-1
  5. The background of Oxlint • 2023-02-01: Post `Rewrite ESLint in

    Rust` https://github.com/ansuz/RIIR/issues/97 • 2023-02-09: Start OXC Project as an OSS https://github.com/oxc-project/oxc Start an OSS project!
  6. How was ESLint reaction for Oxlint? • 2023-03-28: Post an

    idea of Oxlint collaboration on `Complete rewrite of ESLint` issue https://github.com/eslint/eslint/discussions/16557#discussioncomment-5448823 • But, It didn’t go well …
  7. Typeware linting • Powered by tsgolint (oxc-tsgolint) • We can

    use typescript-eslint typeware rule! • And, We can type-check with lint!
  8. Migration from ESLint • ESLint frat con fi g to

    oxlint con fi g • Running ESLint together with eslint-plugin-oxlint
  9. ESLint compatible API • The making is the same as

    ESLint • Support all most of API’s surface • AST traversal • AST exploration • Fixes • Rules option • Selectors • SourceCode (include tokens) APIs • Scope analysis • De fi ne plugin De fi ne rule
  10. Altanative API • More high performance than ESLint APIs •

    Ofcouse, It has ESLint APIs almost compatible • de fi nePlugin • de fi neRule • createOnce • before • after
  11. Altanative API Structure de fi nePlugin de fi neRule Apply

    to each rule & optimize Rule works for Oxlint & ESLint ※ is alternative APIs Wraps rule object & add `create`
  12. Altanative API Structure de fi nePlugin de fi neRule createOnce

    VisitorHooks before after AST Visitor Apply to each rule & optimize Wraps rule object & add `create` Returns Per- fi le Per- fi le Per-AST node Rule works for Oxlint & ESLint ※ is alternative APIs Call rule once only Initalize state Retrun `false` to skip ClassDeclaration FunctionDeclaration … Cleanup resources Final analysis
  13. Oxlint workflow 1. Initialize CLI & Register callbacks 2. Initalize

    Rust layer 3. Resolve JS plugins & loading 4. Sync con fi grations 5. Lint with built-in plugins 6. Lint with JS plugins 7. Report Diagonistic 8. Clearn up
  14. 5. Lint with built-in plugins Lint with built-in rules -

    eslint - typescript-eslint - jsdoc - … and etc
  15. Raw Transfer • A mechanism for transferring AST generated in

    Rust to JS plugins with zero-copy • JSON: ~100ms = Serialize (~50ms) + Transfer (~20ms) + Deserialize in JS (~30ms) • Raw Transfer: ~1-5ms = Create buffer (~1ms) + Point to data (~0.1ms) + Access on-demand Raw Transfer JSON Serialization Memory 1x (shared buffer) 2x (original + JSON) Speed O(1) pointer reads O(n) deserialization Garbage Collection Minimal (buffer reused) Major (copies freed)
  16. Memory architecture • Create buffer aligned at 4GB boundary, size

    2GB using. • All AST nodes are allocated in the fi xed-size allocator • Convert Spans (Loc) UTF-8 to UTF-16 • Write RawTransfer Metadata, including the offset to AST `Program` • Create `UInt8Array` to share for JS layer • Pass the buffer to JS via Callback (NAPI `ThreadsafeFunction`) 0x_00000003_00000000 (free region) Program (AST root) - source_type - body - comments Statement nodes Expression nodes Identi fi er nodes, and etc … ChunkFooter (48 bytes) RawTransfer Metadata (16 bytes) - _padding: u64 - data_offset: u32 = 0x7FFF8A00 - comments - is_ts, is_jsx, has_bom 0x_00000003_7FFF8A00 0x_00000003_7FFF9200 0x_00000003_7FFFA800 0x_00000003_7FFFE000 0x_00000003_7FFFFFA0 0x_00000003_7FFFFFD0 0x_00000003_7FFFFFE0 Case: Allocated in 12GB area chunk ptr ptr
  17. • Desirialize for All AST Nodes! JSON base AST problem

    oxc_parser JSON Serializer JSON Strings Codes (*.js, *.ts) AST (In Memory) JSON Deserializer AST (JS Objects) JSON Strings Linter Parse Rust Layer JavaScript Layer Serialize Desirialize Copy & Transfer Use All nodes serialize … All nodes desierialize …
  18. • AST Node is Just In Time Approchi of Lazy

    Desirializaion oxc_parser UInt8Array Codes (*.js, *.ts) AST (Fixed size) UInt8Array Parse Rust Layer JavaScript Layer Wrap Construct Share the pointer as Raw Transer (zero copy) AST (Just In Time) (~2GB, 4GB algined) ast = { buffer, sourceText, nodes: Map, token } return { get program() get comments() visit() dispose() } walk.js Oxlint Lazy generation Read `Program`
  19. JS plugins performance • DEMO contents • eslint core rule

    + eslint-plugin-regexp for javascript codes • Targets: node/lib https://github.com/nodejs/node/tree/main/lib • eslint core rule + eslint-plugin-regexp for typescript codes • Targets: vscode https://github.com/microsoft/vscode
  20. Demo Result • Env: MacBook Pro, Chipset Apple M1 Max,

    Memory 64 GB https://github.com/kazupon/oxlint-js-plugin-benchmark-demo
  21. Closing • Oxlint works by having the JS layer and

    Rust layer work together to run JS plugins • JS plugins are loaded into the JS layer via dynamic import • Con fi guration information is passed from the Rust layer to the JS layer and used during plugin execution • Oxlint has core technology for running JS plugins • Raw Transfer • Lazy Deserialization