Releases: zauberzeug/nicegui
Release list
v3.15.0
New features and enhancements
- Introduce
ui.popup, a menu on desktop and a dialog on small screens (#1125, #2149, #5613 by @DelScipio, @adosikas, @evnchn, @phifuh, @falkoschindler) - Make the start method of the
run.cpu_boundprocess pool configurable viarun.process_pool_start_method(#6117 by @evnchn, @NiklasNeugebauer, @falkoschindler) - Speed up binding cleanup with a reverse index (#6135, #6150 by @ftilde, @jwinpbe, @evnchn, @falkoschindler)
- Speed up observable change handlers by resolving
expects_argumentsonce at registration (#6098, #6108 by @maybites, @evnchn, @falkoschindler) - Add element identity to the "parent slot has been deleted" error (#6153 by @pascalzauberzeug, @evnchn, @falkoschindler)
Bugfixes
-
Fix
ObservableCollectionleaking change handlers and keeping discarded containers alive (#6139, #6140 by @falkoschindler, @evnchn) -
Raise
KeyErrorfromObservableDict.pop()for a missing key, likedict.pop(#6163, #6164 by @evnchn, @falkoschindler)Breaking change:
app.storage.general,.user,.taband.clientareObservableDicts, sostorage.pop('missing')now raises aKeyErrorinstead of returningNone. Pass an explicit default to keep the previous behavior:storage.pop('missing', None). -
Skip change events for no-op mutations of observable collections (#6169, #6171 by @falkoschindler, @evnchn)
-
Fix
ui.page_title,ui.add_head_html,ui.add_body_htmlandui.add_cssbeing lost in asyncui.sub_pagesbuilders (#6058, #6147, #6148, #6168 by @cervelas, @evnchn, @falkoschindler) -
Fix
run.cpu_boundhanging with theforkserverstart method, e.g. on Python 3.14 + Linux (#6166, #6167 by @evnchn, @falkoschindler) -
Fix
PermissionErroron Windows when clearing storage while a backup is in flight (#6158, #6159, #6173, #6174 by @Jepson2k, @evnchn, @falkoschindler) -
Fix sporadic HTTP 500 when user storage is pruned during an in-flight request (#6145, #6146 by @evnchn, @falkoschindler)
-
Fix
TypeErrorinui.input's shadow text when the autocomplete list is absent (#6161, #6162 by @Jepson2k, @evnchn, @falkoschindler) -
Fix placement and order of
ui.fab_actions underdir="rtl"(#6165, #6172 by @roximn148, @evnchn, @falkoschindler) -
Fix crash when loading an STL model into
ui.scenewithwireframe=True(#5989, #6118, #6137 by @fabian0702, @Jepson2k, @evnchn, @falkoschindler) -
Close streamed media file handles synchronously on teardown (#6149 by @evnchn, @falkoschindler)
Documentation
- Add an accessibility heading tree to the homepage (#6155 by @evnchn, @falkoschindler)
Testing
- Make CPython-only-semantics tests PyPy-compatible (#6157 by @evnchn, @falkoschindler)
Dependencies
- Update nicegui-highcharts to 3.3, fixing dynamic adding and removing of chart series (#6138 by @falkoschindler, @evnchn)
Infrastructure
- Run
examples/pytestsin CI so bundled example tests can't silently rot (#6141, #6144 by @falkoschindler, @evnchn)
Special thanks to our top sponsors DiscoLike Inc. and Lechler GmbH ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.14.0
Security
⚠️ Harden againstX-Forwarded-Prefixreflection and clarify the security documentation (#6124 by @evnchn, @falkoschindler)
New features and enhancements
- Add a custom keybindings API to the
ui.codemirroreditor (#6000 by @Jepson2k, @evnchn, @falkoschindler) - Declare the page language via
<html lang="...">whenui.run(language=...)is set, and stop Quasar from forcingen-USotherwise (#5811 by @evnchn, @falkoschindler) - Introduce
ui.markdown.default_extrasto configure Markdown extras globally (#5548, #5610 by @tomsquest, @evnchn, @falkoschindler) - Simplify the multipart spool-size lookup now that Starlette ≥ 1.0.1 is required, and respect an explicit
spool_max_size = 0(#6102 by @falkoschindler, @evnchn)
Bugfixes
-
Fix character loss in
ui.input(and other value elements) on high-latency connections by preserving client-originated values during element updates (#5185, #6104 by @Xitod, @samuller, @evnchn, @falkoschindler) -
Fall back to polling when the WebSocket cannot connect, fixing the endless reload loop on iOS 26 Safari over plain HTTP (#5802, #6103 by @michaeljandrews, @evnchn, @falkoschindler)
-
Fix native window close hanging or failing to shut down the app — on Windows, after a hot reload, and when
run.cpu_boundwas used (#5443, #5845, #6106, #6111, #6131, #6132 by @MaidScientistIzutsumiMarin, @trivedihoney, @Mick235711, @trivedihoney, @chidoziemanagwu, @evnchn, @falkoschindler) -
Fix
ui.sub_pageswildcard routes not re-rendering on client-side navigation, and reject unsupported route patterns (#6090, #6092 by @JoelBender, @falkoschindler, @evnchn)Breaking change: Route patterns that previously failed silently (e.g.
'/{_:path}','/{name:path}') now raise aValueErroratui.sub_pages(...)/.add(...). These never matched anything before, so only already-broken routes are affected; useshow_404=Falsetogether withPageArguments.remaining_pathfor wildcard routing instead. -
Fix a selection error when changing
ui.selectoptions inside an "input-value" handler (#4420, #6100 by @platinops, @VedantMadane, @falkoschindler, @evnchn) -
Fix
ui.select(with_input=True)dropping itshtml_id, which broke tooltips (#6114, #6116 by @rolfn, @python-and-novella, @evnchn, @falkoschindler) -
Fix
ui.skeleton'sanimation_speedbeing sent as milliseconds instead of seconds (#6107, #6110 by @python-and-novella, @evnchn, @falkoschindler) -
Fix
ui.interactive_imageclick coordinates when a stream changes its resolution (#6122, #6123 by @LeBoozer, @evnchn, @falkoschindler) -
Fix GLTF models in
ui.scenebeing overwritten with the default material at startup (#6118, #6125 by @fabian0702, @evnchn, @falkoschindler) -
Fix an infinite reload loop when an async page build exceeds
response_timeout, showing a terminal error page instead (#6126, #6127 by @evnchn, @falkoschindler) -
Fix the
run.cpu_bound/run.io_boundreturn type toR | None, surfacing the latentNonethey already return on cancel/shutdown (#5925, #6056 by @calebgregory, @evnchn, @falkoschindler)Note: This is a type-level change only; runtime behavior is unchanged. mypy may now flag code that typed the result as non-optional
R— these are surfaced latent bugs, not regressions. NiceGUI 4.0 will raiseCancelledErrorinstead of returningNone.
Documentation
- Improve AI-agent detection in Markdown content negotiation so agents reliably receive Markdown docs (#6109, #6113 by @jwinpbe, @evnchn, @falkoschindler)
- Improve
app.storagedocumentation clarity and fix inconsistencies (#5717, #5719 by @phifuh, @evnchn, @falkoschindler) - Reserve
NOTE:comment markers for drawing special attention (#6101 by @falkoschindler, @evnchn)
Infrastructure
- Add a request check to the startup smoke test so request-time regressions no longer ship green (#6079, #6084 by @evnchn, @SSDWGG, @falkoschindler)
- Remove the redundant CI Gate run on
pushtomainnow that the merge queue already validates every commit reachingmain, speeding up releases (#6136 by @falkoschindler, @evnchn) - Bump actions/checkout from 6 to 7 (#6121 by @dependabot, @evnchn)
Special thanks to our top sponsors DiscoLike Inc. and Lechler GmbH ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.13.0
New features and enhancements
- Introduce
ui.skip_linkfor keyboard-accessibility skip links (WCAG 2.4.1 "Bypass Blocks") (#5790 by @evnchn, @falkoschindler) - Add per-line hover tooltips to
ui.codemirrorvia a newline_tooltipsproperty (with optionalline_tooltip_html) (#5992 by @Jepson2k, @falkoschindler, @evnchn) - Add a
ui.plotlyrun_plot_method()helper (mirroringrun_grid_method/run_chart_method) with aPlotly.extendTracesdemo for appending data without re-sending the full figure (#2660, #6060 by @evnchn, @falkoschindler) - Improve the error message when storing a non-JSON-serializable value in
app.storage, pointing at the offending key path and the underlying type instead of an internal class name (#6044, #6050 by @NichtJens, @falkoschindler, @evnchn)
Bugfixes
-
Fix dropped
app.native.window_args,app.native.settingsandapp.native.start_argswhen the spawned window process can't re-execute the main module (e.g. console-scripts,python -m, PyInstaller); unpicklable values now emit a one-time warning instead of being silently dropped (#6082, #6093 by @VFLins, @falkoschindler, @evnchn) -
Fix blank
ui.aggridwhen flex columns use the infinite row model;auto_size_columnsbecomes a tri-statebool | Nonedefaulting toNone(skipautoSizeStrategywhen columns use flex) (#5087, #6080 by @davetapley, @evnchn, @falkoschindler) -
Fix
Event.emitted()returningNoneinstead of the emitted arguments, adding an opt-inexpect_argsparameter toEvent.subscribe()(#6077, #6078 by @falkoschindler, @evnchn) -
Fix the
ui.sub_pages404 sad-face persisting after client-side navigation when the page is first loaded at an unknown URL (#6069, #6071 by @evnchn, @falkoschindler)Note: Apps that relied on the styled sad-face overlay appearing on
ui.sub_pages404s now see only the inline404: sub page X not foundlabel inside their own chrome. The HTTP 404 status and theshow_404=Falseescape hatch are unchanged. -
Replace the misleading "remove the main guard" reload error for
python -m <pkg>with a targeted message naming the package and the working alternatives (#181, #3769, #5280, #5939, #6066, #6068 by @NichtJens, @evnchn, @falkoschindler) -
Fix
Client has been deletedwarning spam on reload when scene objects are mutated afterawait(#6058, #6059 by @codingpaula, @evnchn, @falkoschindler)Note:
Element.update(),run_method()andget_computed_prop()now stay silent only for the disconnect/reload race; using an element after an explicitelement.delete()emits a one-shot warning with a stack trace.
Documentation
- Improve the Markdown documentation served to AI agents: serve Markdown to known agent user-agents sending a wildcard
Accept, emit heading prefixes while skipping decorative HTML and demo previews, and addaria-label/child-content labels to button Markdown (#6007, #6052, #6053, #6054 by @evnchn, @falkoschindler, @HosseyNJF) - Fill
llms.mdgaps in the element surface vs.ui.*exports (#6048, #6051 by @evnchn, @falkoschindler) - Document how to keep
ui.plotlyresponsive with large datasets by passing NumPy arrays / pandas Series instead of Python lists (#3340, #6095 by @TsaiTung-Chen, @python-and-novella, @mohsenminaei, @krashdifferent, @eddie3ruff, @buiapp, @falkoschindler, @evnchn) - Fix bad Cumulative Layout Shift (CLS) on the documentation homepage (#6087, #6089 by @evnchn, @falkoschindler)
Testing
- Redo: randomize test ports and directories for parallel pytest sessions, re-applying #5960 with a fix for the #6061 import-time
Storage.pathregression (#5960, #6061, #6075 by @falkoschindler, @evnchn)
Infrastructure
- Fix Selenium screenshot artifacts not being uploaded on test failure (#6086 by @HosseyNJF, @evnchn, @falkoschindler)
Special thanks to our top sponsors DiscoLike Inc. and Lechler GmbH ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.12.1
Bugfixes
- Fix auto-prune timers being skipped in script mode (#6072, #6074 by @evnchn, @falkoschindler)
- Fix RuntimeError in native mode on Python 3.14+ Linux (#6062, #6065 by @noafilou, @evnchn, @falkoschindler)
- Fix
ui.uploadroutes listed in/docsand/openapi.json(#6063 by @jsb-zz, @falkoschindler, @evnchn)
Documentation
- Add a note on how to fix non-working
ui.aggridevents (#2878, #6067 by @BlankAdventure, @KrilleGH, @evnchn, @falkoschindler)
Special thanks to our top sponsors DiscoLike Inc., Lechler GmbH and joet-s ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.12.0
Security
⚠️ Prevent local file disclosure inui.restructured_textvia Docutils file insertion directives (GHSA-jfrm-rx66-g536 by @dennyabrahamsinaga, @h3ri0s, @falkoschindler, @evnchn)⚠️ Prevent unauthenticated log-volume denial of service in dynamic resource and ESM module routes (GHSA-pq7c-x8g4-rvp6 by @bitinerant, @evnchn, @falkoschindler)
New features and enhancements
- Make
enable(),disable(),set_enabled(),set_visibility()and many more methods chainable (#6014, #6016 by @stragrothsk, @falkoschindler, @evnchn) - Auto-dedent
ui.mermaidcontent likeui.markdowndoes (#6011, #6012 by @BasementSociety, @falkoschindler, @evnchn) - Suppress alarming
KeyboardInterrupttraceback fromrun.cpu_boundworkers on Ctrl-C (#6025, #6027 by @justus2510, @falkoschindler, @evnchn)
Bugfixes
- Fix
RuntimeError: A SemLock created in a fork context is being shared with a process in a spawn contextinui.run(native=True, reload=True)on CPython ≥ 3.11.5 (#1841, #6045 by @swrpug, @evnchn, @falkoschindler, @rodja, @JensOgorek, @yuanxion, @electronstudio, @knoppmyth, @Qhawaq, @sagarbehere, @frankhuurman, @MrGibus, @BanDroid) - Fix
KeyError: 'error'when callingValidationElement.validate()after theerrorprop was removed viaprops(remove=...)(#5977, #6042 by @manu-ns, @falkoschindler, @evnchn) - Fix silent
window.location.reload()on every WebSocket reconnect (#6018, #6019 by @arodidev, @falkoschindler, @evnchn) - Resolve
ElementFilter.DEFAULT_LOCAL_SCOPEat runtime so changing the class variable actually affects new instances (#6005, #6013 by @gzu300, @DarkRiddle1212, @falkoschindler) - Fix duplicate
app.timerand lifecycle handler (on_connect,on_disconnect,on_delete,on_shutdown,on_exception) registration in script mode (#6003, #6006 by @EchterTimo, @falkoschindler, @evnchn) - Preserve a meaningful DataFrame index in
ui.aggrid.from_pandasandui.table.from_pandas(#5995, #6002 by @NichtJens, @DarkRiddle1212, @falkoschindler, @evnchn)
Note: DataFrames with an informative index now produce additional column(s) in the resulting grid/table. To restore the previous "drop the index" behavior, calldf.reset_index(drop=True)before passing the DataFrame. - Bracket IPv6 hosts and omit default ports in printed URLs (#5996 by @bulletmark, @falkoschindler, @evnchn)
- Fix
ui.codereporting the wrong language and throwing aReferenceErrorin the CodeMirrorfindLanguageerror path (#5982 by @Jepson2k, @falkoschindler) - Fix material settings not applying to GLTF models in
ui.scene(#3515, #5708 by @maria-korosteleva, @evnchn, @falkoschindler, @fabian0702)
Documentation
- Add
llms.md— a self-contained LLM reference covering NiceGUI's API surface, mental models, and common anti-patterns for AI-assisted development (#6021, #6049 by @joko-zauberzeug, @falkoschindler, @evnchn, @rodja) - Restructure CONTRIBUTING.md around the contributor journey, drop rule duplication, and split out a new "For maintainers" section (#6029 by @falkoschindler, @evnchn)
- Restructure AI agent instructions: extract code-review guidance into REVIEW.md, trim AGENTS.md, and tighten Cursor/Copilot prompts (#6030 by @falkoschindler, @evnchn)
- Document packaging with Nuitka (#6009, #6010 by @SHDocter, @falkoschindler, @evnchn)
- Improve authentication example (#6046 by @NichtJens, @evnchn, @falkoschindler)
- Improve
Sortabledocumentation (#6017 by @falkoschindler, @denniswittich) - Clarify the
client_idsecurity model and add an "Examples Are Starting Points" callout (#6004 by @evnchn, @falkoschindler) - Fix Nested
ui.sub_pagesdoc demo link target and label (#5999, #6008 by @aisartag, @falkoschindler, @evnchn)
Testing
- Fix click handler dispatch in user simulation (#6043 by @Jepson2k, @falkoschindler, @evnchn)
Note 1: Click handlers onui.checkboxandui.switchnow receivee.args = Noneinstead ofnot element.value; reade.sender.value(or useon_value_change) for the post-toggle value.
Note 2: Also,find(...).click()no longer broadcasts to every matched element — it picks the lowest-ID enabled match and dispatches once. Tests that relied on simultaneous multi-match clicks need to issue separate calls. - Implement
ui.sub_pagesnavigation in user-simulated tests (#5193 by @rodja, @falkoschindler)
Dependencies
- Bump Mermaid from 11.12.2 to 11.15.0 to consume upstream security patches (#6047 by @falkoschindler, @evnchn)
Infrastructure
- Use
uv sync --lockedin CI workflows so lockfile drift fails fast with a clear diagnostic (#6036 by @evnchn, @falkoschindler) - Use
uv sync --lockedin Copilot setup steps for deterministic agent boot environments (#6040 by @evnchn, @falkoschindler) - Switch Dependabot from the
pipecosystem touv(#6037 by @evnchn, @falkoschindler) - Declare PyPI trove classifiers so NiceGUI appears in PyPI's faceted search (#6041 by @evnchn, @falkoschindler)
- Expand
[project.urls]with PEP 753 well-known labels (#6039 by @evnchn, @falkoschindler)
Special thanks to our top sponsors TestMu AI, Lechler GmbH and joet-s ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.11.1
Bugfix
- Fix
ui.sub_pagessubpaths returning a JSON 404 instead of rendering the page when used insideui.run_with(root=...)(#5998, #5999 by @egursu, @falkoschindler, @evnchn)
v3.11.0
New features and enhancements
- Add lazy imports for the
uimodule to speed up startup by deferring heavy element imports until first access (#5303 by @evnchn, @falkoschindler) - Make
ValueElementandValueChangeEventArgumentsgeneric for proper type inference of.valueand event arguments (#2677, #5785 by @petergaultney, @evnchn, @falkoschindler) - Add favicon support in native mode on Windows (#1745, #5841 by @falkoschindler, @FabianGoessling, @rodja, @DearRude, @evnchn)
- Add
make_sortable()to enable drag-and-drop sorting on container elements likeui.column,ui.row,ui.card, and many more (#932, #4656, #5464, #5855 by @falkoschindler, @evnchn, @EmberLightVFX, @phifuh, @marcrichard22, @nomadfox6, @HansBambel, @sergeyyurkov1, @sukhstanford, @stepheweffie, @TM0088, @weihuan) - Serve a Markdown representation of any NiceGUI page via
Accept: text/markdowncontent negotiation for AI agents and CLI tools (opt-in viaui.run(markdown=True)or@ui.page(markdown=True)) (#5889 by @evnchn, @falkoschindler, @rodja) - Raise an error when
ui.run_with()is called withnicegui.appitself, preventing a self-mount loop that exhausted CPU and RAM (#5954 by @falkoschindler, @evnchn) - Add
ui.keep_aliveto mount children eagerly regardless of visibility, fixing data loss in unmountedui.xtermand unresponsiveui.aggridinside hidden tabs or dialogs (#3033, #5839, #5951 by @falkoschindler, @natankeddem, @kyloe, @amks1, @Ha44a, @evnchn)
Bugfixes
- Fix in-page drag-and-drop in native mode being blocked by the document-level
dragoverhandler (#5943, #5962 by @phifuh, @falkoschindler, @evnchn) - Fix
app.on_exceptionnot catching exceptions from async event handlers (#5945, #5946 by @Rollmops, @falkoschindler, @evnchn) - Fix
PermissionErroron Windows when clearing file-backed storage during shutdown (#5949, #5973 by @atollk, @rodja, @falkoschindler, @evnchn) - Clear streaming client cookie jar between On Air range-requests to prevent unbounded memory growth (#5968 by @AAtomical, @falkoschindler, @evnchn, @stephanpalmer)
- Fix scoped CSS parsing for
@keyframesand similar nested at-rules, and apply scoped selectors to the component root element via tinycss2 (#5969, #5972, #5976 by @jhjcpishva, @falkoschindler, @evnchn) - Return JSON from the 404 handler for non-page endpoints so FastAPI routes keep their default error format (#5974 by @falkoschindler, @evnchn, @jsb-zz, @codingpaula)
- Preserve aspect ratio in
ui.interactive_imagewhensizeis not set, fixing stretched sponsor logos on the website (#5978, #5980 by @lawrenceakka, @falkoschindler, @evnchn) - Fix
ReferenceErrorfrom dangling weakref proxies inui.run_with()(#5979, #5981 by @giunio-prc, @falkoschindler, @evnchn)
Documentation
- Update Trello Cards example with drag-and-drop reordering within a column (#5934 by @entorb, @evnchn, @falkoschindler)
- Improve the xterm example with a configurable command, PTY resize, viewport sizing, and lifecycle hardening (#5959 by @evnchn, @falkoschindler)
- Add
ui.aggriddemo for adding rows without losing client-side edits (#5952, #5967 by @peyman-vasegh, @falkoschindler, @evnchn)
Testing
- Fix
RuntimeErrorwhen a click handler deletes the clicked element during testing (#5935, #5937, #5938 by @samuller, @falkoschindler, @evnchn)
Dependencies
- Bump pytest to v9 to address Dependabot alert 244 (#5953 by @falkoschindler, @evnchn)
- Bump softprops/action-gh-release from 2 to 3 (#5955 by @dependabot, @falkoschindler)
Special thanks to our top sponsors TestMu AI and Lechler GmbH ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.10.0
Security
⚠️ Prevent filename sanitization bypass viaui.uploadon Windows (GHSA-w8wv-vfpc-hw2w by @offset, @evnchn, @falkoschindler)
New features and enhancements
- Add nested dictionary binding support for deeply nested data structures (#2978, #5738 by @Aues6uen11Z, @evnchn, @falkoschindler)
- Add
ui.status_code()to set HTTP status codes from page builders (#5810 by @evnchn, @falkoschindler) - Add
on_resizecallback toui.xtermto communicate terminal size to the PTY (#5847, #5858 by @jacopofar, @evnchn, @falkoschindler) - Unify awaitable handling across lifecycle hooks and tasks (#5878, #5879 by @AlePiccin, @falkoschindler, @evnchn)
- Upgrade Docker image from Python 3.12 to 3.14 (#5900 by @falkoschindler, @evnchn, @rodja)
- Allow
ui.tabto findui.tabsancestor through intermediate containers (#5902 by @falkoschindler, @evnchn) - Warn when native mode runs on a browser engine without ES module support (#5907, #5909 by @drkspace, @evnchn, @iwr-redmond, @falkoschindler)
- Split
helpers.pyinto a package with focused submodules (#5916 by @falkoschindler, @evnchn)
Bugfixes
- Fix
client.ipalways reporting "127.0.0.1" behind reverse proxies and On Air (#4786, #5906, #5920 by @ffilotto, @evnchn, @falkoschindler, @stephanpalmer) - Fix
ValidationElement.errorbeing ignored when no validation is set (#5895, #5903 by @atollk, @falkoschindler, @evnchn) - Fix built-in elements breaking when starting with
tailwind=False(#5868, #5904 by @platinops, @evnchn, @falkoschindler) - Fix
initialized()adding event listeners on every call (#5898 by @falkoschindler, @evnchn) - Fix sad face visibility on dark mode error pages (#5899 by @falkoschindler, @evnchn)
- Fix refreshing sub pages from within nested parent elements (#5912, #5914 by @ZeroPoint095, @falkoschindler, @evnchn)
- Fix Cmd/Ctrl-click on sub-page links not opening new tab (#5928 by @falkoschindler, @evnchn)
- Fix
ui.timercallback tasks leaking when client disconnects mid-execution (#5930, #5931 by @NiklasNeugebauer, @falkoschindler, @evnchn)
Documentation
- Redesign nicegui.io website (#5910, #5911, #5913, #5923 by @falkoschindler, @ma-le-design, @rodja, @evnchn)
- Fix truncated multi-line parameter descriptions in reference docs (#5808, #5905 by @evnchn, @falkoschindler)
- Add keyboard navigation to website search dialog (#5919 by @falkoschindler, @evnchn)
- Add Technological Foundations documentation page (#5835 by @evnchn, @falkoschindler)
- Surface documentation index for AI tooling and discoverability (#5834 by @evnchn, @falkoschindler, @rodja, @iwr-redmond)
Infrastructure
- Update .gitignore for Claude Code and Playwright MCP local files (#5893 by @rodja, @evnchn, @falkoschindler)
- Add PR template instruction to AGENTS.md (#5894 by @rodja, @evnchn)
- Improve PR template checklist for clarity (#5896 by @falkoschindler, @evnchn)
- Auto-format Markdown files via pre-commit hook (#5897 by @falkoschindler, @evnchn)
Special thanks to our top sponsors Lechler GmbH and TestMu AI ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.9.0
Security
⚠️ Prevent memory exhaustion via media streaming routes (GHSA-w5g8-5849-vj76 by @aest3ra, @Khaliun-sw1, @evnchn, @falkoschindler)
New features and enhancements
- Add
ui.parallaxelement based on Quasar Parallax (#4817 by @evnchn, @falkoschindler) - Add camera controls "trackball" and "map" for
ui.scene(#3710, #4820 by @javierlopezrodriguez, @evnchn, @falkoschindler) - Add native window events like shown, resized and file drop to
app.native(#3378, #5866 by @EmberLightVFX, @falkoschindler, @evnchn) - Allow
app.clients()to return all clients when path isNone(#5853 by @AlePiccin, @evnchn, @falkoschindler) - Remove
KWONLY_SLOTSconstant and inline@dataclassarguments (#5856 by @falkoschindler, @evnchn)
Bugfixes
- Fix broken session storage when attaching to a FastAPI app that already has
SessionMiddleware(#2578, #5857 by @denniswittich, @falkoschindler, @evnchn) - Fix
ui.logscroll to bottom on Firefox (#5788, #5842 by @platinops, @falkoschindler, @evnchn) - Fix sort arrow animation in custom table header cells (#5870, #5871 by @JuliusKoenig, @falkoschindler, @evnchn)
- Fix navigation from root page sub-pages to other
@ui.pageroutes (#5705, #5777, #5886 by @CatamountJack, @falkoschindler, @evnchn) - Fix syntax highlighting in
ui.codeby always using DOMPurify (#5877 by @falkoschindler, @evnchn) - Fix
find_speccrashes in compiled environments like PyInstaller (#5747, #5836 by @evnchn, @falkoschindler) - Fix
@ui.refreshable_methodrefresh only updating last instance (#5888, #5890 by @rodja, @evnchn)
Documentation
- Use IntersectionObserver for the navigation tree to reduce render time on small screens (#5832 by @evnchn, @falkoschindler)
- Add "Client-Side Secrets" section to security documentation (#5838 by @oxqnd, @evnchn, @falkoschindler)
- Improve the SVG clock example (#5854 by @rolfn, @falkoschindler, @evnchn)
- Replace the outdated
app.storage.individualAPI withapp.storage.user(#5874 by @KrilleGH) - Fix invalid Python code shown in SPA demo (#5881 by @jmerle, @evnchn, @falkoschindler)
- Use public API imports in examples, tests, and website (#5884 by @falkoschindler)
Testing
- Fix
User.should_seefor child elements inside hidden containers (#5873 by @paco-sevilla, @falkoschindler) - Fix
Usertest simulation for select options withNoneas value (#5880, #5883 by @atollk, @falkoschindler, @evnchn) - Support clicking
ui.tabin user simulation (#5885, #5887 by @atollk, @falkoschindler, @evnchn)
Dependencies
- Fix Dependabot alerts by upgrading rollup, rimraf and Svelte (#5844 by @falkoschindler, @evnchn)
- Fix Dependabot alerts by upgrading vulnerable npm and pip dependencies (#5850 by @falkoschindler, @evnchn)
- Bump actions/upload-artifact from 6 to 7 (#5846 by @dependabot)
- Bump docker/build-push-action from 6 to 7 (#5861 by @dependabot)
- Bump docker/setup-qemu-action from 3 to 4 (#5862 by @dependabot)
- Bump docker/setup-buildx-action from 3 to 4 (#5863 by @dependabot)
- Bump docker/login-action from 3 to 4 (#5864 by @dependabot)
Special thanks to our top sponsors Lechler GmbH and TestMu AI ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v3.8.0
Security
-
⚠️ Prevent XSS via unsanitized method names inrun_method()(GHSA-78qv-3mpx-9cqq by @anuraagbaishya, @evnchn, @falkoschindler)Breaking change: For security reasons,
run_method()andrun_*_method()no longer accept arbitrary JavaScript expressions as method names. Only actual method names are supported now. If you previously passed JS functions likerow = await grid.run_grid_method('(g) => g.getDisplayedRowAtIndex(0).data')
use
row = await run_javascript(f'return getElement({grid.id}).api.getDisplayedRowAtIndex(0).data')
instead.
New features and enhancements
- Preserve cursor position when calling
ui.codemirror.set_value(#5775 by @falkoschindler, @evnchn) - Wake outbox loop on
stop()to avoid ~1s shutdown delay (#5804, #5805 by @Denubis, @evnchn, @falkoschindler) - Prevent
prune_user_storagecrash when UI elements are created beforeui.run_with()(#5480, #5768 by @TulyOpt, @Phloog, @jammerhund, @evnchn, @falkoschindler) - Expose
ui.aggrid.VERSIONconstant for AG Grid version reference (#5726, #5727 by @taschini, @evnchn, @falkoschindler)
Bugfixes
- Guard innerHTML writes in
ui.html,ui.markdownandui.interactive_imageto avoid server-side updates overwriting client-side DOM modifications (#5749, #5761, #5816, #5821, #5823, #5826 by @Denubis, @phifuh, @evnchn, @falkoschindler) - Fix
ui.echartzoom reset on data update by usinggetOption()API (#5819, #5822 by @rtrrtr, @falkoschindler, @evnchn) - Fix
ui.logbackground color being tinted by inner scroll-area element (#5828, #5831 by @rolfn, @falkoschindler, @evnchn) - Cancel connection-wait task when page coroutine completes first to prevent task leak (#5803, #5806 by @Denubis, @evnchn, @falkoschindler)
- Fix jumpy
ui.tablefullscreen toggle with smooth scrolling enabled (#5789 by @falkoschindler, @evnchn) - Guard against missing element in
beforeUnmounthooks during@ui.refreshablerebuild (#5765, #5766 by @evnchn, @falkoschindler) - Fix Leaflet Draw circle resize broken by ES module strict mode (#5751, #5756 by @MicaelJarniac, @evnchn, @falkoschindler)
- Exclude Python prefix directory from reload file watcher to prevent spurious reloads (#5750, #5780 by @phifuh, @evnchn)
- Fix WebSocket URL missing host on HTTPS due to JS operator precedence (#5734 by @evnchn)
- Fix race condition: use static DOMPurify import to avoid mid-module yield (#5732, #5799 by @evnchn, @codingpaula, @rodja, @falkoschindler)
Documentation
- Add security best practices section (#5736 by @evnchn, @falkoschindler)
- Add a "Reaktiv Order Calculator" example (#4758, #5783, #5812 by @FabianGoessling, @buiapp, @evnchn, @buiapp, @falkoschindler)
- Add a "Device Control" example with events and logging (#5201, #5737 by @weinibuliu, @rodja, @eddie3ruff, @evnchn, @falkoschindler)
- Add AI co-authorship attribution guidance to CONTRIBUTING.md (#5758 by @evnchn, @falkoschindler)
- Upgrade the "SQLite Database" example to Tortoise ORM 1.0.0 (#5754 by @falkoschindler)
- Improve Plausible's SPA compatibility for website analytics (#5830 by @evnchn, @rodja)
- Make first demo always load immediately for better SEO (#5793, #5800 by @evnchn, @falkoschindler)
- Fix Googlebot homepage screenshot with unbounded
h-screen(#5792 by @evnchn) - Select search text when reopening search dialog (#5744, #5779 by @Aleborg-Finansforbundet, @marcrichard22, @evnchn, @falkoschindler)
- Fix sponsor button border styling with dark mode support (#5778 by @evnchn)
- Use static URL for sponsor images instead of local path (#5733 by @evnchn)
Testing
- Reuse Chrome driver across screen tests for faster execution (#5729 by @evnchn, @falkoschindler)
- Add support for typing numbers in
UserInteraction(#5771, #5772 by @atollk, @falkoschindler, @evnchn) - Reset
_page_exception_handlerinApp.reset()for test isolation (#5809 by @evnchn) - Fix flaky page test (#5818 by @falkoschindler, @evnchn)
Dependencies
- Update bundled Google Fonts: Material Symbols and Roboto v50 (#5743, #5762 by @VerteinPL, @evnchn, @falkoschindler)
- Bump Mermaid to 11.12.2 (#5755 by @henriknoren, @falkoschindler, @evnchn)
Infrastructure
- Add Copilot coding agent setup (#5770 by @evnchn, @falkoschindler)
- Remove
nanasess/setup-chromedriverfrom CI in favor of runner's preinstalled Chrome (#5740 by @evnchn) - Add GitHub CLI and pre-commit hooks to devcontainer (#5741 by @evnchn, @falkoschindler)
- Add CLAUDE.md with native @AGENTS.md import (#5730 by @rodja, @evnchn)
Special thanks to our top sponsors Lechler GmbH and TestMu AI ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!