What is GeoJSON?

Learn about GeoJSON - the open standard format for encoding geographic data structures using JSON.

What is GeoJSON?

GeoJSON is an open standard format for encoding geographic data structures using JavaScript Object Notation (JSON). Defined in RFC 7946, it has become the most widely used format for exchanging geospatial data on the web.

GeoJSON represents geographic features (places, routes, boundaries) along with their non-spatial properties (names, categories, measurements). If you've used Google Maps, OpenStreetMap, or any web-based map, there's a good chance GeoJSON was involved behind the scenes.

GeoJSON Geometry Types

GeoJSON supports seven geometry types:

TypeDescriptionExample Use
PointA single positionStore locations, markers, addresses
LineStringA sequence of connected pointsRoads, rivers, hiking trails
PolygonA closed shape with an exterior ringBuilding footprints, city boundaries, lakes
MultiPointMultiple pointsChain store locations
MultiLineStringMultiple line stringsA highway system with disconnected segments
MultiPolygonMultiple polygonsA country with islands (e.g., Indonesia)
GeometryCollectionA mix of geometry typesComplex features combining different shapes

GeoJSON Structure

Every GeoJSON object is one of three types:

  • Geometry — a shape (Point, Polygon, etc.)
  • Feature — a geometry with properties (name, population, etc.)
  • FeatureCollection — a list of Features

Here's a simple example of a GeoJSON Feature:

GeoJSON{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-73.9857, 40.7484]
  },
  "properties": {
    "name": "Empire State Building",
    "city": "New York"
  }
}

And a FeatureCollection containing multiple features:

GeoJSON{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-73.9857, 40.7484]
      },
      "properties": { "name": "Empire State Building" }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-73.9876, 40.7661],
          [-73.9814, 40.7661],
          [-73.9814, 40.7623],
          [-73.9876, 40.7623],
          [-73.9876, 40.7661]
        ]]
      },
      "properties": { "name": "Central Park South Edge" }
    }
  ]
}

Key Rules to Remember

  1. Coordinates are [longitude, latitude] — not [lat, lng]. This is the most common mistake developers make with GeoJSON.
  2. Coordinate reference system is WGS 84 — the same system used by GPS. No other CRS is allowed per RFC 7946.
  3. Polygon rings must be closed — the first and last coordinate must be identical.
  4. Exterior rings are counterclockwise, holes are clockwise — this is the right-hand rule defined in RFC 7946.
  5. Properties can be any valid JSON — strings, numbers, booleans, arrays, nested objects, or null.

Why Developers Prefer GeoJSON

  • Human-readable — it's just JSON, easy to inspect and debug
  • Native to the web — works directly with JavaScript, no parsing libraries needed
  • Universal tool support — Leaflet, Mapbox, Google Maps, D3.js, QGIS, PostGIS, and virtually every mapping tool supports it
  • API-friendly — easy to send/receive over REST and GraphQL APIs
  • Version-control friendly — text-based diffs work well with Git

History of GeoJSON

GeoJSON originated in 2008 as a community-driven specification authored by Howard Butler, Martin Daly, Allan Doyle, Sean Gillies, Tim Schaub, and Christopher Schmidt. The original spec lived at geojson.org and gained rapid adoption because it solved a real problem: developers needed a simple, web-native way to exchange geographic data without the complexity of OGC standards like GML (Geography Markup Language).

Prior to GeoJSON, web developers exchanging spatial data relied on XML-based formats like KML (introduced by Keyhole in 2004, later adopted by Google) or GML, which required verbose markup and dedicated XML parsers. Shapefiles, the dominant desktop GIS format since 1998, required binary parsing and multiple companion files (.shp, .shx, .dbf, .prj). GeoJSON eliminated these barriers by building on JSON, which every web browser and server-side language could already parse natively.

By 2015, GeoJSON had become the de facto standard for web mapping, but the original specification left several ambiguities. The IETF (Internet Engineering Task Force) formed a working group to formalize it. In August 2016, they published RFC 7946, which introduced three major changes. First, WGS 84 (EPSG:4326) became the only permitted coordinate reference system, eliminating the optional crs member from the 2008 spec. Second, the right-hand rule for polygon winding order was mandated: exterior rings counterclockwise, holes clockwise. Third, geometries crossing the antimeridian (180 degrees longitude) should be split rather than wrapped.

The RFC 7946 authors also clarified coordinate precision recommendations. While the spec does not mandate a maximum number of decimal places, it notes that 6 decimal places (~0.11 meters at the equator) is sufficient for most applications. The 2008 spec was silent on this topic, leading to files with 15+ decimal places that inflated file sizes without adding meaningful accuracy.

The 2008-to-RFC-7946 transition was mostly backward-compatible. The biggest breaking change affected datasets using non-WGS-84 projections. Tools like GDAL (version 2.3+), PostGIS (via ST_AsGeoJSON()), and QGIS updated their GeoJSON writers to comply with RFC 7946 by default. Today, virtually all new GeoJSON data follows the RFC 7946 rules. Libraries like Turf.js (first released in 2014) and MapShaper further accelerated adoption by providing JavaScript-native tools for creating, transforming, and analyzing GeoJSON without server-side dependencies.

Who Uses GeoJSON?

GeoJSON adoption spans nearly every corner of the geospatial ecosystem. GitHub renders any file with a .geojson extension as an interactive map directly in the repository viewer, making it trivial to preview geographic data alongside code. As of 2024, GitHub hosts over 2 million .geojson files across public repositories.

All major web mapping libraries consume GeoJSON natively. Mapbox GL JS and MapLibre GL JS accept GeoJSON as a source type that is automatically tiled on the client for WebGL rendering. Leaflet parses GeoJSON into SVG or Canvas layers with a single function call. Google Maps provides map.data.addGeoJson() for direct ingestion. OpenLayers includes a dedicated GeoJSON format class.

On the data side, the OpenStreetMap Overpass API can return query results as GeoJSON. The US Census Bureau distributes TIGER/Line boundary data (states, counties, census tracts, ZIP code tabulation areas) in GeoJSON through their TIGERweb service. Natural Earth, a public-domain dataset used widely for world maps, publishes GeoJSON downloads at 1:10m, 1:50m, and 1:110m scales.

Cloud platforms support GeoJSON extensively. AWS Location Service, Google Cloud BigQuery GIS, and Microsoft Azure Maps all accept GeoJSON input. PostGIS converts geometries to GeoJSON with ST_AsGeoJSON(), and Elasticsearch stores and queries geospatial data using GeoJSON geometry objects.

Mobile development frameworks also rely on GeoJSON. React Native Maps, Flutter's google_maps_flutter package, and Apple's MapKit all parse GeoJSON for overlay rendering. Mapbox Navigation SDK uses GeoJSON LineStrings to represent route geometries. Server-side frameworks like Django (via GeoDjango), Rails (via RGeo), and Express.js (via Turf.js) serialize query results as GeoJSON for API responses.

In data journalism, organizations including the New York Times, Washington Post, and BBC use GeoJSON to power interactive maps embedded in stories. D3.js, the visualization library behind many of these maps, treats GeoJSON as its primary geographic data format through the d3-geo module. Observable notebooks render GeoJSON inline, making it a common format for collaborative geographic analysis and prototyping.

GeoJSON vs Other Formats

Choosing a geospatial format depends on your use case. Here is how GeoJSON compares to the most common alternatives:

FormatTypeFile SizeWeb SupportBest For
GeoJSONText (JSON)LargeNativeWeb APIs, small-to-medium datasets, interoperability
ShapefileBinary + textMediumRequires parsingDesktop GIS, legacy systems, regulatory submissions
GeoPackageSQLite databaseCompactRequires parsingOffline mobile apps, multi-layer datasets, mixed vector/raster
KML/KMZXMLMediumGoogle EarthGoogle Earth visualization, styled presentations
WKT/WKBText/BinaryCompactNoneDatabase storage (PostGIS), geometry-only exchange
FlatGeobufBinaryCompactStreamingLarge datasets, HTTP range requests, fast spatial queries
GeoParquetColumnar binaryVery compactLimitedAnalytics, data lakes, cloud-native processing at scale

Shapefile remains dominant in government and traditional GIS workflows, but it carries significant limitations: a 2 GB file size cap, 10-character attribute name limit, no support for null values, and the requirement for at least three companion files (.shp, .shx, .dbf). GeoPackage addresses all of these shortcomings in a single SQLite file.

For web delivery of large datasets (50 MB and above), FlatGeobuf and PMTiles (vector tiles) outperform GeoJSON because they support partial reads via HTTP range requests. The client fetches only the features visible in the current viewport rather than downloading the entire dataset.

KML was designed for Google Earth and includes built-in styling (colors, icons, camera angles), but its XML verbosity makes it 2-3x larger than equivalent GeoJSON. KMZ (compressed KML) reduces size but requires decompression before parsing. KML also lacks a standardized properties system; metadata is embedded in <ExtendedData> elements with inconsistent schemas across producers.

WKT (Well-Known Text) and WKB (Well-Known Binary) are geometry-only encodings used extensively in databases. PostGIS stores geometries internally as WKB and converts to WKT or GeoJSON on output. WKT is compact for single geometries but lacks any mechanism for properties, feature identity, or bounding boxes. It is a geometry serialization format, not a data exchange format.

As a rule of thumb: use GeoJSON when building web APIs or exchanging data between systems, use GeoPackage when you need a portable multi-layer container with full SQL support, and use vector tiles or FlatGeobuf when delivering large datasets to browsers.

Limitations of GeoJSON

GeoJSON is not a universal solution. Understanding its limitations helps you pick the right format for each project:

  • No built-in styling — GeoJSON contains geometry and properties only. There is no standard way to encode colors, line widths, icons, or fill patterns. The MapBox Simple Style Specification (simplestyle-spec) is a convention some tools honor, but it is not part of RFC 7946. Styling is always the responsibility of the rendering application.
  • No topology — each geometry is independent. Two adjacent polygons store their shared boundary twice, and there is no guarantee the coordinates align exactly. This leads to slivers and gaps. TopoJSON solves this by encoding shared arcs.
  • No streaming support — a standard GeoJSON file must be parsed as a complete JSON document. For streaming use cases, line-delimited GeoJSON (newline-delimited JSON where each line is a Feature) exists as a convention but is not part of the RFC.
  • Poor performance above 50 MB — JSON parsing in the browser is single-threaded and memory-intensive. A 50 MB GeoJSON file can consume 200-400 MB of heap memory once parsed into JavaScript objects. At this scale, binary formats like FlatGeobuf or vector tiles are substantially more efficient.
  • No CRS flexibility — RFC 7946 mandates WGS 84 (EPSG:4326). If your workflow requires projected coordinates (UTM, State Plane, national grids), you must reproject to WGS 84 for GeoJSON and then reproject back for analysis. GeoPackage and Shapefile both support arbitrary coordinate reference systems.
  • No temporal dimension — GeoJSON has no native way to encode time-series data or temporal validity ranges. You can add timestamps in properties, but there is no standard schema for it.
  • No random access — to read the last feature in a 10,000-feature FeatureCollection, a parser must scan through all preceding features. Binary formats like FlatGeobuf include spatial indexes that allow reading individual features by location in O(log n) time. GeoJSON always requires O(n) parsing.
  • Coordinate precision bloat — JSON encodes numbers as text. The coordinate -73.985700000000 takes 18 bytes in GeoJSON versus 8 bytes as an IEEE 754 double in a binary format. With millions of coordinate pairs, this overhead is significant. Use our Coordinate Precision Tool to trim excess decimals.

Despite these limitations, GeoJSON remains the best choice for web APIs serving datasets under 10 MB, for data interchange between heterogeneous systems, and for any workflow where human readability matters. Validate your GeoJSON with our validator to catch structural issues before they reach production.

When Not to Use GeoJSON

GeoJSON isn't always the best choice:

  • Very large datasets — GeoJSON files can get large quickly. Consider vector tiles, FlatGeobuf, or GeoParquet for datasets over 10–20 MB.
  • Topology matters — if you need shared boundaries between polygons, TopoJSON preserves topology and reduces file size.
  • 3D or complex CRS — GeoJSON supports an optional altitude coordinate but is limited to WGS 84. For complex coordinate systems, GeoPackage or Shapefile may be more appropriate.
  • Raster data — GeoJSON is for vector data only. Use GeoTIFF or Cloud Optimized GeoTIFF for raster/imagery.

Try It Yourself

Use our GeoJSON Viewer to visualize GeoJSON on a map, or the GeoJSON Validator to check your data against the RFC 7946 specification.