New component: streamlit-hotkeys, the best component for keyboard shortcuts out there!

Streamlit Hotkeys

Streamlit Hotkeys lets you wire up fast, app-wide keyboard shortcuts in seconds. Bind Ctrl/Cmd/Alt/Shift + key to actions and get edge-triggered events with a clean, Pythonic API (if hotkeys.pressed("save"): or multiple on_pressed(...) callbacks). It runs through a single invisible manager—no widget clutter, no flicker—and can scope reruns to the whole page or just a fragment. Reuse the same id across combos (e.g., Cmd+K or Ctrl+K → palette), block browser defaults like Ctrl/Cmd+S, and use physical key codes for layout-independent bindings.

Full disclosure, there are already other shortcut components out there.
Streamlit Shortcuts: Client Challenge
Streamlit Keypress: streamlit-keypress · PyPI

They didn’t work for my use-case, but they might for you, so check them out!

Streamlit Keypress does not refresh the state of the component, so there is no way to tell two consequtive clicks apart on the same key.

Streamlit Shortcuts are close, but they mess up the layout with an iframe for each shortcut and they didn’t trigger my on_click events (maybe I’ve done something wrong or @adriangalilea already fixed it).

Here is my elevator pitch for you:

  • one manager for all shortcuts - minimal iframe layout clutter
  • multiple shortcuts for one action
  • callback and if-then interface
  • automatic legend generation to show as cheatsheet to your users

A little demo:

Copy to clipboardimport streamlit as st
import streamlit_hotkeys as hotkeys

# Activate early (top of the script)
hotkeys.activate([
    hotkeys.hk("palette", "k", meta=True),              # Cmd+K (mac)
    hotkeys.hk("palette", "k", ctrl=True),              # Ctrl+K (win/linux)
    hotkeys.hk("save", "s", ctrl=True, prevent_default=True),  # Ctrl+S
])

st.title("Hotkeys quick demo")

if hotkeys.pressed("palette"):
    st.write("Open palette")

if hotkeys.pressed("save"):
    st.write("Saved!")

st.caption("Try Cmd/Ctrl+K and Ctrl+S")

For a callback API:

import streamlit as st
import streamlit_hotkeys as hotkeys

st.title("Multiple callbacks")

hotkeys.activate([
    hotkeys.hk("save", "s", ctrl=True, prevent_default=True),
])

def save_doc():
    st.write("Saving...")

def toast_saved():
    st.toast("Saved!")

# register both; each runs once per key press
hotkeys.on_pressed("save", save_doc)
hotkeys.on_pressed("save", toast_saved)

# you can still branch with pressed() afterwards
if hotkeys.pressed("save"):
    st.info("Thank you for saving")

You can even hold to spam the event:

import streamlit as st
import streamlit_hotkeys as hotkeys

st.title("Hold ArrowDown to increment")

hotkeys.activate([
    hotkeys.hk("down", "ArrowDown", ignore_repeat=False),
])

st.session_state.setdefault("count", 0)

if hotkeys.pressed("down"):
    st.session_state["count"] += 1

st.metric("Count", st.session_state["count"])
st.caption("Hold ArrowDown to spam events (ignore_repeat=False)")

Would love any feedback! I honestly think this should be a part of the main library.