What's Changed
This release brings major upgrades to table filtering, adds speaker notes to slide view, and lets WASM notebooks query remote files with DuckDB.
⭐ Highlights
Powerful new table column filters
Table columns now support the full operator set across every dtype. Text columns get contains, starts_with, ends_with, equals, regex, is_empty, and more, with a slash-bracketed regex input and a creatable values picker for in / not_in. Number columns get native between, and the new date/datetime/time filter UI brings the same operator coverage to date-like columns with smart clipboard paste for ISO/US/RFC dates and A - B ranges (#9597, #9615).
Screen.Recording.2026-05-18.at.7.54.06.PM.mov
Speaker notes for slides
Press S in slide view to open speaker notes alongside the current slide, including in fullscreen and kiosk mode (#9533).
Screen.Recording.2026-05-12.at.5.32.23.PM.mov
Query remote files with DuckDB in WASM notebooks
WASM notebooks can now read CSV, Parquet, JSON, and GeoJSON over HTTP from mo.sql, SQL cells, raw duckdb.sql/query/execute, connection SQL methods, and the duckdb.read_csv/read_parquet/read_json Python API. marimo rewrites the AST with sqlglot, fetches the remote file via its shared WASM fetch util, and binds the result as a pandas DataFrame that DuckDB can scan (#9480).
SELECT * FROM read_csv('https://example.com/cars.csv')✨ Enhancements
- Expand column filter operators and pill-editor UX (#9597)
- Date/datetime/time filter UI (#9615)
- Add speaker notes for slides (#9533)
- Support HTTP DuckDB queries in WASM notebooks (#9480)
- Snapshot document and outputs in MCP execute_code (#9654)
- Rename ctx.notify to broadcast_raw_notification (#9581)
- Record staleness reads on .code access only (#9655)
- Expose cell outputs to code_mode (#9653)
- Make
marimo newCLI help page render properly at 80 columns (#9636) - Read-before-write protection for cell edits (#9585)
- Skip stdlib/site-packages on per-cell check (#9629)
- Show cell index in dependency minimap (#9633)
- Extract ModuleReloader/ModuleWatcher into AutoreloadManager (#9590)
- DRY up code between wasm and native kernel (#9591)
- Update default duckdb mo.sql deps (#9599)
- Show .git and .venv in file browser (#9606)
- Support disabled on dropdown and multiselect (#9600)
- Split kernel command dispatch into router + callback bundles (#9577)
- Add Prompt tab to pair-with-agent modal (#9568)
- Replace MarimoFileKey alias with FileKey ADT (#9483)
- Optimize memoize_last_value for faster UI reactivity (#9555)
- Hardening pass — utilities, deprecated API cleanup, lifespan fix (#9552)
- Stream uploads to disk instead of buffering (#9527)
- Add
kernel_session()as context manager, DRY up tests (#9554) - Sandboxed exports for consistent wasm envs (#9519)
- Add tool approval flow for chat-panel (#9507)
- Remove input for hidden cells from exports (#9548)
- Parallelize file uploads with bounded concurrency (#9528)
- Use multipart/form-data for /api/files/create (#9521)
- Show loading and success toasts for exports (#9509)
- Add cut cells command (#8019)
- Allow def declarations within functions (#9379)
- Correlate scratchpad completion with run_id (#9350)
- Make disconnect indicator clickable to reconnect (#9410)
🐛 Bug fixes
- Guard SQL ref extraction on sqlglot availability (#9656)
- Fix lru_cache(...) resetting when cell is rerun (#9609)
- Skip reload when notebook has git conflict markers (#9626)
- Stream
lazy-polarsoutput viapl(lazy=True)(#9648) - Trigger downloads programmatically to work inside cross-origin iframes (#9649)
- Stdin handling for empty submissions (#9556)
- Avoid pyarrow requirement for polars output in DuckDB engine (#9643)
- Isolate test_project_dependencies from pyproject.toml pollution (#9634)
- Restore selection_mode='all' and accept list form (#9630)
- Allow freezing pandas index columns (#9631)
- Inline
public/images in static HTML export (#9627) - Remove unused flush_messages plumbing (#9598)
- Migrate remaining background-task sites to asyncio_utils (#9596)
- Normalize dev version in static notebook asset URL (#9592)
- JSON-escape > and < in web-component attrs (#9595)
- Render Enum members as str in JSON serializer (#9594)
- Narrow callback deps, drop get_context in cache (#9589)
- Callback bug fixes in cache clear, dataset connections, and model updates (#9588)
- Avoid treating class-like array refs as data primitives (#9569)
- Group kernel streams into KernelStreams; phase-key NotebookCellHooks (#9571)
- Pass theme to register_formatters in pyodide and script runner (#9553)
- Use Referrer-Policy same-origin to fix Chrome 147+ Error code 5 on macOS (#9543)
- Extract shared kernel lifecycle for subprocess and pyodide (#9541)
- Hide watermark when printing (#9525)
- Markdown singleton to mitigate reported race condition (#9530)
- Contain comm callback errors in mpl_interactive (#9532)
- Disconnect toolbar callbacks on cell rerun (#9531)
- Fix overflow and support vertical tabs (#9511)
- Allow hosts to size-gate downloads (#9510)
- Detect marimo notebooks with long module docstrings (#9652)
- Fix argument splitting on '--' in the command line (#9368)
📚 Documentation
- Update markdown_indentation.md (#9622)
- Standardize supported dataframe backends across UI elements (#9583)
- Attribution (#9608)
- Polish tutorial notebooks (#9573)
- Add detailed docstring for CLI recover command (#9546)
- Note that an added notebook will be downloaded if it's a URL path (#9545)
- Clarify that marimo run hides source code by default (#9529)
- Add Mermaid theme customization options (#9478)
- Remove formatter recommendation section from guide (#9434)
📝 Other changes
- Enforce single backticks in Python docstrings (markdown, not RST) (#9645)
- Add data-testid to top-level chrome elements (#9566)
- Fix pnpm-workspace.yaml configuration (#9574)
- Fix pnpm-workspace.yaml configuration (#9515)
Contributors
Thanks to all our community and contributors who made this release possible: @akshayka, @archpulse, @arghaffari, @dmadisetti, @jeremytanjianle, @JoostGevaert, @kirangadhave, @leoadberg, @Light2Dark, @manzt, @mchav, @mscolnick, @peter-gy, @Rowlando13, @Shamik-07, @williambdean
And especially to our new contributors:
- @archpulse made their first contribution in #9555
- @arghaffari made their first contribution in #9543
- @jeremytanjianle made their first contribution in #9569
- @leoadberg made their first contribution in #9609
- @Rowlando13 made their first contribution in #9636
- @Shamik-07 made their first contribution in #9379
Full Changelog: 0.23.6...0.23.7