Skip to main content

A Streamlit text input that updates on every keystroke, no Enter key required.

Project description

streamlit-live-search

A Streamlit text input that behaves exactly like st.text_input(), except it reports every keystroke back to Python immediately — no Enter key, no loss of focus required.

User types:  b        →  Python receives: "b"
User types:  bi        →  Python receives: "bi"
User types:  bid       →  Python receives: "bid"

Built with a React + TypeScript frontend and a small Python wrapper around the Streamlit Components API.


Features

  • ⚡ Real-time updates on every keystroke — no Enter key needed
  • 🎚️ Configurable debounce (0 for instant, or any millisecond delay)
  • 🏷️ Label, placeholder, help text, and label_visibility support
  • 📐 Configurable width / height
  • 🚫 disabled state
  • ✖️ Built-in clear button (and Esc to clear)
  • 🎯 Autofocus support
  • ⌨️ Keyboard shortcuts (Esc to clear, Ctrl/Cmd+K to focus)
  • 🌗 Automatic dark mode / light mode (follows the active Streamlit theme)
  • 📱 Responsive layout
  • ♿ Accessible: ARIA labels, keyboard navigation, screen-reader friendly
  • 🧪 Unit-tested on both the Python and frontend side

Installation

pip install streamlit-live-search

Requires Python 3.8+ and Streamlit 1.28+.


Quick start

import streamlit as st
from streamlit_live_search import live_search

search = live_search(
    label="Search Student",
    placeholder="Type student name...",
    debounce=0,
    key="search",
)

if search:
    st.write(f"You typed: {search}")

Live-filtering a table

import pandas as pd
import streamlit as st
from streamlit_live_search import live_search

search = live_search(label="Search Student", placeholder="Type student name...")

df = pd.read_csv("students.csv")
if search:
    df = df[df["name"].str.contains(search, case=False, na=False)]

st.dataframe(df)

Typing b instantly filters the table; typing bi filters again — with no Enter key press at any point. See examples/app.py for a complete, runnable example (including an st-aggrid table variant).

Run the example locally:

pip install streamlit-live-search pandas
streamlit run examples/app.py

API reference

live_search(...)

live_search(
    label: str = "",
    placeholder: str = "",
    value: str = "",
    debounce: int = 100,
    key: str | None = None,
    disabled: bool = False,
    width: str | int | None = None,
    height: str | int | None = None,
    clearable: bool = True,
    autofocus: bool = False,
    label_visibility: str = "visible",
    help: str | None = None,
) -> str
Argument Type Default Description
label str "" Label shown above the field. Empty string omits it.
placeholder str "" Placeholder text shown when empty.
value str "" Initial value on first render.
debounce int 100 Milliseconds to wait after the last keystroke before updating Python. Use 0 for instant, uncoalesced updates.
key str | None None Streamlit widget key. Required if rendering more than one live_search with identical arguments.
disabled bool False Renders the field read-only.
width str | int | None None CSS width, e.g. "300px" or "100%".
height str | int | None None CSS height of the widget container.
clearable bool True Shows a clear ("×") button once text is entered; binds Esc to clear.
autofocus bool False Focuses the field automatically on mount.
label_visibility "visible" | "hidden" | "collapsed" "visible" Matches core Streamlit widget semantics.
help str | None None Helper text rendered below the field.

Returns: the current text in the field, as a str, updated live as the user types.

Raises: ValueError if debounce is negative or label_visibility is invalid.


How it works

Streamlit's built-in st.text_input() only pushes a new value to Python on blur or Enter, because it listens to the browser's change event. streamlit-live-search instead:

  1. Listens to the native input event on every keystroke (not change).
  2. Calls Streamlit.setComponentValue() immediately (or after debounce ms), which triggers a Streamlit script rerun with the new value.
  3. Keeps the input's own React state in sync so the field never stutters or loses characters while a rerun is in flight.

Development guide

Prerequisites

  • Python 3.8+
  • Node.js 18+ and npm

Project layout

streamlit-live-search/
├── pyproject.toml
├── README.md
├── LICENSE
├── MANIFEST.in
├── setup.py
├── streamlit_live_search/       # Python package
│   ├── __init__.py
│   ├── component.py             # declares & wraps the component
│   └── frontend/build/          # compiled frontend (generated by `npm run build`)
├── frontend/                    # React + TypeScript source
│   ├── package.json
│   ├── tsconfig.json
│   ├── vite.config.ts
│   ├── src/
│   │   ├── index.tsx
│   │   ├── App.tsx
│   │   └── LiveSearch.tsx
│   └── public/
├── examples/
│   └── app.py
└── tests/
    └── test_component.py

Running in dev mode (hot reload)

In one terminal, start the frontend dev server:

cd frontend
npm install
npm run dev

In another terminal, tell the Python side to use the dev server instead of the built assets, then run the example app:

export STREAMLIT_LIVE_SEARCH_DEV=1   # Windows: set STREAMLIT_LIVE_SEARCH_DEV=1
pip install -e .
streamlit run examples/app.py

Building for production

cd frontend
npm install
npm run build          # outputs to streamlit_live_search/frontend/build

cd ..
pip install .

Linting & formatting

# Frontend
cd frontend
npm run lint
npm run format

# Python
ruff check .
black .
mypy streamlit_live_search

Testing

# Python
pytest

# Frontend
cd frontend
npm test

Publishing guide

Publishing the frontend build

The compiled frontend (streamlit_live_search/frontend/build/) must exist and be up to date before building the Python distribution — it's bundled as package data.

cd frontend
npm install
npm run build
cd ..

Building the Python distribution

python -m pip install --upgrade build twine
python -m build          # creates dist/*.whl and dist/*.tar.gz

Publishing to PyPI

twine check dist/*
twine upload dist/*                 # production PyPI
# or, to test first:
twine upload --repository testpypi dist/*

Versioning

Bump the version in both pyproject.toml ([project].version) and streamlit_live_search/__init__.py (__version__) before each release, following SemVer.


Browser support

Chrome, Firefox, Edge, and Safari (latest two major versions).


Accessibility

  • The input has role="searchbox" and an aria-label derived from label.
  • The clear button has an explicit aria-label="Clear search".
  • Helper text is linked via aria-describedby.
  • The field is fully keyboard operable: Tab to focus, type to search, Esc to clear, Ctrl/Cmd+K to jump focus to the field from anywhere on the page.

Contributing

Issues and pull requests are welcome. Please run the lint, format, and test commands above before submitting a PR.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

streamlit_live_search_bidhan-1.0.0.tar.gz (359.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

streamlit_live_search_bidhan-1.0.0-py3-none-any.whl (360.1 kB view details)

Uploaded Python 3

File details

Details for the file streamlit_live_search_bidhan-1.0.0.tar.gz.

File metadata

File hashes

Hashes for streamlit_live_search_bidhan-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e7f84f8d4478e27ec0518fdf4e579d00e8360e43419c54d8509bca392c757aaf
MD5 0401844bdba211e52868a89a5c0a0b57
BLAKE2b-256 fb11764248a5489c1f760650371da63431d1c209ba4cf6871ba61be5577c1830

See more details on using hashes here.

File details

Details for the file streamlit_live_search_bidhan-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for streamlit_live_search_bidhan-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af03f660618035a5281499f257ff734fb7fb19890a9428d78880d58cd97a5288
MD5 f280c39b26f241169656b560d9373c8c
BLAKE2b-256 99657687e3b5ed3a24100f4b763e5543aff0fe0a6f8e1eb73e22617d0abd5343

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page