Modern Python Stack in 2026: uv, Ruff, Marimo, Polars
Python’s tooling got rewritten in Rust and the day-to-day is unrecognisably faster. Four swaps did most of it, all covered in the MLtools and Software_Tools repos.
The swaps
| Old | New | Job | Why switch |
|---|---|---|---|
| pip + venv + poetry | uv | Install, lock, envs | One tool, ~10-100x faster resolves |
| black + flake8 + isort | Ruff | Lint + format | One tool, ~100x faster |
| Jupyter | Marimo | Notebooks | Reactive, pure-.py, no hidden state |
| pandas | Polars | DataFrames | Multi-threaded, lazy, lower memory |
The theme: one Rust tool replacing three Python ones, faster and with fewer foot-guns.
uv: install speed
Cold-cache environment creation for a mid-size project. This is the difference between a coffee break and a keystroke.
Ruff: lint speed
Linting a ~250k-line codebase. Ruff turns a CI stage into an editor-latency check.
Polars vs pandas
A groupby-aggregate over ~50M rows. Polars is multi-threaded and lazy; pandas is single-threaded and eager.
How they fit together
flowchart LR UV[uv: env + deps] --> DEV[Dev loop] RUFF[Ruff: lint+format] --> DEV MAR[Marimo: explore] --> DEV POL[Polars: data] --> DEV DEV --> CI[Fast CI]
Takeaway
If you change one thing, make it uv - it subsumes pip/poetry/pyenv and the speed is felt every day. Then Ruff for lint/format, and Polars the moment pandas feels slow. Marimo is the wildcard worth trying if hidden notebook state has ever burned you.