Patch Format
Kart patches are JSON files that contain both the changes (diff) and metadata (author, timestamp, message) needed to apply those changes to a repository. Patches are applied using kart apply. Patches can be created from an existing commit using kart create-patch.
Kart’s patch format is currently subject to change. If you’re building something significant relying on patches, best to get in touch to discuss your use case.
Basic Structure
A Kart patch file has two main sections:
{
"kart.patch/v1": {
"authorName": "Jane Developer",
"authorEmail": "jane@example.com",
"authorTime": "2025-10-21T12:34:56Z",
"authorTimeOffset": "+12:00",
"message": "Update feature attributes",
"base": "abc123..."
},
"kart.diff/v1+hexwkb": {
"dataset-name": {
"meta": {},
"feature": []
}
}
}
Patch Metadata (kart.patch/v1)
The kart.patch/v1 section contains commit metadata:
authorName (required): Full name of the patch author
authorEmail (required): Email address of the patch author
authorTime (required): ISO 8601 UTC timestamp when the patch was created
authorTimeOffset (required): Timezone offset in ISO 8601 format (e.g., “+12:00”)
message (required): Commit message describing the changes
base (optional): Git commit hash that this patch is based on. When present, enables updates of existing features without a - key. Also allows patches to omit unchanged fields from feature diffs.
Diff Data (kart.diff/v1+hexwkb)
The kart.diff/v1+hexwkb section contains the actual changes:
{
"kart.diff/v1+hexwkb": {
"my-dataset": {
"meta": {
"title": {
"-": "Old Title",
"+": "New Title"
}
},
"feature": [
{
"++": {
"fid": 1,
"name": "New Feature",
"geom": "0101000000..."
}
},
{
"--": {
"fid": 2
}
},
{
"-": {
"fid": 3,
"name": "Old Name",
"geom": "0101000000..."
},
"+": {
"fid": 3,
"name": "Updated Name",
"geom": "0101000000..."
}
}
]
}
}
}
Feature Changes
Features are specified in the feature array. Each element represents a change:
++for inserts (new features)--for deletes (removed features)-and+for updates (modified features)
Insert a new feature
To insert a new feature, use the ++ key with all required fields:
{
"++": {
"fid": 123,
"name": "New Feature",
"geom": "0101000000...",
"category": "A"
}
}
Delete a feature
To delete a feature, use the -- key with at minimum the primary key field:
{
"--": {
"fid": 123
}
}
Update a feature
To update a feature, include both - (old values) and + (new values):
{
"-": {
"fid": 123,
"name": "Old Name",
"category": "A"
},
"+": {
"fid": 123,
"name": "New Name",
"category": "B"
}
}
Partial Feature Updates
When a patch includes a base commit hash, feature updates can be partial - they don’t need to include all fields in the - and + values. Missing fields are automatically resolved from the base commit.
This is useful for:
Updating only specific attributes without needing to include geometry
Creating smaller, more focused patches
Reducing patch file size
Example of a partial update:
{
"kart.patch/v1": {
"base": "abc123...",
"message": "Update name only",
...
},
"kart.diff/v1+hexwkb": {
"my-dataset": {
"feature": [
{
"-": {
"fid": 123,
"name": "Old Name"
},
"+": {
"fid": 123,
"name": "Updated Name"
}
}
]
}
}
}
In this example, only the fid and name fields are specified in the - and + values. The geom and other fields will be preserved from the feature with fid=123 in the base commit.
Note: For convenience, when a base commit is present, you may omit the - key entirely for updates (specifying only +), and the old values will be resolved from the base commit. However, including both - and + is preferred as it makes the patch self-documenting and easier to review.
Important limitations:
Partial updates only work for existing features (updates, not inserts)
The primary key field is always required
For new feature inserts, all fields must be provided
For deletes, only the primary key is needed
Metadata Changes
Dataset metadata can be changed using the meta object:
{
"meta": {
"title": {
"-": "Old Title",
"+": "New Title"
},
"description": {
"+": "New description"
},
"schema.json": {
"-": {...},
"+": {...}
}
}
}
Geometry Encoding
Geometry fields are encoded as hexadecimal WKB (Well-Known Binary) in the GeoPackage format. The v1+hexwkb in the key name indicates this encoding.
Binary Fields
Binary/blob fields are encoded as hexadecimal strings. A null value for a binary field is represented as JSON null.
Reprojected Patches
Patches can include geometries in a different coordinate reference system (CRS) than the target dataset. This allows you to create patches in a convenient CRS (like EPSG:4326/WGS84) and apply them to datasets in any CRS.
Creating Reprojected Patches
Use the --crs option when creating a patch:
kart create-patch HEAD --crs=EPSG:4326 > my-changes.kartpatch
The patch will include a crs field in the metadata:
{
"kart.patch/v1": {
"base": "abc123...",
"crs": "EPSG:4326",
...
},
"kart.diff/v1+hexwkb": {
...
}
}
Applying Reprojected Patches
When applying a patch with a crs field, Kart automatically transforms geometries from the patch CRS to the dataset’s CRS:
kart apply my-changes.kartpatch
Important limitations for reprojected patches:
A
basecommit is required (for conflict resolution)Feature updates cannot include both
-and+keysUpdates with both old and new values would require comparing the
-geometry with the dataset geometry for conflict detection, but CRS transformations are not reliably reversibleInstead, use only the
+key to replace/update an existing feature’s geometry
Inserts and deletes work normally using
++or--keysPartial updates work - specify only
+with the fields you want to change
Example of a valid reprojected update:
{
"kart.patch/v1": {
"base": "abc123...",
"crs": "EPSG:4326"
},
"kart.diff/v1+hexwkb": {
"my-dataset": {
"feature": [
{
"+": {
"fid": 123,
"geom": "0101000000..."
}
}
]
}
}
}
This updates the geometry (and any other specified fields) of the feature with fid=123, transforming the geometry from EPSG:4326 to the dataset’s CRS.
Creating Patches
To create a patch file from a commit:
kart create-patch HEAD > my-changes.kartpatch
kart create-patch abc123 > my-changes.kartpatch
kart create-patch HEAD~3..HEAD > my-changes.kartpatch
Applying Patches
To apply a patch file:
kart apply my-changes.kartpatch
cat my-changes.kartpatch | kart apply -
Options:
--no-commit: Apply changes to working copy without creating a commit--ref=<branch>: Apply patch to a different branch