Global Windows keyboard listener for Deno with zero dependencies.
import { KeyboardHook, VirtualKeyCodes } from "@nktkas/keyboard-hook";
const hook = new KeyboardHook();
hook.addEventListener("keydown", (event) => {
console.log("Key down:", VirtualKeyCodes[event.detail.vkCode]);
});
hook.addEventListener("keyup", (event) => {
console.log("Key up:", VirtualKeyCodes[event.detail.vkCode]);
});
hook.addEventListener("syskeydown", (event) => {
console.log("System key down:", VirtualKeyCodes[event.detail.vkCode]);
});
hook.addEventListener("syskeyup", (event) => {
console.log("System key up:", VirtualKeyCodes[event.detail.vkCode]);
});
// When done, clean up resources
// hook.close();
/** Contains information about a low-level keyboard input event. */
export interface KeyboardEvent {
/** A {@link VirtualKeyCodes | virtual-key code}. */
vkCode: keyof typeof VirtualKeyCodes;
/** A hardware scan code for the key. */
scanCode: number;
/** The extended-key flag, event-injected flags, context code, and transition-state flag. */
flags: Flags;
/** Time since the system started, in milliseconds. */
time: number;
}
/** Disassembled KBDLLHOOKSTRUCT flags. */
export interface Flags {
/** Set if the key is an extended key (e.g., right Alt, right Ctrl) */
extended: boolean;
/** Set if the event was generated by SendInput with KEYEVENTF_LOWER_IL_INJECTED */
lowerIlInjected: boolean;
/** Set if the event was injected */
injected: boolean;
/** Set if Alt key is pressed */
altDown: boolean;
/** Set if the key is being released (up event) */
up: boolean;
}
/** A class to globally listen for keyboard events in Windows. */
export class KeyboardHook extends EventTarget {
/** Strictly typed addEventListener. */
addEventListener(
type: "keydown" | "keyup" | "syskeydown" | "syskeyup",
listener: (event: CustomEvent<KeyEvent>) => void,
): void;
/** Stops the keyboard hook and cleans up resources. */
close(): void;
}
/** Enumeration of virtual-key codes and their corresponding names. */
export const VirtualKeyCodes = {
/** Left mouse button */
0x01: "LBUTTON",
/** Right mouse button */
0x02: "RBUTTON",
/** Control-break processing */
0x03: "CANCEL",
/** Middle mouse button */
0x04: "MBUTTON",
/** X1 mouse button */
0x05: "XBUTTON1",
/** X2 mouse button */
0x06: "XBUTTON2",
/** Backspace key */
0x08: "BACK",
/** Tab key */
0x09: "TAB",
/** Clear key */
0x0C: "CLEAR",
/** Enter key */
0x0D: "RETURN",
/** Shift key */
0x10: "SHIFT",
/** Ctrl key */
0x11: "CONTROL",
/** Alt key */
0x12: "MENU",
/** Pause key */
0x13: "PAUSE",
/** Caps lock key */
0x14: "CAPITAL",
/** IME Kana mode */
0x15: "KANA",
/** IME On */
0x16: "IME_ON",
/** IME Junja mode */
0x17: "JUNJA",
/** IME final mode */
0x18: "FINAL",
/** IME Kanji mode */
0x19: "KANJI",
/** IME Off */
0x1A: "IME_OFF",
/** Esc key */
0x1B: "ESCAPE",
/** IME convert */
0x1C: "CONVERT",
/** IME nonconvert */
0x1D: "NONCONVERT",
/** IME accept */
0x1E: "ACCEPT",
/** IME mode change request */
0x1F: "MODECHANGE",
/** Spacebar key */
0x20: "SPACE",
/** Page up key */
0x21: "PRIOR",
/** Page down key */
0x22: "NEXT",
/** End key */
0x23: "END",
/** Home key */
0x24: "HOME",
/** Left arrow key */
0x25: "LEFT",
/** Up arrow key */
0x26: "UP",
/** Right arrow key */
0x27: "RIGHT",
/** Down arrow key */
0x28: "DOWN",
/** Select key */
0x29: "SELECT",
/** Print key */
0x2A: "PRINT",
/** Execute key */
0x2B: "EXECUTE",
/** Print screen key */
0x2C: "SNAPSHOT",
/** Insert key */
0x2D: "INSERT",
/** Delete key */
0x2E: "DELETE",
/** Help key */
0x2F: "HELP",
/** 0 key */
0x30: "0",
/** 1 key */
0x31: "1",
/** 2 key */
0x32: "2",
/** 3 key */
0x33: "3",
/** 4 key */
0x34: "4",
/** 5 key */
0x35: "5",
/** 6 key */
0x36: "6",
/** 7 key */
0x37: "7",
/** 8 key */
0x38: "8",
/** 9 key */
0x39: "9",
/** A key */
0x41: "A",
/** B key */
0x42: "B",
/** C key */
0x43: "C",
/** D key */
0x44: "D",
/** E key */
0x45: "E",
/** F key */
0x46: "F",
/** G key */
0x47: "G",
/** H key */
0x48: "H",
/** I key */
0x49: "I",
/** J key */
0x4A: "J",
/** K key */
0x4B: "K",
/** L key */
0x4C: "L",
/** M key */
0x4D: "M",
/** N key */
0x4E: "N",
/** O key */
0x4F: "O",
/** P key */
0x50: "P",
/** Q key */
0x51: "Q",
/** R key */
0x52: "R",
/** S key */
0x53: "S",
/** T key */
0x54: "T",
/** U key */
0x55: "U",
/** V key */
0x56: "V",
/** W key */
0x57: "W",
/** X key */
0x58: "X",
/** Y key */
0x59: "Y",
/** Z key */
0x5A: "Z",
/** Left Windows logo key */
0x5B: "LWIN",
/** Right Windows logo key */
0x5C: "RWIN",
/** Application key */
0x5D: "APPS",
/** Computer Sleep key */
0x5F: "SLEEP",
/** Numeric keypad 0 key */
0x60: "NUMPAD0",
/** Numeric keypad 1 key */
0x61: "NUMPAD1",
/** Numeric keypad 2 key */
0x62: "NUMPAD2",
/** Numeric keypad 3 key */
0x63: "NUMPAD3",
/** Numeric keypad 4 key */
0x64: "NUMPAD4",
/** Numeric keypad 5 key */
0x65: "NUMPAD5",
/** Numeric keypad 6 key */
0x66: "NUMPAD6",
/** Numeric keypad 7 key */
0x67: "NUMPAD7",
/** Numeric keypad 8 key */
0x68: "NUMPAD8",
/** Numeric keypad 9 key */
0x69: "NUMPAD9",
/** Multiply key */
0x6A: "MULTIPLY",
/** Add key */
0x6B: "ADD",
/** Separator key */
0x6C: "SEPARATOR",
/** Subtract key */
0x6D: "SUBTRACT",
/** Decimal key */
0x6E: "DECIMAL",
/** Divide key */
0x6F: "DIVIDE",
/** F1 key */
0x70: "F1",
/** F2 key */
0x71: "F2",
/** F3 key */
0x72: "F3",
/** F4 key */
0x73: "F4",
/** F5 key */
0x74: "F5",
/** F6 key */
0x75: "F6",
/** F7 key */
0x76: "F7",
/** F8 key */
0x77: "F8",
/** F9 key */
0x78: "F9",
/** F10 key */
0x79: "F10",
/** F11 key */
0x7A: "F11",
/** F12 key */
0x7B: "F12",
/** F13 key */
0x7C: "F13",
/** F14 key */
0x7D: "F14",
/** F15 key */
0x7E: "F15",
/** F16 key */
0x7F: "F16",
/** F17 key */
0x80: "F17",
/** F18 key */
0x81: "F18",
/** F19 key */
0x82: "F19",
/** F20 key */
0x83: "F20",
/** F21 key */
0x84: "F21",
/** F22 key */
0x85: "F22",
/** F23 key */
0x86: "F23",
/** F24 key */
0x87: "F24",
/** Num lock key */
0x90: "NUMLOCK",
/** Scroll lock key */
0x91: "SCROLL",
/** Left Shift key */
0xA0: "LSHIFT",
/** Right Shift key */
0xA1: "RSHIFT",
/** Left Ctrl key */
0xA2: "LCONTROL",
/** Right Ctrl key */
0xA3: "RCONTROL",
/** Left Alt key */
0xA4: "LMENU",
/** Right Alt key */
0xA5: "RMENU",
/** Browser Back key */
0xA6: "BROWSER_BACK",
/** Browser Forward key */
0xA7: "BROWSER_FORWARD",
/** Browser Refresh key */
0xA8: "BROWSER_REFRESH",
/** Browser Stop key */
0xA9: "BROWSER_STOP",
/** Browser Search key */
0xAA: "BROWSER_SEARCH",
/** Browser Favorites key */
0xAB: "BROWSER_FAVORITES",
/** Browser Start and Home key */
0xAC: "BROWSER_HOME",
/** Volume Mute key */
0xAD: "VOLUME_MUTE",
/** Volume Down key */
0xAE: "VOLUME_DOWN",
/** Volume Up key */
0xAF: "VOLUME_UP",
/** Next Track key */
0xB0: "MEDIA_NEXT_TRACK",
/** Previous Track key */
0xB1: "MEDIA_PREV_TRACK",
/** Stop Media key */
0xB2: "MEDIA_STOP",
/** Play/Pause Media key */
0xB3: "MEDIA_PLAY_PAUSE",
/** Start Mail key */
0xB4: "LAUNCH_MAIL",
/** Select Media key */
0xB5: "LAUNCH_MEDIA_SELECT",
/** Start Application 1 key */
0xB6: "LAUNCH_APP1",
/** Start Application 2 key */
0xB7: "LAUNCH_APP2",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ;: key */
0xBA: "OEM_1",
/** For any country/region, the + key */
0xBB: "OEM_PLUS",
/** For any country/region, the , key */
0xBC: "OEM_COMMA",
/** For any country/region, the - key */
0xBD: "OEM_MINUS",
/** For any country/region, the . key */
0xBE: "OEM_PERIOD",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the /? key */
0xBF: "OEM_2",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ~ key */
0xC0: "OEM_3",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the [{ key */
0xDB: "OEM_4",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \| key */
0xDC: "OEM_5",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ]} key */
0xDD: "OEM_6",
/** Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '" key */
0xDE: "OEM_7",
/** Used for miscellaneous characters; it can vary by keyboard. */
0xDF: "OEM_8",
/** The <> keys on the US standard keyboard, or the \| key on the non-US 102-key keyboard */
0xE2: "OEM_102",
/** IME PROCESS key */
0xE5: "PROCESSKEY",
/** Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP */
0xE7: "PACKET",
/** Attn key */
0xF6: "ATTN",
/** CrSel key */
0xF7: "CRSEL",
/** ExSel key */
0xF8: "EXSEL",
/** Erase EOF key */
0xF9: "EREOF",
/** Play key */
0xFA: "PLAY",
/** Zoom key */
0xFB: "ZOOM",
/** Reserved */
0xFC: "NONAME",
/** PA1 key */
0xFD: "PA1",
/** Clear key */
0xFE: "OEM_CLEAR",
} as const;
deno run --allow-ffi .\benchmarks\keyhold.ts
Emit to Receive Latency (ms):
┌───────────────┬───────┬───────┬────────┬───────┬───────────┬───────────┬───────┐
│ Duration (ms) │ Min │ Avg │ Median │ Stdev │ 95th %ile │ 99th %ile │ Max │
├───────────────┼───────┼───────┼────────┼───────┼───────────┼───────────┼───────┤
│ 1000 │ 0.026 │ 0.044 │ 0.037 │ 0.028 │ 0.061 │ 0.238 │ 0.303 │
│ 2000 │ 0.025 │ 0.035 │ 0.029 │ 0.018 │ 0.048 │ 0.060 │ 0.269 │
│ 5000 │ 0.024 │ 0.033 │ 0.027 │ 0.017 │ 0.047 │ 0.054 │ 0.485 │
│ 10000 │ 0.024 │ 0.034 │ 0.029 │ 0.012 │ 0.048 │ 0.058 │ 0.429 │
└───────────────┴───────┴───────┴────────┴───────┴───────────┴───────────┴───────┘
deno run --allow-ffi .\benchmarks\keypress.ts
Keydown Latency (ms):
┌───────────┬───────┬───────┬────────┬───────────┬───────────┬───────┐
│ Rate (/s) │ Min │ Avg │ Median │ 95th %ile │ 99th %ile │ Max │
├───────────┼───────┼───────┼────────┼───────────┼───────────┼───────┤
│ 5 │ 0.317 │ 0.460 │ 0.439 │ 0.648 │ 0.682 │ 0.682 │
│ 10 │ 0.285 │ 0.513 │ 0.518 │ 0.685 │ 0.829 │ 0.829 │
│ 20 │ 0.256 │ 0.504 │ 0.535 │ 0.699 │ 0.801 │ 0.833 │
│ 50 │ 0.227 │ 0.362 │ 0.323 │ 0.591 │ 0.685 │ 0.812 │
│ 100 │ 0.212 │ 0.322 │ 0.302 │ 0.501 │ 0.620 │ 0.679 │
└───────────┴───────┴───────┴────────┴───────────┴───────────┴───────┘
Keyup Latency (ms):
┌───────────┬───────┬───────┬────────┬───────────┬───────────┬───────┐
│ Rate (/s) │ Min │ Avg │ Median │ 95th %ile │ 99th %ile │ Max │
├───────────┼───────┼───────┼────────┼───────────┼───────────┼───────┤
│ 5 │ 0.154 │ 0.217 │ 0.206 │ 0.301 │ 0.428 │ 0.428 │
│ 10 │ 0.140 │ 0.291 │ 0.270 │ 0.462 │ 0.611 │ 0.611 │
│ 20 │ 0.117 │ 0.279 │ 0.250 │ 0.475 │ 0.578 │ 0.588 │
│ 50 │ 0.082 │ 0.173 │ 0.140 │ 0.394 │ 0.474 │ 0.515 │
│ 100 │ 0.080 │ 0.130 │ 0.118 │ 0.186 │ 0.415 │ 0.514 │
└───────────┴───────┴───────┴────────┴───────────┴───────────┴───────┘
@nktkas/mouse-hook
- Global Windows mouse listener for Deno with zero
dependencies.
@nktkas/windows-screenshot
- Windows screen capture for Deno with zero
dependencies.