xarray-ts

[!WARNING] This is a work in progress, and I’ve had Claude (Opus 4.8) scaffold it for me. Because of that, it might look good (IDK), but it is certainly not complete or and has not been drive-tested in any meaningful sense of the word. Claims about functionality in this README should be considered probable at best, and aspirational at worst. Use at your own caution (whilst this warning is still up. I’ll get rid of it once I’m confident in the codebase).

A minimal, read-only xarray metadata layer for zarr v3 / icechunk in the browser.

xarray-ts reinterprets the zarr stores produced by serialising an xarray Dataset (e.g. to an icechunk store) into an xarray-shaped object — dimensions, coordinates, data variables, attributes — that view layers can introspect, while streaming actual slices on demand through zarrita.

It is not a reimplementation of xarray. It does exactly one job: turn a zarr group into the metadata you need to drive a viewer, and make selecting a slice a one-liner.

icechunk-js / zarrita FetchStore   →   xarray-ts   →   your view layer
   (bytes, chunks, AsyncReadable)      (this lib)       (rendering)

Install

npm install xarray-ts zarrita
# optional, for icechunk repos:
npm install icechunk-js

Quickstart

import { openDataset, fromIcechunk } from "xarray-ts";

const store = await fromIcechunk("https://bucket.s3.amazonaws.com/repo");
const ds = await openDataset(store);

ds.dims; // { time: 365, y: 720, x: 1440 }
ds.attrs; // group-level attributes
ds.coords.time.dates(); // Date[] — CF time axis decoded for you
ds.coords.x.values; // number[] — eagerly loaded

// Stream just the slice you need; coordinates are metadata, data is lazy.
const frame = await ds.get("temperature").isel({ time: 0 }).load();
frame.data; // a (y, x) TypedArray, fetched via zarrita
frame.shape; // [720, 1440]

Plain zarr v3 over HTTP works too:

import { openDataset, fromHttp } from "xarray-ts";
const ds = await openDataset(fromHttp("https://example.com/data.zarr"));

Any zarrita Readable store is accepted, so openDataset(store) works with FetchStore, icechunk-js, an in-memory Map, or your own store.

What it interprets

It deliberately does not apply scale_factor / add_offset / _FillValue masking, and does not implement computation, alignment, or writing.

Selection

DataArray and Dataset both support positional (isel) and label-based (sel) selection. Both return new lazy views — nothing is fetched until .load() / .values().

const da = ds.get("temperature");

da.isel({ time: 0 }); // integer index drops the dim
da.isel({ x: { start: 100, stop: 200 } }); // half-open slice keeps the dim
da.sel({ time: new Date("2020-06-01") }); // label lookup via the coordinate
da.sel({ time: someDate }, { method: "nearest" });
da.sel({ y: { start: -40, stop: 40 } }); // inclusive label range

await da.isel({ time: 0 }).load(); // -> { data, shape, stride } (zarrita Chunk)
await da.isel({ time: 0 }).values(); // -> just the TypedArray (or a scalar)

ds.isel({ time: 0 }); // selects across every variable -> new Dataset

Enumerating variables

To list a group’s variables without per-array round-trips, openDataset uses consolidated metadata when present (a single fetch). xarray and icechunk write this by default. If a store has no consolidated metadata and cannot list its own children, pass the names explicitly:

await openDataset(store, { variables: ["time", "x", "y", "temperature"] });

Nested groups / DataTree

This package opens a single group at a path (openDataset(store, { path })) and returns a flat Dataset. Recursive, nested-group / DataTree traversal is intentionally out of scope here and owned by a separate library, which plugs into this one through a clearly defined seam:

import { datasetFromGroup, type GroupNode } from "xarray-ts";

API

Export Description
openDataset(store, opts?) Open a zarr v3 store as a Dataset.
openZarr Alias of openDataset.
fromIcechunk(url, opts?) Open an icechunk repo as a store (needs icechunk-js).
fromHttp(url, opts?) Open a plain zarr v3 store over HTTP (FetchStore).
Dataset dims, coords, data_vars, variables, attrs, get, dropVars, pickVars, renameVars, renameDims, setCoords, resetCoords, isel, sel.
DataArray dims, shape, coords, attrs, dtype, rename, isel, sel, load, values.
Coord Eager dimension coordinate: values, dims, attrs, isTime, decoded, calendar, dates(), cftimes().
LazyCoord Lazy auxiliary / N-d coordinate: dims, attrs, isTime, load(), values(). Narrow with isLazyCoord.
datasetFromGroup, childArrayNames, GroupNode The nested-group seam.
openDatatree Stub (throws NotImplementedError).

Development

npm test            # run the hermetic in-memory unit tests
npm run test:watch  # watch mode
npm run typecheck   # tsc --noEmit (strict)
npm run build       # emit ESM + .d.ts to dist/
npm run check:package # assert the public package surface stays self-contained

# opt-in integration test against a real icechunk repo:
ICECHUNK_TEST_URL=https://… npm test

License

Apache 2.0, see LICENSE.

xarray-ts is a TypeScript reimplementation of parts of the xarray data model. It uses Apache-2.0 for license congruence with pydata/xarray, which is also Apache-2.0.

This is an independent project and is not affiliated with or endorsed by the xarray maintainers.