NiceGUI Goes 3.0
Episode Deep Dive
Guests introduction and background
Rodja Trappe and Falko Schindler are the creators and maintainers of NiceGUI, engineers at Zauberzeug, a German robotics company using Python-powered UIs in production. In the episode they trace NiceGUI from its early FastAPI proof of concept to a full component library backed by Vue/Quasar, purpose-built for building modern, real-time web apps in pure Python (no JavaScript required).
What to Know If You're New to Python
Here are a few quick primers so you get the most out of this episode’s discussion about NiceGUI and its stack:
- nicegui.io/documentation: Start here for the three-line "hello ui" and the mental model of components and pages.
- fastapi.tiangolo.com/advanced/websockets: NiceGUI rides on FastAPI and uses WebSockets for live updates; this page shows the handshake and usage.
- quasar.dev: Many NiceGUI widgets wrap Quasar components, which explains features like data tables, tabs, and menus.
- tailwindcss.com/docs: Styling in NiceGUI embraces Tailwind classes; you can drop down to utility classes when you need precision.
Key points and takeaways
NiceGUI’s core idea: modern, component-based web apps in pure Python
NiceGUI lets you write UIs entirely in Python while it handles the browser side through Vue and Quasar. It sits on FastAPI for HTTP and uses WebSockets for live, push-based updates, so you can sync UI state in real time without polling. That "Python-first" flow makes it feel like traditional GUI programming, but the output is a responsive web app that works on desktop and mobile. The framework is open source and actively maintained by its creators.Why teams pick NiceGUI over "data-app" tools
In the show, the guests compare NiceGUI with Streamlit, Gradio, and earlier frameworks like JustPy. Streamlit and Gradio are fantastic for quick demos, but NiceGUI’s strength is full control: routing, component composition, styling, and integration with the rest of your Python back end. That’s why they run it in production at Zauberzeug to control robots and visualize data-rich UIs.- Links and tools:
NiceGUI 3.0 highlights: script mode, SPA root, event system, Tailwind 4
Version 3 focuses on developer ergonomics: a new script mode for "hello world" workflows, arootpage parameter to simplify single-page apps, an event system to communicate between long-lived objects and the UI, and an upgrade to Tailwind 4. The release also cleans up bindings and tightens Python version support. These additions make app structure and state management cleaner while keeping the "write it in Python" feel.Robotics and computer-vision friendly components
The team calls out components that make robotics dashboards straightforward:ui.scenefor 3D visualization powered by three.js andui.interactive_imagefor mouse-aware image overlays. Interactive image lets you draw, select, and map clicks in image coordinates, which is ideal for camera-based workflows; updates are efficient and flicker-free. These are practical building blocks they actually use for robot interfaces.Data-heavy UIs out of the box: tables and charts
NiceGUI wraps Quasar’s QTable asui.table, handling pagination, selection, and custom columns, and integrates with Apache ECharts for highly interactive charts. For advanced grid needs, AG Grid is supported, giving you a path to enterprise-grade tables. Because the state lives server-side in Python, you can push updates as your computations finish.Developer experience: three lines to running UI, hot reload, and browser auto-open
The guests demo the minimal app: importui, create an element, callui.run(). In dev, it auto-reloads on code change and opens your browser to the right URL. That quick feedback loop accelerates iteration while keeping the layout and state model simple.- Links and tools:
Styling with Tailwind for precision without Yak-shaving
NiceGUI exposes Tailwind classes so you can jump straight to utility-first styling when you need exact spacing, color, or layout control. Because many widgets map to Quasar components, you get a consistent baseline and can layer Tailwind on top instead of fighting opaque themes. This gives you design freedom without abandoning the Python-first workflow.- Links and tools:
Routing and single-page apps
You define pages with@ui.pagesimilar to FastAPI routes, with typed parameters and client-side navigation helpers. For SPAs, NiceGUI supports sub-pages and, in 3.0, arootparameter onui.run()to simplify top-level routing. This keeps complex apps organized without a separate JavaScript router.State, sessions, and authentication paths
NiceGUI includes built-in storage dicts (likeapp.storage.user) keyed by a signed browser session cookie, which makes per-user state and multi-tab sync trivial. For auth, you can roll your own forms or adopt FastAPI OAuth2/JWT patterns, and the community has several examples. In the episode, the maintainers argue for keeping auth simple and leaning on established FastAPI security flows.Running multiple workers and scaling behind a proxy
Because interactions use WebSockets, production setups typically place NiceGUI behind a reverse proxy and enable sticky sessions so a client reconnects to the same worker. Shared server-side storage (for example via Redis) helps multiple instances coordinate per-user state. This pattern is widely used when deploying real-time apps and is reflected in NiceGUI’s storage back ends and docs.- Links and tools:
Native desktop mode and packaging
NiceGUI can open in a native window withui.run(native=True), which is handy for kiosk apps or distributing to users who expect a desktop experience. For packaging, PyInstaller is a common choice to bundle the app for Windows, macOS, and Linux. The show covers tradeoffs and notes that under the hood you are still serving a local web app.- Links and tools:
Docker and simple deploys
There is an official NiceGUI image on Docker Hub, and the docs outline common configuration knobs (host, port, reload) for production. Teams often front the container with Nginx or Caddy and wire in TLS and sticky sessions there. This makes it straightforward to host on your platform of choice.- Links and tools:
Install and run with uvx for quick experiments
The maintainers mention usinguvxto run tools in ephemeral environments. With uv from Astral,uvx niceguican launch a minimal app without manually creating a virtual environment, which is great for trying examples or reproducing issues.- Links and tools:
Interesting quotes and stories
"And the minimal NiceGUI app is basically three lines of code... you import UI from NiceGUI, add a label, and then you write ui.run." -- Falko Schindler
"It turned out to be the main UI framework in NiceGUI. Most or many elements are based on Quasar or existing Quasar components." -- Falko Schindler
"Another interesting element could be the interactive image... where you can overlay camera data and things like that. And also the image can be very efficiently updated." -- Rodja Trappe
"As a default, it auto-reloads when you change the code. It automatically opens the browser for you." -- Falko Schindler
"Then you only need a proxy server which can have sticky sessions... and it routes you back to the right server instance." -- Rodja Trappe
key definitions and terms
- WebSocket: A persistent, bi-directional communication channel between browser and server. NiceGUI uses this for live UI updates.
- Quasar: A Vue-based UI framework whose components power many NiceGUI widgets (e.g., tables, tabs).
- ECharts: A high-performance charting library used via
ui.echart. - SPA (Single Page Application): An app that updates views client-side without full page reloads; NiceGUI supports SPA patterns and a
rootpage option in 3.0. - Tailwind CSS: A utility-first CSS framework used for styling NiceGUI apps with fine-grained control.
- Reverse proxy: A front server like Nginx or Caddy that terminates TLS, handles routing, and can enforce sticky sessions for WebSocket apps.
Learning resources
Here are curated Talk Python courses to deepen skills that pair well with NiceGUI. All links include a source tag.
- Python for Absolute Beginners: A gentle start if you’re early in your Python journey.
- Modern APIs with FastAPI and Python: Build and secure production-grade APIs, a perfect companion to a NiceGUI front end.
- Full Web Apps with FastAPI: Go beyond APIs into server-side pages, templates, and app structure.
- Async Techniques and Examples in Python: Master async and concurrency patterns that underpin responsive UIs and real-time features.
- Python Web Apps that Fly with CDNs: Practical performance tips for web apps.
- Effective PyCharm 2025: Level up your day-to-day development workflow.
Overall takeaway
NiceGUI keeps the promise of "write real web apps in Python" without giving up modern front-end power. You get real components, real-time updates, first-class routing, and production patterns that scale, plus the ability to go native or stay web-only as your use case demands. If you’re a Python developer who wants a UI that feels as direct as writing a script but behaves like a modern app, NiceGUI 3.0 is a very practical path forward.
Links from the show
Falko Schindler: github.com
NiceGUI 3.0.0 release: github.com
Full LLM/Agentic AI docs instructions for NiceGUI: github.com
Zauberzeug: zauberzeug.com
NiceGUI: nicegui.io
NiceGUI GitHub Repository: github.com
NiceGUI Authentication Examples: github.com
NiceGUI v3.0.0rc1 Release: github.com
Valkey: valkey.io
Caddy Web Server: caddyserver.com
JustPy: justpy.io
Tailwind CSS: tailwindcss.com
Quasar ECharts v5 Demo: quasar-echarts-v5.netlify.app
AG Grid: ag-grid.com
Quasar Framework: quasar.dev
NiceGUI Interactive Image Documentation: nicegui.io
NiceGUI 3D Scene Documentation: nicegui.io
Watch this episode on YouTube: youtube.com
Episode #525 deep-dive: talkpython.fm/525
Episode transcripts: talkpython.fm
Theme Song: Developer Rap
🥁 Served in a Flask 🎸: talkpython.fm/flasksong
---== Don't be a stranger ==---
YouTube: youtube.com/@talkpython
Bluesky: @talkpython.fm
Mastodon: @talkpython@fosstodon.org
X.com: @talkpython
Michael on Bluesky: @mkennedy.codes
Michael on Mastodon: @mkennedy@fosstodon.org
Michael on X.com: @mkennedy
Episode Transcript
Collapse transcript
00:00
00:06
00:12
00:25
00:35
00:43
01:03
01:09
01:23
01:27
01:34
01:38
01:42
01:49
01:51
01:57
02:00
02:02
02:07
02:14
02:17
02:24
02:25
02:27
02:28
02:29
02:30
02:33
02:37
02:47
02:51
02:56
02:57
03:02
03:03
03:08
03:09
03:10
03:12
03:19
03:22
03:30
03:33
03:42
03:51
03:54
03:56
03:57
04:03
04:16
04:22
04:23
04:24
04:24
04:25
04:27
04:32
04:35
04:40
04:42
04:44
04:49
04:50
04:51
04:56
05:00
05:05
05:08
05:10
05:18
05:19
05:24
05:38
05:39
05:40
05:48
05:53
05:54
06:11
06:23
06:30
06:48
06:59
07:03
07:06
07:08
07:11
07:22
07:23
07:24
07:27
07:27
07:28
07:33
07:47
07:53
08:13
09:05
09:48
09:54
10:01
10:14
11:07
11:35
11:38
11:40
11:45
11:48
11:51
11:54
11:58
12:06
12:11
12:21
12:39
13:25
13:32
13:38
13:42
13:48
13:50
13:55
13:57
14:08
14:14
14:24
14:26
14:36
14:37
14:37
14:46
14:50
14:59
15:06
15:10
15:11
15:13
15:14
15:17
15:18
15:28
15:29
15:34
15:43
15:56
15:59
16:02
16:05
16:08
16:12
16:19
16:23
16:30
16:32
16:37
16:51
16:55
17:00
17:06
17:14
17:21
17:25
17:29
17:31
17:37
17:43
17:46
17:48
17:52
17:58
18:05
18:09
18:12
18:13
18:14
18:22
18:28
18:32
18:43
18:51
18:54
19:00
19:03
19:07
19:08
19:10
19:17
19:19
19:20
19:21
19:21
19:24
19:29
19:32
19:34
19:36
19:38
19:49
19:54
19:58
20:01
20:05
20:12
20:13
20:17
20:18
20:20
20:24
20:28
20:32
20:35
20:38
20:40
20:44
21:12
21:18
21:30
21:34
21:39
21:47
21:52
22:07
22:11
22:12
22:25
22:26
22:33
22:36
22:42
22:58
23:02
23:03
23:14
23:18
23:21
23:29
23:29
23:34
23:41
23:47
23:56
24:01
24:07
24:17
24:18
24:22
24:25
24:26
24:43
24:52
25:04
25:05
25:07
25:09
25:17
25:18
25:22
25:25
25:30
25:34
25:37
25:40
25:49
26:03
26:11
26:13
26:15
26:18
26:32
26:39
26:42
26:47
26:54
26:58
27:00
27:09
27:12
27:18
27:18
27:23
27:25
27:28
27:43
28:03
28:28
28:34
28:37
28:39
28:42
28:53
28:58
29:03
29:08
29:11
29:14
29:17
29:23
29:27
29:34
29:40
29:46
30:00
30:06
30:12
30:13
30:19
31:05
31:24
31:29
31:35
31:38
31:46
31:59
32:04
32:08
32:09
32:19
32:26
32:34
32:37
32:43
32:45
32:49
32:53
32:59
33:04
33:11
33:13
33:19
33:25
33:38
33:40
33:49
33:51
33:59
34:03
34:04
34:08
35:03
35:05
35:08
35:24
35:24
35:31
35:52
35:59
36:02
36:07
36:13
36:19
36:20
36:25
36:27
36:28
36:29
36:31
36:33
36:33
36:36
36:40
36:42
36:44
36:45
36:45
36:46
36:46
36:47
36:48
36:55
36:56
36:59
37:02
37:06
37:11
37:15
37:19
37:23
37:24
37:28
37:31
37:33
37:35
37:36
37:38
37:39
37:42
37:43
37:50
37:52
37:53
37:56
37:56
37:57
37:59
38:06
38:15
38:17
38:20
38:28
38:30
38:31
38:32
38:37
38:42
38:44
38:50
38:54
38:59
39:07
39:08
39:08
39:39
39:43
39:47
39:54
39:55
40:03
40:34
40:35
40:40
40:41
41:01
41:54
42:01
42:06
42:11
42:16
42:17
42:24
42:27
42:34
42:44
42:47
42:58
43:04
43:07
43:20
43:25
43:31
43:40
43:47
43:53
44:14
44:25
44:38
44:40
44:50
44:51
44:59
45:05
45:12
45:19
45:30
45:31
45:35
45:41
45:52
45:59
46:08
46:11
46:27
46:33
46:40
46:42
46:42
46:47
46:55
46:56
46:57
47:14
47:35
47:38
47:42
47:50
48:06
48:07
48:08
48:15
48:20
48:23
48:25
48:32
48:35
48:37
48:43
48:44
48:49
48:52
49:07
49:12
49:40
49:53
50:25
50:35
51:02
51:08
51:12
51:16
51:19
51:26
51:31
51:38
51:53
51:59
52:03
52:06
52:11
52:17
52:18
52:18
52:24
52:27
52:31
52:37
53:01
53:25
53:35
53:42
53:43
53:44
53:49
54:02
54:04
54:06
54:18
54:24
54:27
54:41
54:46
54:55
54:59
55:03
55:11
55:18
55:19
55:21
55:23
55:24
55:25
55:27
55:32
55:40
55:45
55:49
55:53
55:54
55:55
56:01
56:06
56:08
56:10
56:11
56:12
56:14
56:18
56:21
56:26
56:35
56:39
56:46
56:46
56:50
57:09
57:12
57:14
57:18
57:21
57:34
57:37
58:03
58:07
58:09
58:14
58:16
58:23
58:26
58:32
58:37
58:38
58:45
58:50
58:59
58:59
59:01
59:02
59:10
59:11
59:20
59:22
59:25
59:26
59:30
59:31
59:34
59:38
59:40
59:43
59:55
59:57
01:00:07
01:00:12
01:00:15
01:00:17
01:00:20
01:00:21
01:00:22
01:00:22
01:00:23
01:00:24
01:00:26
01:00:30
01:00:38
01:00:45
01:00:56
01:01:01
01:01:08
01:01:15
01:01:30
01:01:34
01:01:49
01:02:11
01:02:56
01:02:58
01:03:07
01:03:11
01:03:13
01:03:15
01:03:19
01:03:24
01:04:09
01:04:20
01:04:22
01:04:25
01:04:31
01:04:33
01:04:38
01:04:43
01:04:46
01:04:48
01:04:55
01:04:59
01:05:01
01:05:06
01:05:28
01:05:33
01:05:34
01:05:45
01:05:45
01:05:53
01:06:02
01:06:06
01:06:12
01:06:17
01:06:19
01:06:21
01:06:22
01:06:25
01:06:27
01:06:30
01:06:35
01:06:45
01:06:46
01:06:47
01:06:50
01:06:51
01:06:51
01:06:52
01:06:53
01:06:53
01:06:54
01:06:55
01:06:55
01:07:07
01:07:10
01:07:11
01:07:22
01:07:26
01:07:33
01:07:44
01:07:49
01:07:54
01:07:59
01:08:09
01:08:11
01:08:12
01:08:15
01:08:26
01:08:27
01:08:27
01:08:27
01:08:28
01:08:42
01:08:44
01:08:46
01:08:50
01:08:55
01:09:00
01:09:05
01:09:07
01:09:07
01:09:09
01:09:10
01:09:12
01:09:14
01:09:14
01:09:20
01:09:24
01:09:50
01:09:56
01:10:06
01:10:17
01:10:21
01:10:25
01:10:26
01:10:29
01:10:32
01:10:38
01:10:42
01:10:46
01:10:59
01:11:02
01:11:03
01:11:09
01:11:13
01:11:22
01:11:23
01:11:32
01:11:33
01:11:50
01:11:58
01:12:01
01:12:02
01:12:04
01:12:06
01:12:10
01:12:15
01:12:17
01:12:22
01:12:39
01:12:40
01:12:42
01:12:47
01:12:50
01:12:50
01:12:51
01:12:53
01:12:55
01:13:03
01:13:09
01:13:13
01:13:14
01:13:16
01:13:21
01:13:27
01:13:32
01:13:33
01:13:36
01:13:39
01:13:42
01:13:45
01:13:46
01:13:47
01:13:48
01:13:50
01:13:51
01:13:56
01:14:34
01:14:38
01:14:41
01:14:42
01:14:42
01:14:42
01:14:43
01:14:44
01:14:47
01:14:48
01:14:49
01:14:50
01:14:50
01:15:06
01:15:10
01:15:18
01:15:27
01:15:30
01:15:32
01:15:35
01:15:36
01:15:38
01:15:38
01:15:39
01:15:40
01:15:41
01:15:42
01:15:45
01:15:47
01:15:48
01:15:50
01:15:52
01:15:57
01:16:04
01:16:05
01:16:11
01:16:12
01:16:15
01:16:19
01:16:26
01:16:27
01:16:31
01:16:37
01:16:39
01:16:42
01:16:44
01:16:47
01:16:48
01:16:58
01:17:01
01:17:09
01:17:10
01:17:12
01:17:13
01:17:40


