GeoJSON (RFC 7946) Explained
GeoJSON is the dominant JSON-based format for encoding geographic data on the web. RFC 7946 (IETF, August 2016) standardized the format, replacing the 2008 community specification. Object types: Geometry (Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection), Feature (geometry + properties), FeatureCollection. Coordinates are [longitude, latitude] order — important difference from some other formats. RFC 7946 mandates WGS 84 (EPSG:4326) and removed the optional CRS member from the 2008 spec. Polygon orientation: exterior rings counter-clockwise (right-hand rule), interior rings clockwise. Bounding box (bbox) optional member. MIME type: application/geo+json. Used by Leaflet, MapLibre, Mapbox GL JS, OpenLayers, all major web-mapping libraries. Variants: GeoJSON-LD, TopoJSON (Bostock), GeoJSON-Sequence (RFC 8142), FlatGeobuf (binary).
By Steve K.. Published . Last updated .
This article closes the recommended trio of Data Standards & Specifications supports with the dominant data format for web mapping. Companion to /learn/iso-19111-srs-explained (the CRS framework) and /learn/wgs84-explained (the mandatory CRS for GeoJSON).
What GeoJSON is
GeoJSON is a JSON-based format for encoding geographic data: points, lines, polygons, and collections of them with associated attributes. Because it's JSON, it's readable by any JSON-capable tool — browsers, APIs, databases, scripts.
GeoJSON has become the lingua franca of web-mapping data exchange. When a web map needs to fetch data from a server, GeoJSON is overwhelmingly the default format.
History
Sean Gillies and the 2008 spec
GeoJSON was created by Sean Gillies and other Python/web-GIS developers around 2008. The 2008 specification was a community-driven document hosted at geojson.org. Adoption was rapid as web mapping took off in the late 2000s.
RFC 7946 (August 2016)
In 2016, the IETF formalized GeoJSON as RFC 7946 (authors: Howard Butler, Martin Daly, Allan Doyle, Sean Gillies, Stefan Hagen, Tim Schaub). The IETF standardization addressed several issues with the 2008 spec:
- CRS member removed: the 2008 spec allowed an
optional
crsmember for non-WGS-84 CRSs; RFC 7946 removed it, mandating WGS 84. - Antimeridian handling: explicit rules for polygons crossing 180° longitude.
- Polygon orientation: right-hand rule formalized.
- MIME type registration: application/geo+json.
- General cleanup: clarified edge cases.
Modern GeoJSON refers to RFC 7946. The 2008 spec is largely deprecated but still encountered in legacy systems.
The object types
Geometry types
Three primary geometry types and three multi- variants:
- Point: a single position.
- LineString: an array of two or more positions, encoding a connected line.
- Polygon: an array of LinearRings (closed LineStrings). First ring is the exterior; subsequent rings are holes.
- MultiPoint: multiple points in one geometry.
- MultiLineString: multiple lines.
- MultiPolygon: multiple polygons.
- GeometryCollection: heterogeneous collection of any geometry types.
Feature
A geometry plus arbitrary key-value properties:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.9857, 40.7484]
},
"properties": {
"name": "Empire State Building",
"height_m": 443,
"year_completed": 1931
}
}
Optional id member (string or number) for
unique-feature identification.
FeatureCollection
An array of features:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-73.9857, 40.7484]},
"properties": {"name": "Empire State Building"}
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-73.9871, 40.7587]},
"properties": {"name": "Rockefeller Center"}
}
]
}
The most common top-level container.
Coordinate convention
GeoJSON uses [longitude, latitude] order — important to remember.
{
"type": "Point",
"coordinates": [-73.9857, 40.7484]
}
That's the Empire State Building at 40.7484°N,
73.9857°W: encoded as [-73.9857, 40.7484] —
longitude first, then latitude.
Optional third element is altitude/elevation:
{
"type": "Point",
"coordinates": [-73.9857, 40.7484, 381]
}
Optional fourth element is application-specific (typically time or measurement). Most tools ignore elements beyond the first three.
Coordinate order is consistent across all geometry types — LineString positions, Polygon ring positions, etc., all use [longitude, latitude].
The order confusion
Other formats use different conventions:
- WKT (Well-Known Text): some implementations use longitude-first; the OGC spec doesn't enforce.
- WKT 2 (ISO 19162): axis order specified explicitly in the CRS definition (latitude-first for geographic CRSs).
- APIs: many use latitude-first in URLs
(
?lat=40&lon=-74). - Mapping libraries (Leaflet): latitude-first in API but accept GeoJSON's longitude-first natively.
The order mismatches are a frequent bug source. Verify coordinate order when copying coordinates between systems.
CRS: WGS 84 only
RFC 7946 mandates WGS 84 (EPSG:4326):
"All GeoJSON coordinates SHALL refer to a unique
location, identified using longitude and latitude,
in the World Geodetic System 1984 (WGS 84) reference
ellipsoid."
The optional crs member from the 2008 spec was
removed in RFC 7946. Modern GeoJSON files
should not contain a crs member.
If a crs member exists in a file (legacy 2008-
style GeoJSON), RFC 7946-compliant readers may
ignore it (assume WGS 84) or reject the file.
Why mandate WGS 84?
The RFC's rationale: interoperability. With
mandated WGS 84, GeoJSON consumers know without
ambiguity how to interpret coordinates. The 2008
flexibility caused tooling fragmentation — some
tools supported the crs member, others didn't;
data exchange across systems was error-prone.
For non-WGS-84 data
RFC 7946 suggests either:
- Convert to WGS 84 before encoding (standard approach).
- Use a different format (GeoPackage, Shapefile, WKT) that natively supports arbitrary CRSs.
GDAL's ogr2ogr can convert any source format
to GeoJSON with reprojection:
ogr2ogr -f GeoJSON -t_srs EPSG:4326 output.geojson input.shp
Polygon orientation (right-hand rule)
RFC 7946 specifies the right-hand rule for polygon ring orientation:
- Exterior ring: counter-clockwise (CCW) when viewed from above.
- Interior rings (holes): clockwise (CW).
The convention helps renderers determine which is the exterior vs interior rings without ambiguity.
{
"type": "Polygon",
"coordinates": [
// Exterior ring (CCW)
[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]],
// Interior ring (hole, CW)
[[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]]
]
}
Many implementations don't enforce orientation strictly. Reading non-compliant files often works (many renderers tolerate either direction); writing standards-compliant files is good practice.
Antimeridian crossing
Polygons that geographically span the antimeridian (180° longitude) require special handling per RFC 7946:
- Split into two parts at the antimeridian.
- Each part is in the same hemisphere.
- Encoded as separate polygons (or as a MultiPolygon).
Example: Fiji geographically spans the antimeridian. A naive single-polygon encoding might list longitudes like [179, -179, -178, ..., 178, 179] — which most renderers would draw as a thin line across the world, not the actual Fijian archipelago.
RFC 7946-compliant: split into one polygon at longitudes [177, 180, ...] (the western Fijian side) and another at longitudes [-180, -179, ...] (the eastern Fijian side).
Pre-RFC GeoJSON was ambiguous about antimeridian crossings; modern compliant data must handle them properly.
The bounding box (bbox)
Optional member describing the geometric extent:
{
"type": "FeatureCollection",
"bbox": [-74.1, 40.6, -73.9, 40.8],
"features": [...]
}
Format: [westLon, southLat, eastLon, northLat]
(2D) or [westLon, southLat, minElev, eastLon, northLat, maxElev] (3D).
The bbox member can appear on FeatureCollection,
Feature, and Geometry objects. It accelerates
spatial filtering (a client can quickly check if a
feature's bbox intersects a viewport without
parsing the full geometry).
MIME type and file extensions
- MIME type:
application/geo+json(registered via RFC 7946). - File extensions:
.geojson(canonical) or.json. - HTTP Content-Type:
application/geo+jsonfor GeoJSON-specific responses;application/jsonis also acceptable.
Encoding examples
A point with attributes
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.9857, 40.7484]
},
"properties": {
"name": "Empire State Building",
"type": "skyscraper",
"year_completed": 1931
}
}
A line representing a route
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-73.9857, 40.7484],
[-73.9871, 40.7587],
[-73.9819, 40.7681]
]
},
"properties": {
"name": "Manhattan walking route"
}
}
A polygon with a hole
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[[-74.01, 40.71], [-73.97, 40.71], [-73.97, 40.74],
[-74.01, 40.74], [-74.01, 40.71]],
[[-74.00, 40.72], [-73.98, 40.72], [-73.98, 40.73],
[-74.00, 40.73], [-74.00, 40.72]]
]
},
"properties": {
"name": "Central Manhattan with cutout"
}
}
A FeatureCollection
{
"type": "FeatureCollection",
"features": [
{"type": "Feature", "geometry": {...}, "properties": {...}},
{"type": "Feature", "geometry": {...}, "properties": {...}}
]
}
Library support
GeoJSON is supported by essentially every modern geospatial library:
Web mapping
- Leaflet:
L.geoJSON(data)displays features. - MapLibre GL JS / Mapbox GL JS: GeoJSON source type in style spec.
- OpenLayers:
ol.format.GeoJSON().
Python
- GeoPandas:
gpd.read_file('data.geojson'). - Fiona / pyogrio: vector I/O.
- GDAL/OGR: GeoJSON driver.
Databases
- PostGIS:
ST_AsGeoJSON(geom)converts to GeoJSON; PostGIS reads GeoJSON via OGR. - MongoDB: native GeoJSON support for spatial-index types.
- Elasticsearch: geo_shape index type supports GeoJSON.
- CouchDB / Couchbase: native JSON queries treat GeoJSON naturally.
Command-line
- ogr2ogr: convert between GeoJSON and any other format.
- jq: general JSON processing works on GeoJSON.
- GitHub: renders .geojson files as interactive maps automatically.
Variants
TopoJSON
TopoJSON (Mike Bostock, 2012) is a GeoJSON extension that encodes topology — shared boundaries between adjacent features are stored once and referenced.
Use case: country borders. In GeoJSON, the US-Canada border appears twice (once in the US polygon, once in Canada). In TopoJSON, the shared arc is stored once with both polygons referencing it.
Result: TopoJSON files are typically ~80% smaller than equivalent GeoJSON when adjacent features share boundaries.
Supported by D3 (Bostock's library) and some other tools; less widely supported than GeoJSON.
GeoJSON-Sequence (RFC 8142)
A line-delimited variant: each line is a separate GeoJSON object. Used for streaming, log-style data, or very large datasets that shouldn't be loaded entirely into memory.
{"type":"Feature",...}
{"type":"Feature",...}
{"type":"Feature",...}
Each line is a complete GeoJSON object (typically Feature). Files use record-separator characters (0x1E) before each record per RFC 8142, or plain newlines for the simpler NDJSON variant.
Supported by GDAL, GeoPandas (with
engine='pyogrio'), and modern streaming tools.
GeoJSON-LD
GeoJSON-LD serializes GeoJSON with JSON-LD context for linked-data semantics. Allows RDF-style references and queryable knowledge graphs.
Less widely supported than plain GeoJSON; used in semantic-web and Linked Open Data contexts.
FlatGeobuf
FlatGeobuf (Björn Harrtell) is a binary geospatial format with GeoJSON-compatible semantics but vastly smaller and faster to read.
- Cap'n Proto / FlatBuffers-based encoding.
- Spatial index built into the file.
- HTTP range-request support.
- Cross-language support.
Not strictly a GeoJSON variant but increasingly used where GeoJSON would be used, when binary efficiency matters.
Performance considerations
Text-based, not binary
GeoJSON is text-based JSON — larger than binary formats:
- Shapefile: typically 2-5× smaller than equivalent GeoJSON.
- GeoPackage: 3-10× smaller.
- FlatGeobuf: 5-15× smaller.
For very large datasets, binary formats are preferred. GeoJSON is excellent for web exchange where human readability and simple JSON parsing matter more than file size.
Streaming
Large GeoJSON files load slowly because the top-level FeatureCollection requires holding the whole array in memory. Solutions:
- GeoJSON-Sequence for streaming.
- NDJSON-style: line-delimited features.
- Pagination: server-side API returns chunks.
Compression
GeoJSON compresses well — gzip typically reduces size 70-80%. HTTP responses should be served with gzip/Brotli compression for production use.
Common misconceptions
“GeoJSON uses latitude-longitude order.” No — it uses [longitude, latitude] order. This is a critical detail and frequent bug source.
“GeoJSON supports any CRS.” No,
not since RFC 7946 (2016). Modern GeoJSON
mandates WGS 84. The 2008 spec allowed alternative
CRSs via a crs member; RFC 7946 removed this.
“GeoJSON polygons close themselves
automatically.” No — the first and
last positions of each ring must be identical.
A ring like [[0,0], [1,0], [1,1], [0,1]] is
invalid; it should be [[0,0], [1,0], [1,1], [0,1], [0,0]].
“GeoJSON files can hold any size data.” In principle, but JSON parsing becomes slow for very large files (10+ MB). Streaming variants (GeoJSON-Sequence) or binary formats (FlatGeobuf) scale better.
“GeoJSON is just JSON.” It's JSON with specific structural rules. Not every valid JSON is valid GeoJSON; the type, coordinates, and feature schema must conform to RFC 7946.
“Polygon orientation doesn't matter.” Specified by RFC 7946: exterior CCW, interior CW. Many tools tolerate either; standards-compliant data should follow the rule.
“GeoJSON-LD is widespread.” Niche. Used in semantic-web contexts; not standard for typical web mapping.
“TopoJSON has replaced GeoJSON.” No — TopoJSON is used for specific cases (D3 visualizations with shared boundaries); GeoJSON remains the dominant general format.
“Antimeridian polygons just work.” Need explicit splitting per RFC 7946. Antimeridian-naïve polygons render incorrectly in most viewers.
“GeoJSON supports topology.” Not natively — each feature has its own complete geometry, even when adjacent features share boundaries. TopoJSON adds topology support.
“The id member is required.”
Optional. Many features omit it. When present,
RFC 7946 specifies it should be a string or
number unique within the FeatureCollection.
“Properties have a defined schema.”
They don't. The properties object can
contain any JSON values. There's no schema
mechanism in GeoJSON itself. JSON Schema or
OGC API - Features can layer schema on top of
GeoJSON.
“3D coordinates work.” Yes — the optional third element is altitude/elevation. But many libraries treat GeoJSON as 2D and discard altitude on read. Verify library support before relying on 3D.
“GeoJSON is GIS-software-friendly.” Yes. All major GIS tools (QGIS, ArcGIS, GDAL, PostGIS) read/write GeoJSON. The format is versatile across GIS and web contexts.
“You can mix CRSs in one file.” Per RFC 7946, no — all coordinates must be WGS 84. The 2008 spec allowed mixing, but modern compliant GeoJSON does not.
“GeoJSON is dying.” Actively used. The format is the default for web- mapping data exchange. Newer binary formats (FlatGeobuf, Cloud-Optimized GeoTIFF for raster) complement GeoJSON for specific use cases but don't replace its general-purpose role.
“GitHub's GeoJSON rendering is arbitrary.” GitHub renders .geojson files as interactive Leaflet-based maps automatically — a powerful default that makes GitHub a convenient hosting platform for small GeoJSON datasets.
“GeoJSON files self-document.”
Partially. The structure is self-describing;
attribute meanings are not. A "population": 12345 property doesn't indicate units, year,
source, or definition. Companion documentation
(README, data dictionary) is needed for true
self-documentation.
“Cloud-Optimized GeoJSON is a thing.” Emerging concept: line-delimited GeoJSON with HTTP range requests for partial reads. Not yet a formal standard; some tooling supports the pattern.
Related
- WGS 84 Explained— The mandatory CRS for GeoJSON per RFC 7946
- ISO 19111 Spatial Reference Systems— The conceptual framework for CRSs
- Geographic Coordinate System— The geographic CRS GeoJSON uses by default per RFC 7946
- The International Date Line— The antimeridian RFC 7946 handles specifically
- Methodology— How content is sourced and verified
Frequently asked questions
What is GeoJSON?
GeoJSON is a JSON-based format for encoding geographic data. Originally created in 2008 by Sean Gillies and other Python/web-GIS developers; formally standardized as RFC 7946 by the IETF in August 2016. The format defines three primary object types: Geometry (Point, LineString, Polygon, plus Multi-* variants and GeometryCollection), Feature (a geometry plus arbitrary key-value properties), and FeatureCollection (an array of features). GeoJSON has become the dominant web-mapping data format — used by Leaflet, MapLibre, Mapbox GL JS, OpenLayers, GitHub (which renders .geojson files as interactive maps), and most modern geospatial web services. The MIME type is application/geo+json.
What's the coordinate convention?
GeoJSON uses **[longitude, latitude]** order — important to remember as some other formats (notably WKT and many APIs) use latitude-first order. RFC 7946 explicitly states: 'A position is an array of numbers. There MUST be two or more elements. The first two elements are longitude and latitude, or easting and northing.' Optional third element is altitude/elevation. Optional fourth element is application-specific. The Empire State Building at 40.7484° N, 73.9857° W is encoded as [-73.9857, 40.7484] — longitude first, then latitude. The convention is consistent across all GeoJSON geometry types. Mismatched coordinate order (writing [lat, lon] in a GeoJSON file) is a frequent bug source; tools that auto-detect the issue help, but careful coding practice is the only reliable fix.
What CRS does GeoJSON use?
RFC 7946 mandates WGS 84 (EPSG:4326) longitude/latitude. The optional 'crs' member from the 2008 community spec was explicitly removed in RFC 7946 — modern GeoJSON is always WGS 84 unless sender and receiver have explicit out-of-band agreement otherwise. This is a significant change from the 2008 spec, which let producers specify alternative CRSs via a 'crs' member. The RFC 7946 rationale: GeoJSON is for web data exchange, where consistent WGS 84 lat/lon is essential for interoperability; embedded CRS handling caused tooling fragmentation. For non-WGS 84 data, the IETF recommends converting to WGS 84 before encoding as GeoJSON or using a different format (GeoPackage, Shapefile, etc.).
How does GeoJSON handle the antimeridian and polygons?
RFC 7946 introduced specific rules for both. Antimeridian: polygons crossing the antimeridian (180° meridian) must be split into two parts — one on each side. A polygon like 'all of Fiji' that geographically spans the antimeridian is encoded as two separate polygons (or a MultiPolygon). This avoids ambiguity in rendering — RFC 7946-compliant clients correctly handle Fiji rather than drawing a stretched polygon across the world. Polygon ring orientation: RFC 7946 specifies the **right-hand rule** — exterior rings are counter-clockwise (CCW) when viewed from above; interior rings (holes) are clockwise (CW). Many implementations don't enforce this strictly; consequences are mostly aesthetic (some renderers display polygons backwards or treat interior rings as exterior).
What are the GeoJSON variants?
Several. **TopoJSON** (Mike Bostock, 2012): extends GeoJSON to encode topology — shared boundaries between adjacent features are stored once and referenced. Dramatically smaller than equivalent GeoJSON when adjacent features share boundaries (e.g., country borders). **GeoJSON-LD**: GeoJSON serialized with JSON-LD context for linked-data semantics. Used in semantic-web and Linked Open Data contexts. **GeoJSON-Sequence** (RFC 8142, IETF 2017): line-delimited GeoJSON for streaming, log-style data, and large datasets. Each line is a separate GeoJSON object. **Newline-delimited GeoJSON (NDJSON-style)**: similar pattern, slightly different conventions. **FlatGeobuf**: binary geospatial format with GeoJSON-compatible features but vastly smaller and faster to read. Designed by Björn Harrtell. Each format trades GeoJSON's simplicity for specific advantages (size, streaming, binary speed).
Sources
- IETF — RFC 7946 — The GeoJSON Format (Butler et al., August 2016) · https://www.rfc-editor.org/rfc/rfc7946 · Accessed .
- GeoJSON.org — GeoJSON.org — community-driven information site · https://geojson.org/ · Accessed .
- GDAL — GDAL GeoJSON driver — reference implementation · https://gdal.org/drivers/vector/geojson.html · Accessed .
- IETF — RFC 8142 — GeoJSON Text Sequences · https://www.rfc-editor.org/rfc/rfc8142 · Accessed .
Cite this article
APA format:
Steve K. (2026). GeoJSON (RFC 7946) Explained. Coordinately. https://coordinately.org/learn/geojson-rfc-7946-explained
BibTeX:
@misc{coordinately_geojsonrfc7946_2026,
author = {K., Steve},
title = {GeoJSON (RFC 7946) Explained},
year = {2026},
publisher = {Coordinately},
url = {https://coordinately.org/learn/geojson-rfc-7946-explained},
note = {Accessed: 2026-06-05}
}