narwhals-dev/narwhals

Lightweight and extensible compatibility layer between dataframe libraries!

What it solves

Narwhals is a lightweight compatibility layer that allows developers to write dataframe-agnostic code. It solves the problem of having to write separate implementations for different dataframe libraries (like pandas, Polars, cuDF, and PyArrow) when building libraries that consume dataframes.

How it works

Narwhals provides a unified API—a subset of the Polars API—that wraps native dataframe objects. The process follows three steps:

  1. Wrap: Use narwhals.from_native to wrap a native dataframe or LazyFrame into a Narwhals class.
  2. Operate: Use the supported Polars-style API to perform operations on the data.
  3. Return: Use narwhals.to_native to return the object in its original format (e.g., if the input was a pandas DataFrame, the output is a pandas DataFrame).

Computation remains native to the input library, meaning no additional dependencies are required and overhead is negligible.

Who it’s for

Developers who maintain libraries that consume dataframes and want to support multiple dataframe backends without adding them as dependencies or writing redundant code.

Highlights

  • Broad Compatibility: Supports cuDF, Modin, pandas, Polars, and PyArrow (full API) and Daft, Dask, DuckDB, Ibis, PySpark, and SQLFrame (lazy-only).
  • Zero Dependencies: Only uses what the user passes in, keeping the host library lightweight.
  • Native Performance: Computation stays native to the input library (e.g., GPU compute for cuDF).
  • Full Static Typing: Provides full static typing for better IDE support.
  • Stable API: Maintains a strict backwards compatibility policy.

Related

  • Project
  • Project
  • Project
  • Project
  • Project