@codemod/javascript-use-add-remove-event-listener
Codemod for JavaScript (browser DOM code) that rewrites direct on* handler property usage (e.g., elem.onclick = fn, window.onresize = fn) to explicit addEventListener/removeEventListener patterns, improving consistency, composability, and lint compliance (unicorn/prefer-add-event-listener).
Installation
bash
Usage
This codemod targets browser-oriented *.js, *.jsx, *.mjs, *.cjs, *.ts, and *.tsx files and rewrites safe on* property assignments on likely DOM EventTarget receivers.
Rewritten patterns:
el.onclick = onClick->el.addEventListener('click', onClick)window.onresize = handleResize->window.addEventListener('resize', handleResize)doc.body.onkeydown = (event) => key(event)->doc.body.addEventListener('keydown', (event) => key(event))el.onclick = handler; ... el.onclick = null->el.addEventListener('click', handler); ... el.removeEventListener('click', handler)- Inline function teardown pairs are hoisted to a stable local listener variable before converting to
addEventListener/removeEventListener
Receiver inference is intentionally conservative. The codemod rewrites globals like window and document, variables typed as DOM event targets, values derived from common DOM APIs such as document.getElementById() and document.querySelector(), document aliases like doc: Document, and typed this.<field> DOM wrappers inside classes.
Preserved as-is by default:
- Computed properties such as
obj['onclick'] = fnorel['on' + evt] = fn - Camel-case custom properties such as
obj.onClick = fn - Non-DOM or unknown receivers such as
customStore.onchange = fn - Read-only access such as
if (el.onclick) - Invalid assignments such as
el.onclick = 42 - Reassignment chains such as
el.onclick = first; el.onclick = second; - Unmatched clears such as
el.onclick = null
Pairing is intentionally conservative. The codemod only rewrites add/remove pairs when the setup and clear are compatible within the same lexical scope and the handler reference is valid at the clear site. Unmatched clears and ambiguous overwrite patterns are left unchanged.
Development
bash
License
MIT