
Research
/Security News
Fake imToken Chrome Extension Steals Seed Phrases via Phishing Redirects
Mixed-script homoglyphs and a lookalike domain mimic imToken’s import flow to capture mnemonics and private keys.
emit-keypress
Advanced tools
Drop-dead simple keypress event emitter for Node.js. Create powerful CLI applications and experiences with ease.
Drop-dead simple keypress event emitter for Node.js. Create powerful CLI applications and experiences with ease.
Please consider following this project's author, Jon Schlinkert, and consider starring the project to show your :heart: and support.
Install with npm:
$ npm install --save emit-keypress
Node's built-in readline module is great for handling user input if you need something simple. But when using createInterface, there are a number of built-in behaviors that are difficult or impossible to override when you need more control over the input stream.
Other keypress modules I found either did too much, or didn't allow for enough customization. This module is designed to be simple, flexible, easy to use, and easy to customize.
Create your own CLI interface
It's lightweight with only one dependency for detecting the terminal. It's easy to use, and easy to customize. It's designed to be used in a wide range of use-cases, from simple command-line utilities to complex terminal applications.
Powerful CLI applications can be built with this module.
import { emitKeypress } from 'emit-keypress';
emitKeypress({ input: process.stdin });
process.stdin.on('keypress', (input, key) => {
console.log({ input, key });
if (input === '\x03' || input === '\r') {
process.stdin.pause();
}
});
Pass an onKeypress function to emitKeypress to handle keypress events.
// The "close" function is passed as the third argument
const onKeypress = async (input, key, close) => {
// do stuff with keypress events
console.log({ input, key });
// Close the stream if the user presses `Ctrl+C` or `Enter`
if (input === '\x03' || input === '\r') {
close();
}
};
emitKeypress({ onKeypress });
A close function is also returned from emitKeypress that can be called to close the stream.
const { close } = emitKeypress({ onKeypress });
// close the stream
setTimeout(() => {
close();
}, 10_000);
Pass a keymap array to map keypress events to specific shortcuts.
emitKeypress({
keymap: [
{ sequence: '\x03', shortcut: 'ctrl+c' },
{ sequence: '\r', shortcut: 'return' }
],
onKeypress: async (input, key, close) => {
// do stuff with keypress events
console.log({ input, key });
if (key.shortcut === 'return' || key.shortcut === 'ctrl+c') {
close();
}
}
});
Note that you can add arbitrary properties the keymap objects. This is useful for mapping shortcuts to commands.
Example
emitKeypress({
keymap: [
{ sequence: '\x1B', shortcut: 'escape', command: 'cancel' },
{ sequence: '\x03', shortcut: 'ctrl+c', command: 'cancel' },
{ sequence: '\r', shortcut: 'return', command: 'submit' }
],
onKeypress: async (input, key, close) => {
// do stuff with keypress events
switch (key.command) {
case 'cancel':
console.log('canceled');
close();
break;
case 'submit':
console.log('submitted');
break;
}
}
});
Pass a ReadableStream to input to listen for keypress events on the stream.
emitKeypress({
input: process.stdin,
onKeypress: async (input, key, close) => {
// do stuff with keypress events
console.log({ input, key });
if (key.shortcut === 'return' || key.shortcut === 'ctrl+c') {
close();
}
}
});
Pass an onMousepress function to handle mouse events. When provided, mouse tracking is automatically enabled.
emitKeypress({
onKeypress: (input, key, close) => {
console.log('key:', key);
},
onMousepress: (mouse, close) => {
console.log('mouse:', mouse);
// mouse.x, mouse.y, mouse.button, mouse.action, etc.
}
});
Enable bracketed paste mode to handle multi-line pastes as a single event.
emitKeypress({
enablePasteMode: true,
pasteModeTimeout: 100, // timeout in ms
maxPasteBuffer: 1024 * 1024, // 1MB limit
onKeypress: (input, key, close) => {
if (key.name === 'paste') {
console.log('pasted:', key.sequence);
}
}
});
Enable the Kitty or modifyOtherKeys keyboard protocol for better key detection in supported terminals.
emitKeypress({
keyboardProtocol: true,
onKeypress: (input, key, close) => {
// Enhanced key reporting with better modifier detection
console.log({ input, key });
}
});
Supported terminals include: kitty, alacritty, foot, ghostty, iterm, rio, wezterm (Kitty protocol), and windows_terminal, xterm, gnome_terminal, konsole, vscode, xfce4_terminal, mate_terminal, terminator (modifyOtherKeys protocol).
Control cursor visibility and get cursor position.
import { cursor, emitKeypress } from 'emit-keypress';
// Hide/show cursor
cursor.hide(process.stdout);
cursor.show(process.stdout);
// Or use the hideCursor option
emitKeypress({
hideCursor: true,
onKeypress: (input, key, close) => {
// cursor is automatically shown when close() is called
}
});
// Get initial cursor position
emitKeypress({
initialPosition: true,
onKeypress: (input, key, close) => {
if (key.name === 'position') {
console.log('cursor at:', key.x, key.y);
}
}
});
| Option | Type | Default | Description |
|---|---|---|---|
input | ReadStream | process.stdin | Input stream to listen on |
output | WriteStream | process.stdout | Output stream for escape sequences |
keymap | Array | [] | Custom key mappings |
onKeypress | Function | required | Keypress event handler |
onMousepress | Function | undefined | Mouse event handler (enables mouse tracking) |
onExit | Function | undefined | Called when the stream closes |
escapeCodeTimeout | number | 500 | Timeout for escape sequences (ms) |
handleClose | boolean | true | Register cleanup on process exit |
hideCursor | boolean | false | Hide cursor while listening |
initialPosition | boolean | false | Request initial cursor position |
enablePasteMode | boolean | false | Enable bracketed paste mode |
pasteModeTimeout | number | 100 | Paste mode timeout (ms) |
maxPasteBuffer | number | 1048576 | Max paste buffer size (bytes) |
keyboardProtocol | boolean | false | Enable enhanced keyboard protocol |
Create an isolated instance with its own exit handlers.
import { createEmitKeypress } from 'emit-keypress';
const { emitKeypress, onExitHandlers } = createEmitKeypress({
setupProcessHandlers: true
});
onMousepress option for mouse event handling with automatic mouse trackingenablePasteMode, pasteModeTimeout, maxPasteBuffer)keyboardProtocol option)createEmitKeypress factory for creating isolated instances with separate exit handlerscursor utilities for hiding/showing cursor and getting positioninitialPosition option to request cursor position on starthideCursor option for automatic cursor visibility managementonExit callback optionfn modifier support to key objectskeycodes export with comprehensive key sequence mappingsPull requests and stars are always welcome. For bugs and feature requests, please create an issue.
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
$ npm install && npm test
(This project's readme.md is generated by verb, please don't edit the readme directly. Any changes to the readme must be made in the .verb.md readme template.)
To generate the readme, run the following command:
$ npm install -g verbose/verb#dev verb-generate-readme && verb
Jon Schlinkert
Copyright © 2025, Jon Schlinkert. Released under the MIT License.
This file was generated by verb-generate-readme, v0.8.0, on December 10, 2025.
FAQs
Drop-dead simple keypress event emitter for Node.js. Create powerful CLI applications and experiences with ease.
The npm package emit-keypress receives a total of 18 weekly downloads. As such, emit-keypress popularity was classified as not popular.
We found that emit-keypress 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.

Research
/Security News
Mixed-script homoglyphs and a lookalike domain mimic imToken’s import flow to capture mnemonics and private keys.

Security News
Latio’s 2026 report recognizes Socket as a Supply Chain Innovator and highlights our work in 0-day malware detection, SCA, and auto-patching.

Company News
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.