github marimo-team/marimo 0.22.0

12 hours ago

What's Changed

This release brings a unified data table explorer, reliability improvements to the programmatic notebook API that power the new marimo-pair agent skill, smarter numeric formatting in tables, faster mo.persistent_cache, and a contextual tips system in the CLI.

⭐ Highlights

Combined row viewer and column explorer

The row viewer and column explorer panels are now unified into a single tabbed "Table Explorer" pane. A single toolbar button opens and closes the panel; Rows and Columns tabs live inside it, and your selected tab persists across open/close.

Pair programming with marimo-pair

The experimental _code API receives reliability fixes in this release, enabling the new marimo-pair agent skill for pair programming in marimo notebooks.

npx skills add marimo-team/marimo-pair

🚨 Breaking changes

mo.image no longer normalizes uint8 values (#8889)

Previously, mo.image() normalized all numeric arrays (including uint8) to the [0, 1] float range. Now, uint8 arrays are always rendered with values in [0, 255] without normalization. Two new parameters — vmin and vmax — let you set explicit value bounds for under- or over-saturated displays. If you relied on the old uint8 normalization, pass vmin=0, vmax=1 explicitly.

__marimo__ location now follows sys.pycache_prefix (#8797)

The __marimo__ directory now respects sys.pycache_prefix, consistent with Python's own __pycache__ placement. This also fixes cache placement for notebooks in nested directories. Existing caches will not be migrated — they can be safely deleted.

Cache version bump (#8793)

The cache format version has been bumped, invalidating existing caches.

✨ Enhancements

  • Remove auto-instantiate from /api/execute endpoint (#8943)
  • Use document as source of truth in code_mode _apply_ops (#8944)
  • Enhance SQLAlchemy engine with safe_execute and inspector methods for SnowFlake (#8920)
  • Support custom cloudpathlib providers in path normalization (#8929)
  • Use variable name as download filename in dataframe viewer (#8811)
  • Unify row viewer and column explorer (#8905)
  • Fix hide_code not taking effect on kernel-created cells (#8926)
  • Virtualize data table rows when pagination is disabled (#8899)
  • Emit document transactions from --watch file reload (#8846)
  • Remove document mutation from session.notify() (#8886)
  • Style fix for li & ol: reduce margin and restore original disc (#8768)
  • Avoid selecting cells in table when interactive elements (#8862)
  • Lazy-load KaTeX via dynamic import of @streamdown/math (#8874)
  • Display startup tips in CLI (#8836)
  • Add ListSQLSchemas to support lazy schema fetching in datasource panel (#8824)
  • Auto right-align numeric columns and normalize decimal formatting in tables (#8887)
  • Mechanism for parallel read/write in mo.persistent_cache (#8805)
  • Convert fonts from TTF to WOFF2, remove unused font files (#8873)
  • Prefer tomllib over tomlkit for reading TOML (#8827)
  • Support markdown in file tree notebook creation (#8770)
  • Allow code as positional arg in edit_cell (#8806)
  • Discourage casual cell naming in code mode (#8804)
  • Rename check to skip_validation in code mode API (#8803)
  • Document stale globals caveat on ctx.globals (#8802)
  • Make _CellsView behave like a read-only ordered dict (#8778)
  • Downgrade model fallback log from warning to debug (#8773)
  • Add snippet buttons in storage file viewer (#8737)
  • Isolation when running multiple notebooks in an app server (#8611)
  • Pass raw data for tables during search and copy text/html to clipboard (#8622)
  • Support dragging range slider track to move entire range (#8698)
  • Propagate notebook __doc__ to cell execution namespace (#8636)
  • Add POST /api/kernel/focus_cell endpoint for external editor integration (#8497)

🐛 Bug fixes

  • Fix _code_mode cell ID collisions on large notebooks (#8951)
  • Support datetime values in mo.ui.matplotlib selection masks (#8940)
  • Sanitize password in frontend render (#8857)
  • Kill LSP child processes on shutdown to prevent memory leak (#8927)
  • Replace lodash imports with built-in or custom (#8878)
  • Remove Content-Length from virtual file StreamingResponse (#8928)
  • Enforce cell_ids parameter in session serialization and caching (#8904)
  • File descriptor conflicts in terminal ws (#8896)
  • Remove matplotlib stretch effect in mo.ui.matplotlib (#8883)
  • Key pending tasks by event loop (#8875)
  • Use decoding as a heuristic for binary data, and download accordingly (#8858)
  • Add script dependencies to data_editor example (#8867)
  • Fix cached self entries fsspec (#8863)
  • Provide a warning when toml keys are skipped for security (#8854)
  • Set file in compilation for app mode linecache and better stack traces (#8800)
  • Use python -m pip instead of pip --python for PipPackageManager (#8840)
  • Remove litellm (#8852)
  • Render data-tooltip in portal to prevent clipping in overflow containers (#8813)
  • Clamp memory reported in cgroup v1 reports (#8841)
  • Fix asyncio tasks starved by blocking control loop (#8825)
  • Keep markdown preview in sync on local edits (#8832)
  • Stop mac completion bindings from stealing backticks (#8829)
  • Ignore blank line rules (E302, E305) (#8815)
  • Fix cells stuck as "needs run" after backend-initiated execution (#8794)
  • Graceful fallback for unsupported extension dtypes in to_arrow_ipc (#8785)
  • Harden conversion path for ipynbs (#8795)
  • Fix console output routing for code_mode run_cell (#8790)
  • Append .py extension to markdown notebooks for correct ruff formatting (#8786)
  • Patch html-to-image for PNG export font crash and tainted canvas (#8754)
  • Exclude index columns for pivot for count/sum agg (#8769)
  • Markdown bullets inside of details (#8767)
  • Make the pickling mechanism in mo.cache more robust (#8761)
  • Recursive private function not detected (#8762)
  • Fallback static parsing for completely invalid notebooks (#8723)
  • Fix Ty LSP startup and stale diagnostics in notebook editor (#8390)
  • Slider editable input ignores debounce bug (#8682)
  • Fix three issues with mo.mpl.interactive in marimo run mode (#8760)

📚 Documentation

  • Replace white background in NumFOCUS logo with transparency (#8812)
  • Add markdown support for documentation with edge middleware and conversion scripts (#8796)

🔬 Preview features

📝 Other changes

  • Refactor session extensions to use EventAwareExtension base class (#8678)
  • Update dependency yaml to v2.8.3 [security] (#8902)
  • Update dependency path-to-regexp to v8.4.0 [security] (#8913)
  • Bump yaml from 1.10.2 to 2.8.3 (#8897)
  • Update dependency yaml to v2.8.3 [security] (#8891)
  • Lint configuration (#8560)
  • Make transitionCell pure by injecting parseOutline (#8729)
  • Add new NotebookDocument model (#8842)

Contributors

Thanks to all our community and contributors who made this release possible: @abhiyadav2345, @akshayka, @app/dependabot, @app/marimo-github-maintenance-bot, @app/renovate, @Bortlesboat, @daizutabi, @dmadisetti, @kirangadhave, @koaning, @Light2Dark, @manzt, @mauro-cerzosimo, @mscolnick, @peter-gy, @Sushit-prog, @tomneep

And especially to our new contributors:

Full Changelog: 0.21.1...0.22.0

Don't miss a new marimo release

NewReleases is sending notifications on new releases.