Nishant Gaurav

Mar 05, 2026 • 7 min read

18 Python Libraries Worth Switching To in 2026 tags: python, tooling, backend, ai

18 Python Libraries Worth Switching To in 2026 tags: python, tooling, backend, ai

My team's requirements.txt last year had 5 separate linting tools configured.

black, flake8, isort, pyflakes, autoflake — all doing overlapping jobs, all needing separate config files, all slowing down CI.

One tool replaced all five. Runs 100x faster. Most people on the team had never heard of it.

That's Python in 2026 — the ecosystem has moved significantly, but most developers are still running 2019-era workflows because no one handed them the upgrade guide.

Here's that guide. No NumPy, no Pandas, no Matplotlib — you know those already.


Toolchain First

1. uv — Replace pip, virtualenv, and pyenv. All three.

Written in Rust by the Ruff team. Dependency resolution in milliseconds, not minutes.

uv venv # create env
uv pip install fastapi pydantic # 10-100x faster than pip
uv run --with httpx script.py # inline deps, no pollution

50k+ GitHub stars. Fastest growing Python tool in recent memory.


2. ruff — One linter to replace five

Same team as uv. Replaces black + flake8 + isort + pyflakes + autoflake.

ruff check . # lints entire codebase in <1 second
ruff format . # formats like black, faster

One pyproject.toml block. No more juggling five config files.

[tool.ruff]
line-length = 88
select = ["E", "F", "I"]

35k+ stars. If you're not using this, you're maintaining unnecessary complexity.


Data & Validation

3. pydantic v2 — Not just validation anymore

Rewritten in Rust. 5–50x faster than v1. But the bigger story: it's now the runtime type system Python never had.

from pydantic import BaseModel, EmailStr, Field
from typing import Annotated

class User(BaseModel):
 name: str
 email: EmailStr
 age: Annotated[int, Field(gt=0, lt=150)]

Backbone of FastAPI, Instructor, PydanticAI, and most serious AI tooling. Not optional in 2026.


4. polars — DataFrames done right

Not just "faster than Pandas." The API is better. Explicit. No confusing index behavior. Lazy evaluation out of the box.

result = (
 pl.scan_csv("big_file.csv") # lazy — nothing loads yet
 .filter(pl.col("age") > 25)
 .group_by("dept")
 .agg(pl.col("salary").mean())
 .collect() # executes now, optimized
)

On large datasets, Polars builds a query plan and optimizes before executing — like a SQL engine. 10–100x faster, less memory. 32k+ stars.


HTTP & Async

5. httpx — requests with async support that actually works

Same API as requests. Plus HTTP/2. Plus first-class async.

# Sync — familiar
response = httpx.get("https://api.example.com/data")

# Async — runs requests concurrently
async with httpx.AsyncClient() as client:
 results = await asyncio.gather(
 client.get("/users"),
 client.get("/orders"),
 client.get("/products"),
 )

If your code hits a network and you're not async, you're leaving performance behind.


Developer Experience

6. rich — Terminal output from this decade

print() debugging, but useful.

from rich.console import Console
console = Console()

console.print_json('{"name": "Alice"}') # syntax highlighted
console.print(table) # beautiful tables
for item in track(items, "Processing..."): # progress bar
 process(item)

50k+ stars. Also replaces the default Python traceback with one that's readable.


7. loguru — Logging without the 20-line setup

Python's built-in logging works. It also requires a lot of boilerplate before it does anything useful. Loguru works at import.

from loguru import logger

logger.info("Started")
logger.add("logs/app_{time}.log", rotation="500 MB", retention="10 days")
logger.bind(user_id=123).info("Request processed")

Colored output, file rotation, structured context — all zero config.


8. typer — CLIs that document themselves

argparse is filling out paperwork. Typer is writing Python.

@app.command()
def process(
 input: str = typer.Argument(..., help="Input file path"),
 verbose: bool = typer.Option(False, "-v"),
 limit: int = typer.Option(100),
):
 """Process input file and output results."""
 ...

Auto-generates --help. Validates types. Supports subcommands. Built on Click without the ceremony.


Data & Databases

9. duckdb — SQL inside your Python script, no server needed

SQLite is for transactional workloads. DuckDB is for analytics — aggregations, joins, column operations on large datasets.

# Query CSV directly. No schema. No import.
result = duckdb.sql("""
 SELECT dept, AVG(salary), COUNT(*)
 FROM 'employees.csv'
 WHERE hire_date > '2022-01-01'
 GROUP BY dept
""").fetchdf() # returns a DataFrame

Columnar storage. Millions of rows in seconds. No server. No setup. 26k+ stars.


10. marimo — Jupyter but reproducible

Two things wrong with Jupyter: cells run out of order (hidden state), and git diffs are unreadable JSON.

marimo fixes both. Notebooks are stored as plain .py files. Cells execute based on data dependencies, not order.

# Reactive — change this slider, dependent cells auto-rerun
data = mo.ui.slider(1, 100, label="Sample Size")
chart = mo.ui.table(generate_data(data.value))

18k stars in ~1 year. The data community is watching.


AI Tooling

11. instructor — Structured output from LLMs, reliably

Ask an LLM for JSON. Get mostly JSON. Sometimes broken. Sometimes missing fields.

Instructor wraps any LLM client and uses Pydantic models to define exactly what you want back. Auto-retries with validation errors as context if the model gets it wrong.

class Person(BaseModel):
 name: str
 age: int
 skills: list[str]

person = client.chat.completions.create(
 model="gpt-4o",
 response_model=Person,
 messages=[{"role": "user", "content": "John is a 32-year-old Python dev..."}]
)
# person.skills → ["Python", "FastAPI", ...] — always typed, always valid

12k stars. Essential for any production LLM pipeline.


12. pydantic-ai — Agent framework that looks like Python, not magic

Most agent frameworks are overengineered. PydanticAI follows the same philosophy as Pydantic: type safety, explicit interfaces, no magic.

agent = Agent(
 "openai:gpt-4o",
 result_type=WeatherResult, # typed output
 system_prompt="You are a weather assistant."
)
result = await agent.run("Weather in Tokyo?")
print(result.data.recommendation) # typed, not raw text

Dependency injection for testing. Multi-model support. Streaming. The right abstraction level. 14k stars.


13. markitdown — Any document → Markdown in one line

Microsoft released this quietly in late 2024.

md = MarkItDown()
result = md.convert("report.pdf") # PDF
result = md.convert("data.xlsx") # Excel
result = md.convert("deck.pptx") # PowerPoint
result = md.convert("https://...") # URL

Converts PDF, Word, Excel, PowerPoint, HTML, images (OCR), audio → clean Markdown. The obvious use case is feeding documents to LLMs.

86,000 GitHub stars. Not a typo.


Production Patterns

14. tenacity — Retry logic without the while loop

Network calls fail. APIs rate-limit. Databases have transient errors. The naive implementation is always a messy while loop.

@retry(
 stop=stop_after_attempt(5),
 wait=wait_exponential(min=1, max=60),
 retry=retry_if_exception_type(httpx.TimeoutException)
)
async def fetch(url: str):
 ...

Composable, configurable, async + sync. Handles exponential backoff, jitter, and logging automatically.


15. structlog — Logs as data, not strings

Loguru for dev. structlog for production.

log.info("payment_failed",
 user_id=123,
 error_code="insufficient_funds",
 amount=99.99
)

Dev output: readable key-value pairs. Production output: clean JSON that Datadog/Elasticsearch can parse and index.

SELECT * FROM logs WHERE error_code = 'insufficient_funds' — that's what structured logs give you.


16. anyio — Async code that runs on any backend

asyncio and trio. Code written for one doesn't work on the other. anyio abstracts both.

async with anyio.create_task_group() as tg:
 for item in items:
 tg.start_soon(process_single, item)

anyio.run(main) # runs on asyncio
anyio.run(main, backend="trio") # same code, runs on trio

FastAPI, Starlette, and httpx are all built on anyio. You're already using it indirectly.


17. fastapi deeper — You're using ~30% of it

You probably know FastAPI. Here's what most people skip:

@app.post("/orders", response_model=OrderResponse, status_code=201)
async def create_order(
 order: OrderCreate, # validated automatically
 token: Annotated[str, Depends(security)], # injected automatically
 db: Annotated[Session, Depends(get_db)] # DI — easy to mock in tests
) -> OrderResponse:
 ...

Background tasks, WebSockets, middleware, dependency injection, OpenAPI docs — all from type annotations. State of Python 2025 survey: FastAPI now leads Flask in new project adoption.


18. stamina — Production retries with zero config

Tenacity when you need control. stamina when you just want it to work correctly.

@stamina.retry(on=httpx.HTTPError, attempts=5)
def fetch_user(user_id: int):
 response = httpx.get(f"/users/{user_id}")
 response.raise_for_status()
 return response.json()

Adds jitter by default (prevents thundering herd). Integrates with structlog. Toggle off in tests with one line: stamina.set_active(False).


The pattern underneath all of this

Rust is eating Python's tooling layer. uv, Ruff, Polars, Pydantic v2 — all have Rust cores. Python stays as the interface; Rust handles the performance-critical parts.

Type hints are no longer optional. Pydantic, FastAPI, Instructor, PydanticAI — all built around annotations. Writing untyped Python in 2026 is actively making your life harder.

The LLM tooling layer is finally maturing. First wave: demos. Instructor and PydanticAI are the second wave — production-grade tools with validation, error handling, typed interfaces.


Where to start if you're not already:

  • Still using pip for everything → switch to uv today

  • Messy linting setup → ruff this week

  • Building with LLMs → instructor immediately

  • Data work → give polars one real project

The gap between developers who've adopted this stack and those who haven't is growing. The work takes the same amount of time; the experience is just completely different.


What am I missing from your stack? Drop it in the comments.

Join Nishant on Peerlist!

Join amazing folks like Nishant and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

10

1