rioxarray: putting a geospatial layer on top of xarray
geospatial xarray extension powered by rasterio
At a glance
- What is it?
- rioxarray is a rasterio backed extension for xarray that lets labelled arrays carry coordinate reference systems, reprojection and spatial metadata. The current source requires Python 3.13 or newer and an xarray release from 2026, which narrows who can adopt it right now.
- Who is it for?
- rioxarray suits a team already working in xarray with raster data who need CRS handling, reprojection and spatial metadata without leaving the array interface, and who can run Python 3.13 with a current xarray. It does not suit a team pinned to an older Python or an older xarray, and it is not a vector or point geometry library.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A raster backend with a geospatial accessor
rioxarray is described as a geospatial xarray extension powered by rasterio, and the README is more terse still: rasterio xarray extension. It is a library, published on PyPI and on conda-forge, with documentation in two versions, a stable one and a latest one, both hosted under the project Pages site.
The problem it solves is specific. xarray gives you labelled n-dimensional arrays with named dimensions and coordinates, which is a good fit for raster time series. What xarray does not give you is the geospatial metadata that a raster file carries: the coordinate reference system, the spatial resolution, the bounds, the transform, the nodata value, and the ability to reproject onto another grid. rioxarray adds those, and it does it as an accessor on the array rather than as a separate object you have to convert between.
So the data flow stays in one representation. You open or load a raster, the array gets a rio accessor, and from there the spatial operations are methods on the array itself. That is the difference from the more common pattern where a raster becomes a numpy array, then a separate geospatial object, and then back.
The packaging metadata marks the project as a Beta, as OS Independent, as typed, and as a Scientific/Engineering GIS library, and the topics cover GDAL, geospatial, GIS, netcdf, raster, rasterio and xarray, with a hacktoberfest tag that explains the shape of the contributor base.
Three upstream projects show in the credits
The credits section is unusually detailed, and it is worth reading because it explains a lot about the design.
The reproject functionality was adopted from the Open Data Cube's datacube-core project, with the source file named as geo_xarray.py. datacube is licensed under the Apache License, Version 2.0, and that licence is included in the repository as LICENSE_datacube.
Two pieces were adopted from the pydata xarray project. The first is open_rasterio, the backend module, and the second is set_options, from the options module. xarray is licensed under the Apache License, Version 2.0 as well, and that licence is included as LICENSE_xarray.
The RasterioWriter dask write functionality was adopted from dymaxionlabs dask-rasterio, with write.py named as the source file.
The project was originally templated with Cookiecutter, which is a small detail that dates the repository's shape.
Two things follow. First, the licence position is not a single file. The repository root carries LICENSE, LICENSE_datacube and LICENSE_xarray, and the package metadata sets license to Apache-2.0 with license-files covering LICENSE* and AUTHORS.rst, so the notice obligations of the adopted code travel with the package. Second, the lineage explains the feature set. The datacube origin brings the reprojection, the xarray origin brings the backend and options handling, and the dask-rasterio origin brings chunked writing.
The dependency floor is the first thing to check
The current source tree is not a version you can drop into an older environment, and the manifest is explicit about it.
The project version in the manifest is 0.24.0.dev0, and requires-python is >=3.13. The classifiers list Python 3.13, 3.14 and 3.15, so the supported interpreters are the current ones.
The runtime dependencies are four.
dependencies = [
"rasterio>=1.4.3",
# https://github.com/pydata/xarray/issues/11000
"xarray>=2026.2",
"pyproj>=3.7",
"numpy>=2.1",
]Two of those floors are worth a second look. The xarray requirement carries a comment pointing at an upstream issue, which is the kind of marker that tells you the pin exists because of a specific incompatibility rather than a policy. And numpy 2.1 plus a 2026.2 xarray means the environment is recent.
For a scientific Python package, this is not unusual. Raster and geospatial work is a corner of the ecosystem that moves with the GDAL and PROJ releases underneath it, and a package that wraps rasterio is exposed to those. But it does mean the adoption question is really an environment question: if your cluster runs Python 3.11, this is not the release to pick.
The tooling tells you how the project is maintained
The dependency groups and the Makefile describe a well instrumented project, and both are readable without much context.
The groups are doc, test, type, lint and dev, and dev includes the others by reference. The test group carries pytest, pytest-cov, pytest-timeout, dask, netcdf4 and packaging, which tells you that the test suite exercises dask and netCDF paths, not just pure array logic.
test = [
"pytest>=3.6",
"pytest-cov",
"pytest-timeout",
"dask",
"netcdf4",The Makefile has a help target that parses the comments in the file itself, which is why the targets carry a double hash suffix.
test: ## run tests quickly with the default Python
pytest
lint: ## check style with flake8
flake8 rioxarray/ test/
black --check .There is also a pylint target that runs the main linter over the package and then a second invocation with a custom plugin loaded for the test code, enabling only two custom checks, C9999 and C9998. Running a separate lint pass over the tests with the noisy categories disabled is a small piece of process discipline that usually says the test suite is treated as code rather than as scratch.
The repository root backs this up with a .pre-commit-config.yaml, a mypy.ini, a .pylintrc, a .flake8, an .isort.cfg and an .editorconfig, plus a codecov.yml, an appveyor.yml for Windows CI, and a Dockerfile.
The Docker image assembles GDAL and Python together
The Dockerfile is a good summary of what a geospatial Python stack actually requires, because it builds both halves rather than assuming them.
The base is the official GDAL image, pinned by a build argument.
ARG GDAL=ubuntu-full-3.8.5
FROM ghcr.io/osgeo/gdal:${GDAL}
ARG PYTHON_VERSION="3.13"The Python version is not in the base image, so the file adds the deadsnakes apt repository to obtain it, then installs the toolchain around it.
RUN add-apt-repository -y ppa:deadsnakes/ppa
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
g++ \
gdb \
make \
python3-pip \
python${PYTHON_VERSION} \
python${PYTHON_VERSION}-dev \
python${PYTHON_VERSION}-venv \
&& rm -rf /var/lib/apt/lists/*The development headers, a compiler and make are there because rasterio is installed from source rather than from a wheel, which the environment enforces with PIP_NO_BINARY set to rasterio. The final step creates a virtual environment and installs the project in editable mode with the dev group, and the entrypoint is a shell rather than a fixed command, so the container is meant to be used interactively for development.
That last detail is the point of the image. It exists to give contributors a GDAL and Python 3.13 environment that matches the package constraints, not to ship a runtime.
Where rioxarray is the wrong tool
The first case is a team that cannot move to Python 3.13. The requirement is not a preference, it is a hard bound, and the release line is 0.x, so there is no older rioxarray to fall back on that supports a current-but-older Python in the same way. Falling back means an older rioxarray with older xarray and numpy behaviour, and the geospatial edge cases tend to live in exactly the versions that change.
The second case is vector or point data. This is a raster library. Its data model is a regularly gridded array with a CRS, and if your problem is polygons, lines or points, then a different library is the right shape and rioxarray will not help.
The third case is a project that only needs to open a raster and read its values. xarray already ships a rasterio backend, and the README credits the open_rasterio module from xarray as one of the sources this project adopted from. The difference in approach is that rioxarray adds a geospatial accessor with CRS handling, reprojection, spatial indexing style metadata and writing helpers, whereas the plain backend is just a way to load a file into an array.
The honest summary is that rioxarray is worth the dependency weight when your workflow is genuinely geospatial, that is when you reproject, resample, clip by bounds or write results back with a defined CRS. If you only read pixels into a labelled array, the extra layer is overhead, and the datacube and xarray origins explain exactly what you would be taking on.
Editorial conclusion
rioxarray suits a team already working in xarray with raster data who need CRS handling, reprojection and spatial metadata without leaving the array interface, and who can run Python 3.13 with a current xarray. It does not suit a team pinned to an older Python or an older xarray, and it is not a vector or point geometry library. Verify first that the xarray version you need is available, because the manifest pins xarray to 2026.2 and cites an upstream issue as the reason, and check the licence files in the repository root, since the package ships separate licence files for the code adopted from datacube-core and from xarray.
Frequently asked questions
What is rioxarray?
It is a geospatial xarray extension powered by rasterio, adding coordinate reference system handling, reprojection and spatial metadata to xarray arrays. It is published on PyPI and conda-forge, with stable and latest documentation hosted under the project Pages site.
Which Python versions does rioxarray support?
The current source declares requires-python of >=3.13, and the classifiers list Python 3.13, 3.14 and 3.15. The development version in the manifest is 0.24.0.dev0.
What are the runtime dependencies of rioxarray?
Four: rasterio>=1.4.3, xarray>=2026.2, pyproj>=3.7 and numpy>=2.1. The xarray floor carries a comment pointing to an upstream xarray issue.
What licence does rioxarray use, and what is in the LICENSE files?
The package metadata sets the licence to Apache-2.0 with license-files covering LICENSE* and AUTHORS.rst. The repository root carries LICENSE, LICENSE_datacube and LICENSE_xarray, because the reproject code was adopted from datacube-core and parts of the backend and options handling from xarray, both under the Apache License 2.0.
Where can I find the rioxarray documentation?
There is a stable version and a latest version, both under the project Pages site, and the changelog is linked from the project URLs in the package metadata. Bugs and feature requests go to the repository issue tracker, and there are discussion channels on the repository, on Gitter and on GIS StackExchange.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vylor-rioxarray)Was this useful?