# nodejs-polars puts the Rust dataframe engine behind a Node API

> nodejs-polars is the Node.js front end of Polars, binding the Rust dataframe engine through NAPI with prebuilt binaries for eight platforms and a TypeScript API that returns series and dataframes. It suits server side JavaScript and TypeScript services that need columnar data handling, and it does not run in the browser.

**pola-rs/nodejs-polars** — nodejs front-end of polars

- Repository: https://github.com/pola-rs/nodejs-polars
- Website: https://pola-rs.github.io/nodejs-polars/
- Stars: 761 · Forks: 60
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/pola-rs-nodejs-polars

## A binding, not a reimplementation

Polars is described as blazingly fast DataFrames in Rust, Python, Node.js, R and SQL, and nodejs-polars is the Node.js front end of it. The repository makes the layering clear. The primary language is TypeScript, but the Cargo manifest shows the real engine, with polars-core, polars-io, polars-lazy, polars-ops, polars-arrow, polars-utils and polars-compute all pinned at version 0.55.2, and the crate is built as a cdylib and a lib. The bridge is napi, the Node API, at version 3.12.4 with the napi8 and serde-json features, plus napi-derive for the macro layer. So the dataframe logic, the lazy query planner and the IO all live in Rust, and the TypeScript you import is a typed surface over a native addon. That distinction matters for expectations. A JavaScript reimplementation of a columnar engine would be a different library with different performance characteristics. This is the same engine the Python and Rust users run, and the differences between the language front ends are surface differences, not engine differences.

## Prebuilt binaries for eight targets, and a source build when there is none

The napi configuration in package.json lists the targets it ships, and there are eight of them. On Linux there is x86_64-unknown-linux-gnu and x86_64-unknown-linux-musl, plus aarch64-unknown-linux-gnu and aarch64-unknown-linux-musl, and aarch64-linux-android. On Apple platforms there is x86_64-apple-darwin and aarch64-apple-darwin, and on Windows there is x86_64-pc-windows-msvc. The musl and gnu split matters for container images, since a gnu build will not run on a musl base and vice versa, and Android is there for the mobile case. The published package contains only the bin directory, and the main entry points at bin/index.js. When a prebuilt binary does not cover your platform, the README gives the from source path, which needs the latest Rust compiler, then npm or yarn install, then a choice between the fastest binary with very long compile times and a debug build with the fastest compile. The minimum requirements list Node 18 or newer and Rust 1.86 or newer, with the Rust version needed only for development, while the engines field in package.json requires Node 20 or newer.

## The API shape, from a Series to an expression

The TypeScript surface follows the Python Polars API closely, and the README examples show a Series behaving like a first class value. A Series is created with a name and an array, methods return values you can print, and the object is iterable, so spreading it into an array gives you the underlying values, and indexing by position works the same way. That last point is not cosmetic, because it is what makes a Series usable in ordinary JavaScript code that expects an array. DataFrames are constructed from an object of arrays, and the operations available on them cover sorting, selecting, expression building and grouping. The expression vocabulary is the interesting part, with pl.lit for a literal value, pl.col for a column, alias to name a result, filter to narrow rows, sum to aggregate, over to do a windowed operation, and reverse and flatten to reshape. The example in the README combines all of these in one select call to produce a table with grouped sums and a reversed column, which is the clearest indication of how much of the Polars expression language is exposed here.

## Installing it, and the release rhythm

The package is published to npm as nodejs-polars, and the README gives the three package manager forms:

```sh
yarn add nodejs-polars   # yarn
npm i -s nodejs-polars   # npm
bun i -D nodejs-polars   # Bun
```

Both ESM and CommonJS import styles are supported, which matters for a package that has to drop into an existing codebase without a build change:

```js
// esm
import pl from 'nodejs-polars';

// require
const pl = require('nodejs-polars'); 
```

The README also says releases happen quite often, weekly or every few days, and suggests updating regularly to get the latest bugfixes and features. That is worth weighing against the version churn it implies. The recent tags are nodejs-polars-v0.26.1 on 2026-09-14, nodejs-polars-v0.26.0 on 2026-08-19 and nodejs-polars-v0.25.2 on 2026-07-28, so the 0.26 line is where the current work is. The package version in package.json reads 0.26.1, the licence is MIT, and the last push was on 2026-09-15. The versioning is still below 1.0, which is a signal that the API can move.

## Deno imports straight from npm, with a notebook path

Deno is treated as a first class target rather than an afterthought. In Deno modules you can import polars straight from npm:

```typescript
import pl from "npm:nodejs-polars";
```

And the notebook story is a genuine one, because DataFrames render as text tables in a Deno notebook. With Deno 1.37 you use the display function to display a DataFrame in the notebook, importing pl from npm and display from a deno.land module, then reading a TSV file with pl.readCSV and passing the frame to display. With Deno 1.38 the requirement loosens, since the dataframe only has to be the last expression in the cell. Both examples read the same world atlas TSV from a CDN and parse it with a tab separator, which is a small but complete example of reading a delimited file into a frame. The general point is that the server side story covers Node, Bun and Deno, and the Deno route needs no separate build.

## Server side only, and the browser answer is a different package

The constraint that will decide this for many teams is stated in a note at the top of the README. This library is intended to work only with server side JS and TS, meaning Node, Bun and Deno, and for the browser you are pointed to a separate js-polars package. That is not a limitation of the binding, it is a consequence of what it is. A NAPI addon is a native library loaded into the process, and a browser has no way to load one. So the moment your requirement becomes a dataframe in a web page, this package is the wrong tool and the alternative is a different project with a WebAssembly or pure JavaScript design. The same boundary applies to edge runtimes and to serverless platforms with restricted native extension support. The second limit is version churn. The engine crates are pinned at 0.55.2 in this build, the JavaScript package is at 0.26.1, and the release cadence is weekly or every few days, so pinning a version is a normal part of using it rather than a sign of distrust.

## The repository shows how the binding is maintained

The tree is arranged like a native Node addon project, and reading it tells you what the project does for you. There is src/ for the TypeScript layer, polars/ for the generated and compiled output, __tests__/ for the test suite, benches/ for benchmarks, @types/ for the ambient type declarations, npm/ for the packaging helper, a build.rs at the root for the Rust side, a Cargo.toml and a rust-toolchain file, and both a tsconfig.json for development and a tsconfig.build.json for the shipped build. The package scripts show the pipeline. The build runs napi build with the platform and release flags and outputs into the polars directory, build:ts compiles the TypeScript with tsc into bin, and cp:bin copies the compiled node files into bin, which is the directory the package actually publishes. The test script is the Node built-in test runner with source maps and coverage enabled, running the test files under __tests__ through tsx. Linting is done with biome for TypeScript and cargo fmt for Rust, and precommit runs lint, type check and tests together. A .nvmrc file pins the Node version used in development.

## Conclusion

Adopt nodejs-polars when a Node or TypeScript service needs real columnar data handling with lazy execution, and when you want the same engine that backs the Python and Rust Polars libraries rather than a JavaScript imitation of it. Do not adopt it for browser code, since the project says it is intended to work only with server side JS and TS and points to a separate js-polars package for the browser. Verify first that your platform has a prebuilt binary or that you can compile from source, which needs a Rust toolchain of 1.86 or newer, and that the Node version you run meets the engines requirement of 20 or newer.

## FAQ

### Can I use nodejs-polars in the browser?

No. The README states that this library is intended to work only with server side JS and TS, in Node, Bun and Deno, and points to the separate js-polars project for the browser. A NAPI addon is a native library and cannot be loaded in a browser.

### Which platforms have prebuilt nodejs-polars binaries?

The napi targets list covers x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu, aarch64-unknown-linux-musl, aarch64-linux-android, x86_64-apple-darwin, aarch64-apple-darwin and x86_64-pc-windows-msvc. Building from source is the alternative and requires a Rust compiler of 1.86 or newer.

### How do I install nodejs-polars?

The README gives yarn add nodejs-polars, npm i -s nodejs-polars, or bun i -D nodejs-polars. The package is published on npm as nodejs-polars, and both ESM import and require styles are supported.

### How stable is the nodejs-polars API?

The package version is 0.26.1, below 1.0, and the README notes that releases happen quite often, weekly or every few days, and suggests updating regularly for bugfixes and features. That is a reason to pin a version rather than track the latest.

## Sources

- [License: MIT](https://github.com/pola-rs/nodejs-polars/blob/main/LICENSE)
- [pola-rs/nodejs-polars on GitHub](https://github.com/pola-rs/nodejs-polars)
- [Project website](https://pola-rs.github.io/nodejs-polars/)
- [README](https://github.com/pola-rs/nodejs-polars/blob/main/README.md)
- [Releases](https://github.com/pola-rs/nodejs-polars/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pola-rs-nodejs-polars
