This release focuses on anywidget improvements, along with UI enhancements and many bug fixes.
⭐️ Highlights
anywidget improvements
This release improve marimo's anywidget integration with better lifecycle management, performance, and static export support (#8244, #8166, #8163, #8256, #8168, #8159, #8082). Anywidgets now render in static HTML exports with client-side interactivity preserved, and mo.state setters work in widget callbacks.
Together these changes improve performance and reliability for interactive widget libraries. Here's 10M points rendered interactively on a 24GB M4 MacBook Air with jupyter-scatter:
Try it for yourself on molab!
Column header alignment in tables
Column headers now follow the same alignment as cell data when using text_justify_columns, fixing the visual mismatch where headers stayed left-aligned while data was right- or center-aligned. (#8236)
Hide reusable functions from the dependency graph
A new "Hide reusable functions" toggle in the dependency graph settings panel lets you declutter the graph by hiding def cells that don't have edges to other cells. (#8228)
✨ Enhancements
- Allow
mo.statesetters in widget callbacks (#8244) - Persist anywidget model state in static HTML exports (#8166)
- Add toggle to hide reusable functions from dependency graph (#8228)
- Always show default value for CLI args (hide if default is None) (#8246)
- Add disabled parameter to mo.ui.chat (#8214)
- Align column headers with text_justify_columns setting (#8236)
- Support for
dict(ChatMessage(...))(#8091) - Add uv version to
marimo envoutput (#8157) - Merge model messages into a single replay snapshot (#8163)
🐛 Bug fixes
- Grab module css from model-state instead of passing via DOM attributes (#8256)
- Remove openai from required dependencies (#8265)
- Add back margin for missing gap in file explorer panel (#8267)
- Batch anywidget model updates like UI element updates (#8168)
- Better datastructures for kernel Runner (#8251)
- Don't read the full file for OSFileSystem._is_marimo_file (#8253)
- Prevent sidebar resize handle from overlapping file explorer buttons (#8181)
- Normalize Html subclasses in as_html for correct f-string formatting (#8223)
- Use variable name as download filename in dataframe viewer (#8227)
- Avoid unnecessary duckdb calls in stats and getting db names (#8250)
- Use mount_config.code and filename as fallback in WASM mode (#8161)
- Continue on thumbnail capture timeout (#8254)
- Include xfailed and xpassed in pytest summary counts (#8220)
- Preserve justify on nested stacks when widths/heights are set (#8219)
- Suppress RuntimeWarning for all-NaN DataFrame columns (#8217)
- Allow interaction with sidebar behind package alert popup (#8216)
- Prevent margin collapse between consecutive cell outputs (#8215)
- Don't enable reactive tests in run mode (#8252)
- Upgrade codemirror-languageserver to fix prefix completions with underscore (#8245)
- Handle null registration.active in service worker registration (#8213)
- Set data-theme attribute on body for third-party dark mode compat (#8231)
- Decorator invalidation for caching (#8171)
- Disable panel resize handles when panels are collapsed (#8183)
- Preserve return statements inside nested functions when pasting (#8222)
- Close anywidget comms on cell re-execution and deletion (#8159)
📚 Documentation
- Fix reddit links (#8266)
- Gallery + OpenGraph preview docs (#8122)
- Removes ploomber deployment (#8249)
📝 Other changes
- Preserve function return type in live docs panel (#8210) (#8263) (3828e5f)
- Bump loro (#8264)
- Update Plotly to 3.3.1 and add heatmap click event (#8255)
- Update dependency anywidget to ~=0.9.21 (#8082)
- Enable reading session cache in App Mode (configurable) (#7895) (d85e9b7)
- Update codemirror dependencies (#8170)
- Replace react-plotly.js with vendored Plot component (#8238)
- Respect display.dataframes config setting (#8053) (190ca31)
Contributors
Thanks to all our community and contributors who made this release possible: @AhmadYasser1, @akshayka, @dmadisetti, @ffmiruz, @julianpistorius, @koaning, @Light2Dark, @manzt, @maxkoretskyi, @mscolnick, @nojaf, @peter-gy
And especially to our new contributors:
- @chrisflath made their first contribution in #8053
- @jpopesculian made their first contribution in #7895
- @AhmadYasser1 made their first contribution in #8222
- @julianpistorius made their first contribution in #8249
- @ffmiruz made their first contribution in #8161
Full Changelog: 0.19.9...0.19.10

