Narwhals
Compatibility layer for Python dataframe libraries. Write code once, run on pandas, Polars, cuDF, Modin, and PyArrow. narwhals exposes a common API subset that works identically across backends. Critical for library authors who want to support multiple dataframe backends, and for agent data pipelines that may receive pandas or Polars DataFrames interchangeably.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Data processing library — no network exposure. No credential handling. Community-maintained.
⚡ Reliability
Best When
You're writing a library or utility that needs to accept multiple DataFrame types, or you want to write pandas-like code that can transparently use Polars for better performance.
Avoid When
You need Polars-specific features (lazy evaluation, streaming) or pandas-specific features not in narwhals' common subset.
Use Cases
- • Build agent data processing functions that work with both pandas and Polars DataFrames without if/else branching on the input type
- • Write dataframe-agnostic agent libraries that accept any DataFrame type and process it without forcing a specific backend
- • Migrate agent data pipelines from pandas to Polars incrementally — narwhals lets both coexist without rewriting shared code
- • Use narwhals in agent data validation and transformation code that must handle data from different upstream sources (some pandas, some Polars)
- • Test agent data processing logic once and validate it works identically across pandas and Polars for correctness assurance
Not For
- • Code that uses pandas-specific features not in the common subset — narwhals exposes an opinionated common API; deep pandas-specific APIs require pandas directly
- • Performance-critical paths where Polars-native API is needed — narwhals has overhead from the compatibility layer; use Polars directly for hot paths
- • Spark or Dask distributed DataFrames — narwhals targets single-node in-memory DataFrames; distributed computing requires different tools
Interface
Authentication
Data processing library — no authentication.
Pricing
Community-maintained open source. MIT license.
Agent Metadata
Known Gotchas
- ⚠ narwhals wraps DataFrames in its own type — pass the narwhals DataFrame to narwhals functions, but extract the native frame with .to_native() before passing to non-narwhals functions
- ⚠ narwhals API is a subset — not all pandas or Polars operations are supported; operations outside the common subset raise AttributeError; check narwhals docs for supported operations
- ⚠ Lazy vs eager execution differs by backend — Polars is lazy by default; narwhals normalizes this with collect() but the execution model affects when errors surface
- ⚠ Type inference across backends may differ slightly — integer types (int32 vs int64) and null handling may not be identical between pandas and Polars via narwhals; validate output types
- ⚠ narwhals version and backend version compatibility matrix changes — a narwhals version may require minimum pandas/Polars versions; pin dependency versions in agent data pipelines
- ⚠ Expression API (.select(), .filter() with narwhals expressions) is narwhals-specific — don't mix narwhals expressions with pandas boolean masking or Polars native expressions in the same operation
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Narwhals.
Scores are editorial opinions as of 2026-03-06.