English | Русский
nicegui-kit is a theme and a small toolkit for NiceGUI apps that run jobs:
internal tools, scrapers, admin panels, review queues. Call theme.apply_theme() once and every page
gets a light and dark theme that passes WCAG AA, a self-hosted Inter font that works offline, and
helpers that keep spacing consistent. run_pool and run_monitor add the part most of these tools need:
start a subprocess from a button and watch its log live, with cancel that really stops it.
This screen is examples/showcase.py, about 200 lines on top of the kit.
Install
pip install nicegui-kit
# or
uv add nicegui-kit
Python ≥3.12, nicegui>=3.15,<4.
Quick start
from nicegui import ui
from nicegui_kit import layout, run_pool, run_monitor, theme
theme.apply_theme() # once, before ui.run() — colors/CSS shared across pages
@ui.page("/")
def index() -> None:
with layout.page_container(max_width=layout.PAGE_MAX_WIDTH_WIDE):
layout.heading("My tool", level=1)
theme.theme_toggle() # usually inside ui.header()
with layout.section_card():
layout.button("Run it", kind="primary", on_click=lambda: run_pool.submit(
["python", "-c", "print('hi')"], label="demo run",
))
run_monitor.attach_run_monitor()
ui.run(host="127.0.0.1")
The full demo, from a clone:
git clone https://github.com/octrow/nicegui-kit && cd nicegui-kit
uv run python examples/showcase.py # http://127.0.0.1:8787, ?dark=1 forces dark
Kit strings are Russian by default; texts.TEXTS.update(texts.EN) switches them to English, as the
showcase does.
What's in the kit
| module | what you get |
|---|---|
theme |
apply_theme(): light and dark tokens in one dict, every text/background pair tested at WCAG AA in both themes, self-hosted Inter Variable. theme_toggle(): a header button that cycles system → light → dark and remembers the choice |
layout |
page_container, heading, section_card, grid, field, search_field, filter_bar, actions_row, button, markdown_reader, copy_for_chat_button, and the three states every data view needs: empty, waiting, failed |
table |
empty_aware_table(): a ui.table and its "nothing found" label, kept in sync by one call |
hotkeys |
on_keydown(): page hotkeys that ignore keyup, held modifiers and typing in inputs |
texts |
every kit string in one dict, Russian by default, texts.EN for English |
run_pool |
submit(argv): subprocesses with a slot limit, a queue cap and cancel; no ui.* inside |
run_monitor |
attach_run_monitor(): live list of runs with status, log and a cancel button |
The /kit page of the showcase shows each component in all its states:
Signatures and details for every module are in the API reference. The design rules behind the theme (tokens, type scale, do's and don'ts) are in DESIGN.md.
How a run works
Your page calls run_pool.submit(argv). The pool runs up to 3 processes at once and queues up to 20
more; argv is a list and never goes through a shell. stdout and stderr are merged, and lines up to
1 MiB are kept (asyncio's default 64 KiB limit would break the pipe). The run monitor polls once a
second and changes the existing widgets instead of rebuilding them, because NiceGUI has no virtual DOM:
a rebuild would collapse open panels and reset the log's scroll position.
Why not plain NiceGUI?
NiceGUI gives you Quasar components and Tailwind classes, which is enough for one page. Across several tools the same things get written again: colors that fail contrast in dark mode, a different gap on every card, a subprocess launched from a button that blocks the event loop or leaves a zombie when the tab closes, a log view that jumps to the top on every refresh. The kit fixes those once and tests them.
You still write ui.* code; the kit sits on top of NiceGUI, and each part of it works on its own. If you
are building a data app around dataframes and charts rather than jobs and forms, Streamlit or Gradio may
fit better.
Out of scope
Domain logic stays in your app. The kit gives you the pieces to build it:
- Duplicate-run detection and "you are number N in the queue" wording: use
RunState.metaandrun_pool.live_runs(). - Parsing a run's output for known error patterns: the failure summary is a plain "exit code N" line;
read the log in
on_lineif you need more.
Agent skill
.claude/skills/nicegui-kit-gui/SKILL.md teaches a coding agent to build GUIs on this kit (what to
mirror, the non-obvious NiceGUI traps). Claude Code picks it up by itself in sessions inside this repo;
install it to use it in your own projects:
# via the skills CLI (https://github.com/vercel-labs/skills); copies the skill, works with several agents
npx skills add octrow/nicegui-kit --skill nicegui-kit-gui -g -a claude-code # global
npx skills add octrow/nicegui-kit --skill nicegui-kit-gui -a claude-code # into ./.claude/skills of the current project
Refresh with npx skills update nicegui-kit-gui, remove with npx skills remove nicegui-kit-gui.
Development
uv sync --extra dev
uv run pytest -q
The README images are built from the kit's own tokens: uv run python docs/images/readme_svgs.py.
Contributions are welcome, see CONTRIBUTING.md. Security issues: SECURITY.md.
License
MIT, see LICENSE. The bundled Inter font is under the SIL Open Font License 1.1, see THIRD_PARTY_NOTICES.md.
Metadata
Release files for nicegui-kit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nicegui_kit-0.1.0.tar.gz | 419.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nicegui_kit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 808.9 kB
Release files / nicegui_kit-0.1.0.tar.gz
| Download URL | nicegui_kit-0.1.0.tar.gz |
|---|---|
| Size | 419.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
abea13bdb434221e8d217cde89e0a67fa02db846b1c5bc55dd1ddb3490b63eb1
|
|
BLAKE2b-256 checksum How to use checksums |
5057ce0b526a8a6e6c2057ceec7526434522ff447389d60e089f6372054b5b72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / nicegui_kit-0.1.0-py3-none-any.whl
| Download URL | nicegui_kit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 389.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68a79ecf6f615a5413fdcbbddcc4d5a8aa90188a46e92bf0e8378052a4f6d13c
|
|
BLAKE2b-256 checksum How to use checksums |
ecf96cebac1b40ead86f97a9bd893e3a572bf12fa9b7472082ceea5b7f99ddb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log