Kart and the problem of versioning a GeoPackage without breaking it
Distributed version-control for geospatial and tabular data
At a glance
- What is it?
- Kart is a distributed version control system for geospatial and tabular data, built on a GeoPackage working copy that you edit in QGIS while the changes are tracked underneath. It fits a team whose data changes need to be reviewed and merged, and it does not support schema changes yet, which is the sharpest limit in the documentation.
- Who is it for?
- Kart fits a GIS team that needs history, review and branching for the same spatial data, and that already works in GeoPackage and QGIS. It is the wrong tool if you need schema migration, because the documentation states that schema changes should be detected but are not supported yet and will error, and it is the wrong tool for data that is not tabular and spatial, since the working copy model is built around a single file.
- 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 17 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 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The working copy is a GeoPackage you edit in QGIS
Kart is described as distributed version-control for datasets, and the way it works is the interesting part: you do not version a text diff of a table, you version a database.
The quick start starts by exporting a GeoPackage from Koordinates with any combination of vector layers and tables, then creating a repository and importing it:
$ kart init myproject --import GPKG:kx-foo-layer.gpkg
$ cd myprojectThat repository directory is the place to run all the other commands in, and the import also creates a working copy as `myproject/myproject.gpkg` to edit. So the shape is: a repository holds the history, and inside it sits a plain GeoPackage file that your desktop GIS can open.
The editing model is the part that determines whether the tool works for you. Editing the working copy in QGIS or a similar tool will track changes in the internal `kart` tables, and additions, edits and deletes of features are supported, as is changing feature primary keys. The readme is explicit about the negative case: schema changes should be detected, but aren't supported yet and will error. It also tells you to use F5 to refresh your QGIS map after changing the underlying working copy data using `kart`, because the two views of the same data are not automatically synchronised.
That last point is the practical workflow constraint. You are running a desktop GIS against a file that a version control system is tracking, and the readme treats the refresh as a manual step. That is a normal consequence of tracking a database rather than a text file, and it is the price of the design.
The command set is git, with the index removed
The command list is the most convincing part of the documentation, because it is a git command set with one deliberate difference.
From inside the `myproject/` folder, `kart` commands should work if run from there, and the readme says to check `--help` for options, with the most important ones supported. In some cases options are passed straight through to an underlying git command.
What is listed: `kart diff` diffs the working copy against the repository, with the parenthetical note that there is no index. `kart commit -m {message}` commits outstanding changes from the working copy. `kart log` reviews the commit history. `kart branch` and `kart checkout -b` handle branch management. `kart fetch` fetches upstream changes. `kart status` shows the working copy state. `kart merge` merges and supports `--ff`/`--no-ff`/`--ff-only` from one merge source. `kart switch` switches to existing or new branches. `kart reset` and `kart restore` discard changes in the working copy. There is `kart tag`, `kart remote`, `kart push` and `kart pull`, and `kart clone` initialises a new repository from a remote URL.
The missing index is the structural point. Git's index is a staging area, and for a database-backed working copy there is nothing sensible to stage, because a change is a change to a set of rows rather than a set of hunks. The readme even adds that simple remotes can just be another local directory, which is the sort of detail that matters when you are experimenting with a branch on the same disk.
So the learning curve for a team that knows git is close to zero, and the mental model for the code review process is familiar. What is new is that the unit of change is a query, not a hunk.
One binary, four platform installers, and a Python package behind them
The installation section is complete across the three major platforms, and it is a distribution story rather than a build story.
On Windows you download the .msi installer from the release page, and there is a note that if Windows Defender SmartScreen says it prevented an unrecognized app from starting, you need to click Run anyway. On macOS you download the .pkg installer, or use Homebrew with `brew install koordinates/kart/kart`. On Linux there are two paths: the .deb package for Debian and Ubuntu based distributions, installed via `dpkg -i kart_*.deb`, and the .rpm for RPM based distributions, installed via `rpm -i kart-*.rpm`.
The versioning convention in those commands is worth noting. The package name carries the version, so `kart_*.deb` and `kart-*.rpm` mean a specific build, and a versioned package name is a deliberate choice for something that installs system wide.
The repository itself is a hybrid, and the top level listing shows it. There is a `kart/` directory for the Python package, a `libkart/` directory for the C++ core, a `CMakeLists.txt` with `CMakePresets.json` and a `cmake/` directory, a `vcpkg-vendor/` directory, and a `kart.spec` for RPM packaging. The `setup.py` reads the version from a `VERSION` file inside the `kart/` package rather than hard coding it, and it declares two console scripts that both point at the same entry point, `kart = kart.cli:entrypoint` and `sno = kart.cli:entrypoint`.
That second name is a small curiosity rather than a feature. The `sno` alias is the same command under a shorter name, and a repository that offers two names for the same entry point is usually doing it for muscle memory or a rename in progress.
There is also a `cli_helper/` directory, which suggests the CLI has some generated or shared component, and the `platforms/` directory plus `scripts/` suggest platform specific packaging work. The documentation is hosted on Read the Docs and the project site is kartproject.org, with the tutorials and reference at docs.kartproject.org.
GPLv2 with a linking exception, which is deliberate and specific
The licence section is worth reading closely, because the exception is not the usual one.
Kart is GPLv2 with a linking exception. The text says that in addition to the permissions in the GNU General Public License version 2, the authors give you unlimited permission to link the compiled version of this file into combinations with other programs and to distribute those combinations without any restriction coming from the use of this file. The GPL restrictions do apply in other respects, and the readme gives two examples: they cover modification of the file, and distribution when not linked into a combined executable.
So the shape is familiar from other tools in this position. The code itself stays copyleft, so if you modify Kart you owe the obligations of GPLv2 on your modification. But linking it into a larger program, including a proprietary one, does not infect the whole product. That matters for a lot of real deployments, because a plain GPL tool cannot be dropped into a commercial product without a legal argument, while a linking exception can.
The exception is per file, which is worth noting. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, and the readme points to the `COPYING` file for the full terms.
The repository listing also shows a `CITATION` file and an `AUTHORS.md`, and the top level carries `CHANGELOG.md`, `HOWTO-RELEASE.md`, `CONTRIBUTING.md` and `CLAUDE.md`, alongside `pytest.ini`, `mypy.ini` and a `.pre-commit-config.yaml`.
For a tool whose whole purpose is collaborative data work, a copyleft licence with a linking exception is a reasonable position: it keeps the improvements in the commons while leaving the door open for a company to embed it in a product.
The compatibility and upgrade notes live in the release, not the readme
The readme is upfront about where the details are, and the pointer is worth following before an upgrade.
The installing section opens with Upgrading to v0.17.1 and sends the reader to the v0.17.1 release notes for changes, upgrading, and compatibility notes. The readme itself does not describe the upgrade path, the migration steps or what breaks.
That is a deliberate division. The readme covers the shape of the tool and the install, and the release notes carry the things that change. The release history supports that division: v0.16.1 on 2025-01-24, v0.17.0 on 2025-11-16 and v0.17.1 on 2026-06-11, with a ten month gap before the minor bump and a seven month gap before the patch. The version numbers use a date-like scheme, which is a common approach for a tool whose compatibility story is tied to the underlying libraries and formats rather than to an API surface.
The top level listing also shows `vcpkg-vendor/`, a `CMakePresets.json` and a `cmake/` directory, which together with the `libkart/` C++ core suggests that the C++ side pins and vendors its native dependencies. That is a plausible reason for the care around version compatibility, and it is also a plausible reason an upgrade can need attention.
The last push to the master branch was on 2026-10-08, so work continues on the branch after the v0.17.1 release from June. For a team that pins to a release, the practical habit is to read the release notes before bumping, and to test against a copy of a real repository rather than a toy one, because the failure modes in a version controlled database show up in the merge and diff paths rather than in the single file editing.
Where Kart is the wrong tool, and what you would use instead
There are three situations where Kart does not fit, and the first is the one the documentation itself flags.
The first is schema evolution. The readme says schema changes should be detected but aren't supported yet and will error. A dataset whose column types or attribute definitions change over time is a normal thing in geospatial work, because a new sensor or a new administrative boundary set often arrives with a different structure. For those teams, Kart is a versioning tool for the rows but not for the structure, and that is a limit that a data manager will hit in the first quarter.
The second is data that is not a table. The working copy is a GeoPackage file, and the tracking is described in terms of features, primary keys and the internal `kart` tables. Rasters, imagery, point clouds and models do not live in a GeoPackage in a way this workflow handles, so a team with a mixed asset repository needs something else for the non-tabular part.
The third is a team that does not need version control. If a dataset is written once by one team and published, or if the existing process already has a review and change history in another system, Kart is infrastructure for a problem you do not have, and it asks the team to change how they edit, in QGIS, with a manual refresh step and a commit instead of a save.
The alternative worth naming is a plain spatial database with its own change tracking, which handles schema evolution with a migration and gives the team a single interface for both structure and rows, at the cost of no branching, no diff review and no distributed collaboration. The other is to keep files in object storage with a catalogue, which handles arbitrary assets but gives up the row level history that Kart is built around.
The real alternative, though, is doing the version control at the file level with a tool that understands binary formats, which is what people do when they treat a GeoPackage as an opaque file. That gives history and branching immediately and loses the ability to review what changed inside the table, which is the thing Kart is actually for. So the decision is whether reviewing row level changes matters to you more than schema freedom.
Editorial conclusion
Kart fits a GIS team that needs history, review and branching for the same spatial data, and that already works in GeoPackage and QGIS. It is the wrong tool if you need schema migration, because the documentation states that schema changes should be detected but are not supported yet and will error, and it is the wrong tool for data that is not tabular and spatial, since the working copy model is built around a single file. Before adopting, verify three things: whether your dataset survives a round trip through GeoPackage, whether your review process fits the commit and branch model Kart exposes, and how the v0.17.1 changes affect your existing repositories, since the readme sends upgraders to the release notes for changes, upgrading and compatibility. The licence is GPLv2 with a linking exception, the current release is v0.17.1 from 2026-06-11, and the last push was on 2026-10-08.
Frequently asked questions
What is Kart and what problem does it solve?
Kart is a distributed version-control system for datasets, aimed at geospatial and tabular data. You import a GeoPackage into a repository, edit the working copy in QGIS or a similar tool, and the changes are tracked so they can be committed, reviewed, branched and merged like code.
How do I install Kart?
On Windows download the .msi installer from the release page, on macOS the .pkg or `brew install koordinates/kart/kart`, and on Linux the .deb installed with `dpkg -i kart_*.deb` or the .rpm installed with `rpm -i kart-*.rpm`. Source development is covered in the Contributing Notes.
What can Kart track in a GeoPackage?
Additions, edits and deletes of features are supported, as is changing feature primary keys, and changes are tracked in the internal `kart` tables. Schema changes should be detected but are not supported yet and will error, and the readme asks you to refresh the QGIS map with F5 after changing the working copy data with `kart`.
Is Kart the same as git?
It uses git underneath and exposes a similar command set, with `kart diff`, `kart commit -m`, `kart log`, `kart branch`, `kart fetch`, `kart status`, `kart merge` with `--ff`/`--no-ff`/`--ff-only`, `kart switch`, `kart reset`, `kart restore`, `kart tag`, `kart remote`, `kart push`, `kart pull` and `kart clone`. The difference is that `kart diff` diffs the working copy against the repository, with no index.
What licence is Kart released under?
GPLv2 with a linking exception. The authors give unlimited permission to link the compiled version into combinations with other programs and distribute those combinations without restriction, while the GPL restrictions still cover modification of the file and distribution when not linked into a combined executable.
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/koordinates-kart)Was this useful?