
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
react-modifiers
Advanced tools
Use modifiers to intercept event handling more concisely in React, like "stop", "prevent".
Use modifiers to enhance event handling concisely in React.
This package brings Vue-style event modifiers to React, enabling concise and intuitive event handling interception. With React Modifiers, you can chain modifiers to restrict when event handlers execute, eliminating boilerplate code for event filtering, propagation control, and modifier key checks.
# npm
npm install react-modifiers
# yarn
yarn add react-modifiers
# pnpm
pnpm add react-modifiers
Import the mod utility and chain modifiers to your event handlers:
Trigger a handler only when the Ctrl+L shortcut is pressed:
import mod from "react-modifiers";
<button onKeyDown={mod.ctrl.l(e => {
console.log("Ctrl+L pressed!");
})} />
Prevent event bubbling and browser default behavior before executing the handler:
import mod from "react-modifiers";
<button onClick={mod.stop.prevent(e => {
console.log("Click handled without propagation/default behavior!");
})} />
// Or just
<button onClick={mod.handled(e => {
console.log("Click handled without propagation/default behavior!");
})} />
The handler function can be ignored, it will only handled by modifiers.
import mod from "react-modifiers";
<form onSubmit={mod.prevent()} />
Modifiers are executed in the order they are chained. This affects behavior:
mod.prevent.self: Prevents default behavior for all clicks (element + children)mod.self.prevent: Prevents default behavior only for clicks on the element itselfFor keyboard modifier key modifiers (ctrl/shift/alt/meta): Chained modifiers mean AND (all must be pressed)
For other modifiers—keyboard character/function key modifiers, mouse button modifiers, pointer type modifiers—except universal modifiers (e.g., a/b/space/tab/enter/middle/right/touch): Chained modifiers mean OR (any one pressed or used)
Apply to any React synthetic event type:
| Modifier | Behavior |
|---|---|
.stop | Calls event.stopPropagation() |
.prevent | Calls event.preventDefault() |
.handled | Shorthand for .stop.prevent (calls both methods) |
.self | Triggers handler only if the event originates from the element itself (not children) |
.once | Triggers handler a maximum of one time |
Apply to keyboard, mouse, or pointer events (case-insensitive):
| Modifier | Behavior |
|---|---|
.ctrl | Triggers handler only when Ctrl/Control key is pressed |
.shift | Triggers handler only when Shift key is pressed |
.alt | Triggers handler only when Alt/Option key is pressed |
.meta | Triggers handler only when Win/Command key is pressed |
.capsLockOn | Triggers handler only when CapsLock is active |
.capsLockOff | Triggers handler only when CapsLock is inactive |
.numLockOn | Triggers handler only when NumLock is active |
.numLockOff | Triggers handler only when NumLock is inactive |
.scrollLockOn | Triggers handler only when ScrollLock is active |
.scrollLockOff | Triggers handler only when ScrollLock is inactive |
.exact | Enforces exact modifier key combination (no extra keys) |
[!NOTE]
.ctrlworks for both left and right Ctrl/Control key (similar to other modifier keys).- Do not use both
.capsLockOnand.capsLockOff(similar to other lock keys) simultaneously, this will never trigger the handler!
.exact Examples// Triggers if Ctrl is pressed (even with Alt/Shift)
<button onClick={mod.ctrl(handleClick)} />
// Triggers ONLY if Ctrl is pressed (no other modifier keys)
<button onClick={mod.ctrl.exact(handleClick)} />
// Triggers ONLY if no modifier keys are pressed
<button onClick={mod.exact(handleClick)} />
[!NOTE]
You can put
.exactanywhere. The following code has the same behavior.<button onKeyDown={mod.ctrl.p.exact(handleClick)} /> <button onKeyDown={mod.exact.ctrl.p(handleClick)} /> <button onKeyDown={mod.ctrl.exact.p(handleClick)} />
Apply exclusively to keyboard events (onKeyDown/onKeyUp/onKeyPress):
Common keys supported (case-insensitive):
.enter, .tab, .delete, .backspace, .space, .esc.up, .down, .left, .right.pageUp, .pageDown, .home, .end, .printScreen, .pause, .insert.a, .b, ..., .z, [0], [1], ..., [9], ["`"], ["/"], ["\\"]).application (also known as context menu key)[!NOTE]
- Number and special symbols (e.g.,
`,/,\) must be wrapped in brackets:
mod.ctrl["/"](handler)mod.ctrl["\\"](handler)mod.ctrl[0](handler)- Do not use shift-modified symbol keys (e.g.
!,@,#,?), just use primary symbol keys (e.g.-,=,;,').
[0] works for both 0/) key and numpad 0/Insert key. Same as other numbers, ["."], ["-"], ["/"], .enter.["+"] is an alias of ["="], and it works for both =/+ key and numpad + key.["*"] works for numpad * key only, it doesn't work for 8/* key.| Modifier | Behavior |
|---|---|
.arrow | Shorthand for .up.down.left.right (any arrow key) |
.noRepeat | Triggers handler only once for held keys (ignores event.repeat = true) |
// Ctrl+Shift+L OR Ctrl+Shift+P (L/P = OR; Ctrl/Shift = AND)
<button onKeyDown={mod.ctrl.shift.l.p(handleKeyDown)} />
// Ctrl+Shift+L (stop propagation) OR Ctrl+Shift+P (no stop)
<button onKeyDown={mod.ctrl.shift.l.stop.p(handleKeyDown)} />
// Ctrl+/ (special symbol via bracket notation)
<button onKeyDown={mod.ctrl["/"](handleKeyDown)} />
// Arrow key (up/down/left/right) with no repeat
<button onKeyDown={mod.arrow.noRepeat(handleKeyDown)} />
Apply to mouse or pointer events (onClick/onMouseDown/onPointerUp etc.):
| Modifier | Behavior |
|---|---|
.left | Triggers handler only for left mouse button clicks |
.right | Triggers handler only for right mouse button clicks |
.middle | Triggers handler only for middle mouse button clicks |
You can chain them together to indicate that any of them can trigger the handler.
// Triggers handler for both middle mouse button and right mouse button
// Left mouse button will not trigger the handler
<button onClick={mod.middle.right(handleClick)} />
Apply exclusively to pointer events (onPointerDown/onPointerEnter etc.):
| Modifier | Behavior |
|---|---|
.mouse | Triggers handler only for mouse input |
.touch | Triggers handler only for touch input (mobile/tablet) |
.pen | Triggers handler only for stylus/pen input |
You can chain them together to indicate that any of them can trigger the handler.
// Triggers handler for both touch and pen input
// Mouse will not trigger the handler
<button onPointerDown={mod.touch.pen(handleTouch)} />
// Ctrl + mouse left click (Not Ctrl+Left Arrow!)
<button onClick={mod.ctrl.left(handleCtrlClick)} />
// Shift + touch screen, with NumLock on
<button onClick={mod.shift.touch.numLockOn(handleShiftTouch)} />
// Prevent default, trigger once, right click only (self)
<button onClick={mod.prevent.once.right.self(handleRightClick)} />
// Mouse or touch input, middle or right click only if mouse input
<button onPointerUp={mod.middle.right.mouse.touch(handleClick)} />
// Ctrl+Shift+Delete (prevent default) OR Ctrl+Shift+Backspace (stop propagation)
<button onKeyDown={mod.ctrl.shift.delete.prevent.backspace.stop(handleKeyDown)} />
TypeScript Support: Full TypeScript support. Due to technical limitations, the modifiers for non specific events will also be displayed in the suggestion list, but it can report errors normally after use.
Case-Insensitive: All modifiers are case-insensitive. However, TypeScript will suggest the most appropriate camel case.
Event Type Compatibility: Ensure modifiers match the event type (e.g., .touch only works with onPointerDown, not onKeyDown).
Chaining Order: Always test modifier order—execution is sequential (e.g., .self.prevent ≠ .prevent.self).
Do not Duplicate: Duplicate modifiers will not have any effect, they will only waste your traffic out of thin air.
Synthetic Events And Native Events: React Modifiers work with both React synthetic events and native DOM events.
Browser Support: Follows React's browser support matrix—modifiers like .touch require PointerEvent support (modern browsers); .noRepeat require Chromium 137 and above.
react-modifiers is available under the MIT License. See the LICENSE file for more info.
FAQs
Use modifiers to intercept event handling more concisely in React, like "stop", "prevent".
We found that react-modifiers demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.