⌨️ A tiny keyboard shortcut handling library
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



npm License:MIT Build Status Coverage Status

⌨️ A tiny keyboard shortcut handling library.


  • Pocket-sized – library size is less than 600 bytes (~350 bytes gzipped!)
  • Minimal – pass a callback function => get results.
  • Specialized – only handles key combinations with at least one or more modifier keys pressed and at most one regular key (read more)
  • Framework-agnostic – can be plugged on any standard KeyboardEvent listener (keyup, keydown, keypress, etc.)

Use Cases

  • Declaratively listen for shortcut events
  • Key combination input field for user-friendly shortcut configuration
  • Handle simple or complex shortcut UIs with a standardized format

Bundle Sizes

minizipped size minizipped size


import combi from 'combi'

const onShortcut = combi((shortcut, keyEvent) => {
  console.log(shortcut) // -> 'ctrl+z'

window.addEventListener('keydown', onShortcut)


Via npm

npm install --save combi

Via unpkg

Alternatively, you can download and/or import it from unpkg.com/combi as an ES or UMD module.

Import as ES Module

import combi from 'https://unpkg.com/combi/dist/combi.es.js'

Use as UMD Module

<!-- This adds `combi` to the global context (`window`) -->
<script src="https://unpkg.com/combi/dist/combi.umd.js"></script>

You can find the library on window.combi

Usage Examples

Listening for Shortcuts

combi takes a handler function as an argument. This handler function should take two arguments. The first one: the keyboard shortcut that has been pressed. The second one: the original keyboard event. You can match these shortcuts however you want.

See it in action

import combi from 'combi'

const onShortcut = combi((shortcut) => {
  switch ((shortcut, event)) {
    case 'meta+s':
    case 'ctrl+s':
    case 'shift+meta+z':
    case 'ctrl+y':
    case localStorage.getItem('shortcut'):
    // do nothing.

window.addEventListener('keydown', onShortcut)

Key Combination Input Field

You can use combi to create custom input fields for specifying key combinations. Useful when building apps with configurable keyboard shortcuts.

See it in action

import combi from 'combi'

// pass `true` as second argument to call preventDefault() when a combination is used
const onShortcut = combi((combination, event) => {
  event.target.value = combination
  localStorage.setItem('shortcut', combination)
}, true)

const inputElement = document.querySelector('#shortcut-input')

inputElement.addEventListener('keydown', onShortcut)



combi(callback, [preventDefault])

combi(callback: Function [, preventDefault: Boolean])
callback {Function}

A function that handles shortcuts, that looks like this:

(shortcut: String, event: KeyboardEvent) => any

shortcut {String} - keyboard shortcut that has been pressed (e.g. shift+meta+x, ctrl+y)

event {KeyboardEvent} - the original KeyboardEvent passed to combi by the event listener

preventDefault {Boolean}

Whether combi should always call .preventDefault() when receiving a keyboard event. Defaults to false

Supported Modifiers

These are the modifiers combi supports. Shortcuts detected will always be parsed in this order:

  • ctrl
  • alt
  • shift
  • meta
    • Command key () on macOS
    • Windows key () on Windows (note: using meta on Windows is highly discouraged for non-system shortcuts)


In order to maintain combi as simple as possible, while enabling the most common and standard use cases, some rules are in place:

  • Only key combinations of two or more keys are allowed, with the following conditions:
    • at least one or more modifiers (ctrl, shift, alt, etc.)
    • at most one regular key (a-z, 0-9, -, +, [, ], \, etc.)
    • Example: shift+k+z won't work
  • Key combinations are represented as a string concatenation of modifier keys and an (optional, if the combination is of more than two ) regular key in the following normative order: ctrl+alt+shift+meta+somekey
  • All non-modifier keys are lowercased versions of KeyboardEvent.code with the words Key and Digit removed
    • Examples:
      • KeyA becomes a
      • Digit0 becomes 0
      • BracketLeft becomes bracketleft

Note: These considerations are not arbitrary. Most of them are derived from the following guidelines:


Bug Reports & Feature Requests

Something does not work as expected or perhaps you think this project needs a feature? Please open an issue using GitHub issue tracker.

Make sure that an issue pointing out your specific problem does not exist already. Please be as specific and straightforward as possible.

Pull Requests

Pull Requests (PRs) are welcome! You should follow the same basic stylistic conventions as the original code.

Make sure that a pull request solving your specific problem does not exist already. Your changes must be concise and focus on solving a discrete problem.


The MIT License (MIT)

Copyright (c) 2018 Kristian Muñiz