The basics
What is a GeoJSON file?
A GeoJSON file stores geographic features as JSON: each feature has a shape on the earth (a point, a line or an area) and a set of properties describing it. Because it's plain JSON, any programming language can read it, and web map libraries can draw it with a line or two of code.
It's the everyday format of web mapping. Open data portals offer downloads in it, APIs return it, GIS software such as QGIS reads and writes it, and GitHub draws .geojson files as interactive maps. A file of shop locations, a delivery zone, a cycling route or the borders of a country can all be GeoJSON.
Three things GeoJSON is not:
- Not a map. It has no colours, icons or background map. The application that loads it decides how it looks.
- Not projected. Coordinates are always longitude and latitude on WGS 84, the GPS datum. Data in metres from a national grid must be converted first.
- Not efficient for huge datasets. Every coordinate is written out as text. For millions of features, vector tiles, GeoPackage or GeoParquet are usually a better fit.
Anatomy
What's inside a GeoJSON file
A GeoJSON file is ordinary JSON with an agreed structure. Its building block is the Feature: a geometry (where) plus properties (what). Here is a small but complete file with a point and an area, part by part.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "cafe-1",
"geometry": {
"type": "Point",
"coordinates": [4.895168, 52.370216]
},
"properties": {
"name": "Sample Café",
"seats": 28
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[5.13, 52.08], [5.14, 52.08],
[5.14, 52.087], [5.13, 52.087],
[5.13, 52.08]
]]
},
"properties": { "name": "Sample park" }
}
]
}- 1
"type": "FeatureCollection"The collection
Every GeoJSON object has a
type. A FeatureCollection is the usual top level: a list of features. A single Feature or a bare geometry is also a valid file. - 2
"features": [ … ]The features
An array of Feature objects, in any order.
- 3
"type": "Feature"A feature
One thing on the map: a café, a road, a country. It always has a
geometryandproperties, either of which may benull. - 4
"id": "cafe-1"An identifier
Optional, a string or a number. Map libraries use it to update or highlight a feature.
- 5
"geometry": { "type": "Point", … }The geometry
Where the feature is. One of seven geometry types, each with its own nesting of
coordinates. - 6
[4.895168, 52.370216]A position: longitude first
Longitude (east-west), then latitude (north-south), in decimal degrees. This is central Amsterdam. Swapped, it would be a point in the Indian Ocean.
- 7
"properties": { … }The properties
Anything you like about the feature, as a JSON object: names, numbers, booleans, lists. GeoJSON doesn't define any property names.
- 8
"type": "Polygon"A polygon
An area. Its
coordinatesare a list of rings, each a list of positions, which is why there are three levels of brackets. - 9
[5.13, 52.08] … [5.13, 52.08]A closed ring
A ring's last position repeats its first, and a ring needs at least four positions. This outer ring runs counterclockwise: east, north, west, back south.
The classic mistake
The [longitude, latitude] trap
GeoJSON writes positions as [longitude, latitude], like x, y on a graph. People, and many apps, say latitude first. Swap them and nothing errors: the point just lands somewhere else.
| Written as | Ends up in |
|---|---|
[4.895168, 52.370216] | Amsterdam, correct |
[52.370216, 4.895168] | The Indian Ocean, east of Somalia |
[-74.005974, 40.712776] | New York, correct |
[40.712776, -74.005974] | Antarctica |
[0, 0] | The Gulf of Guinea, where empty or failed coordinates pile up |
| Longitude first | Latitude first |
|---|---|
| GeoJSON, KML, Shapefile, WKT as usually written | Google Maps coordinates and links |
MapLibre and Mapbox (LngLat) | Leaflet's own functions (L.marker, setView) |
OpenLayers (fromLonLat) | The GEO property in ICS files |
Turf.js, PostGIS ST_MakePoint | Most people, when reading coordinates aloud |
A quick check
Latitude is never above 90 or below −90, so a second number outside that range means the order is swapped. Inside that range a swap still parses, so if points land in the sea or on the wrong continent, check the order first.
Under the hood
Geometry types and the rest of the structure
| Type | coordinates holds | Example use |
|---|---|---|
Point | One position | A shop, a photo location |
LineString | Two or more positions | A route, a river |
Polygon | A list of closed rings: the outside first, then any holes | A park with a pond, a building |
MultiPoint | A list of positions | All the stops on one bus line |
MultiLineString | A list of lines | A route with a ferry crossing |
MultiPolygon | A list of polygons | A country with islands |
GeometryCollection | geometries: a list of other geometries | Mixed shapes; often better as separate features |
- A position is two numbers, or three with a height in metres above the WGS 84 ellipsoid. RFC 7946 says not to use more than three.
bboxis an optional bounding box on any object:[west, south, east, north].geometry: nullis allowed, for a feature whose location is unknown.- Extra members, such as a
titlenext tofeatures, are allowed and called foreign members. Readers ignore them, and some tools drop them when they save. - There is no
crsmember in RFC 7946. The 2008 version allowed other coordinate systems; the standard removed that because it caused errors. Older files may still have one. - Styling isn't part of the format. A convention called simplestyle uses properties like
marker-color,strokeandfill, which some viewers read and others ignore.
The rules
WGS 84, winding order and coordinate precision
Only WGS 84. Coordinates are longitude and latitude in decimal degrees on the World Geodetic System 1984, the same system GPS uses (the OGC calls it CRS84). Data from national grids, such as British National Grid or the Dutch RD New, or in web Mercator metres (EPSG:3857), has to be reprojected before it's valid GeoJSON. Any coordinate beyond ±180 is the giveaway.
The right-hand rule. RFC 7946 says a polygon's outer ring runs counterclockwise and its holes run clockwise. Because the 2008 version said nothing about this, parsers should not reject polygons that get it wrong, and many files do. Watch out for two tools that use the opposite convention: D3 expects clockwise outer rings for polygons smaller than a hemisphere and draws an RFC 7946 polygon as "the whole world except this shape", and Shapefile stores outer rings clockwise.
| Decimals | Example | About |
|---|---|---|
| 2 | 52.37 | 1 km: a neighbourhood |
| 3 | 52.370 | 110 m: a street |
| 4 | 52.3702 | 11 m: a building |
| 5 | 52.37022 | 1.1 m: a doorway |
| 6 | 52.370216 | 11 cm: more than GPS can tell you |
| 15 | 52.370216000000012 | Nothing real; only file size |
RFC 7946 notes that 6 decimal places is about 10 centimetres, and that going from 6 to 15 places can nearly double the size of a file full of detailed polygons. Trim coordinates when you export: GDAL's COORDINATE_PRECISION option or mapshaper's precision setting do it in one step.
Edge cases
Shapes that cross the antimeridian
Longitude jumps from 180 to −180 at the antimeridian, in the Pacific. A line from [170, 45] to [-170, 45] is 20 degrees long across the Pacific, but most software draws it 340 degrees the other way, across the whole world. RFC 7946 says to cut such geometry in two, so that no part crosses the line:
{
"type": "MultiLineString",
"coordinates": [
[[170.0, 45.0], [180.0, 45.0]],
[[-180.0, 45.0], [-170.0, 45.0]]
]
}A polygon becomes a MultiPolygon in the same way. A bbox that crosses the antimeridian has a west value greater than its east value, such as [177, -20, -178, -16] around Fiji; code that assumes west is always the smaller number gets this wrong. sample-antimeridian.geojson below has a zone and a route cut this way.
Comparison
GeoJSON vs KML vs Shapefile vs TopoJSON
| GeoJSON | KML | Shapefile | TopoJSON | |
|---|---|---|---|---|
| Syntax | JSON, one file | XML; KMZ is a zipped KML | Binary, at least three files (.shp, .shx, .dbf), plus .prj for the coordinate system | JSON, one file |
| Coordinates | WGS 84 longitude, latitude | WGS 84 longitude, latitude | Any system, described in the .prj file | Usually WGS 84, stored as small integers plus a transform |
| Styling | None (simplestyle by convention) | Built in: icons, colours, popups | None | None |
| Shared borders | Stored once per polygon | Stored once per polygon | Stored once per polygon | Stored once and shared, as arcs |
| Attributes | Any JSON values | Free text and typed data | Field names up to 10 characters, no nulls, dates without times, 255 fields at most | Any JSON values |
| Size limits | None in the format | None in the format | 2 GB per component file | None in the format |
| Origin | Community spec 2008; RFC 7946 (2016) | Google Earth; OGC standard | Esri, 1998 specification | Mike Bostock; extension of GeoJSON |
| Typical use | Web maps and APIs | Google Earth, sharing places | Desktop GIS, government data | Compact boundaries for web maps |
Converting between them is routine. GDAL's ogr2ogr converts between GeoJSON, KML and Shapefile and can read TopoJSON; mapshaper also writes TopoJSON. GitHub notes that converting a large GeoJSON file to TopoJSON can reduce its size by up to 80%, because borders shared by neighbouring areas are stored once.
How to
How to view, load and convert a GeoJSON file
- See it on a map in a browser: drop it on geojson.io, which also lets you draw and edit features.
- On GitHub: commit it with a
.geojsonextension and GitHub shows it as a map, drawn with Leaflet on OpenStreetMap. Files over 10 MB aren't rendered,.jsonfiles only if theirtypeisFeatureCollectionorGeometryCollection, and only longitude and latitude data shows in the right place. - In desktop GIS: drag it into QGIS, or use Layer, Add Layer, Add Vector Layer.
- In a text editor: it's JSON, so any editor opens it, and a JSON formatter makes it readable.
- Convert it:
ogr2ogr -f GeoJSON -lco RFC7946=YES out.geojson in.shpturns a Shapefile into GeoJSON. TheRFC7946=YESoption matters: without it GDAL writes the 2008 version, without reprojecting to WGS 84.ogr2ogr -f KML out.kml in.geojsongoes the other way.
Web map libraries load GeoJSON from a link. Leaflet needs the data fetched first; MapLibre and OpenLayers can take the address directly (map setup trimmed):
// Leaflet: fetch the file, then hand the data to L.geoJSON.
// (Leaflet's own functions, like setView, take [latitude, longitude].)
const leafletMap = L.map("map").setView([52.09, 5.12], 6);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "© OpenStreetMap contributors",
}).addTo(leafletMap);
fetch("https://example.com/places.geojson")
.then((response) => response.json())
.then((data) => L.geoJSON(data).addTo(leafletMap));
// MapLibre GL JS: a geojson source loads the address itself.
maplibreMap.on("load", () => {
maplibreMap.addSource("places", {
type: "geojson",
data: "https://example.com/places.geojson",
});
maplibreMap.addLayer({ id: "places", type: "circle", source: "places" });
});
// OpenLayers: a vector source with the GeoJSON format.
const layer = new VectorLayer({
source: new VectorSource({
url: "https://example.com/places.geojson",
format: new GeoJSON(),
}),
});If the map page and the GeoJSON file are on different domains, the browser only lets the page read the file if the file's server allows it with CORS headers. A 'blocked by CORS policy' error in the console means the request reached the file but the browser withheld the response.
Security
Privacy and safety
- Locations are personal data. A file of customers, members or GPS tracks shows where people live and go. Six decimal places identify a front door; round or aggregate before publishing.
- Properties travel with the shapes. Exports from GIS software often carry every attribute column, including internal IDs, owner names or notes. Check the properties before sharing a file.
- Popups can run code. Map libraries often insert property values into popups as HTML. A property containing
<img src=x onerror=…>from an untrusted file then runs in your page. Insert untrusted values as text, or escape them. - Size and complexity. A file with millions of vertices can freeze a browser tab. Simplify geometry and limit the size of files your application accepts.
Free downloads
Sample GeoJSON files to download
Free sample GeoJSON files for testing map libraries, GIS imports, parsers and upload limits. Each one is valid RFC 7946 GeoJSON, checked with Python's geojson and shapely libraries and our own checks for coordinate ranges, precision, ring closure and winding order. Places and properties are made up; coordinates are rough city centres or invented shapes.
Loading…What's inside sample-places.geojson
JSON has no comments, so this file explains itself through its structure. Open it in a text editor and look for these parts.
The FeatureCollection
typeand afeaturesarray with eight Point features, the most common shape of a GeoJSON file.A foreign member
_aboutis not part of GeoJSON. The standard allows extra members like it, and readers ignore them, which makes it a way to add a note to a file that can't have comments.The bbox
[-74.005974, -34.603722, 151.20929, 52.370216]: west, south, east and north edges around all eight places, from New York to Sydney.Coordinates in all four quarters of the globe
Longitude first, six decimal places. New York and Buenos Aires have negative longitudes (west), Buenos Aires, Sydney and Nairobi negative latitudes (south).
Properties of every JSON type
Strings, numbers (
rating,seats), booleans (wifi), an array (tags), a nested object (hours) and anull. Formats with flat tables, such as Shapefile, can't hold the array or the nested object as they are.String ids
Each feature has an
idsuch as"sample-1". Numbers are also allowed, as in the other samples.marker-color
A simplestyle property. Viewers that support the convention colour each marker; others show it as an ordinary property.
All sample GeoJSON files
Eight sample places around the world
sample-places.geojson · 4.8 KB (4,903 bytes)
A FeatureCollection of made-up cafés and shops at rough city-centre coordinates on six continents, with a bbox, string ids, properties of every JSON type and simplestyle colours.
- Testing a map library or viewer
- Catching swapped latitude and longitude
Every geometry type
sample-geometries.geojson · 3.9 KB (3,992 bytes)
One feature per geometry type: a Point with a height, a LineString, a Polygon with a hole, MultiPoint, MultiLineString, MultiPolygon and GeometryCollection, plus a feature with
geometry: null.- Checking a parser supports every type
- Testing hole and winding handling
Shapes cut at the antimeridian
sample-antimeridian.geojson · 1.5 KB (1,574 bytes)
A rectangle from 175°E to 175°W stored as a two-part MultiPolygon, and a route split into a two-part MultiLineString, with bounding boxes whose west value is greater than their east.
- Testing rendering near 180° longitude
- Checking bbox code handles a crossing box
Minimal GeoJSON: one Feature
sample-minimal.geojson · 207 bytes
A single Feature with a Point and a name, with no FeatureCollection around it. Valid, but some tools only accept collections.
- Parser smoke tests
- Checking tools accept a lone Feature
100 KB GeoJSON file
sample-100kb.geojson · 100 KB (102,400 bytes)
555 generated points in a box over Europe, one feature per line, padded to exactly 102,400 bytes.
- Upload and size-limit tests
- Rendering many markers at once
Ways to test with them
- Coordinate order: load
sample-places.geojson. The markers should sit in Amsterdam, Utrecht, London, New York, Buenos Aires, Nairobi, Tokyo and Sydney. Markers in the ocean or Antarctica mean something swapped latitude and longitude. - Holes and winding: in
sample-geometries.geojson, the park polygon should show a hole where the pond is. A filled-in pond, or a shape that covers the whole map, points to winding-order trouble. - The antimeridian:
sample-antimeridian.geojsonshould show a small zone and a short route near Fiji, not bands stretching across the whole world. - Upload limits:
sample-100kb.geojsonis exactly 102,400 bytes, so you can test a size limit right at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a GeoJSON file? Give it a link.
Drop a GeoJSON file on 99helpers and it gets its own web address. Browsers show it as text, and a map page on the same 99helpers site can load it with Leaflet, MapLibre or OpenLayers.
Questions
GeoJSON files, frequently asked
What is a GeoJSON file?
A JSON file that describes geographic features (points, lines and areas) with properties for each one. It's the standard format for data on web maps.
How do I open a GeoJSON file?
To see it on a map, drop it on geojson.io or open it in QGIS. To read the data, open it in any text editor; it's JSON.
Is it latitude, longitude or longitude, latitude?
Longitude first: [longitude, latitude], like x and y. It's the most common GeoJSON mistake, and it puts points in the wrong place without any error.
What's the difference between GeoJSON and JSON?
GeoJSON is JSON with an agreed structure for geographic data: type, features, geometry, coordinates and properties. Every GeoJSON file is valid JSON.
Can GeoJSON use a different coordinate system?
Not under RFC 7946: coordinates are always WGS 84 longitude and latitude. The older 2008 version allowed a crs member, which the standard removed. Reproject other data before saving it as GeoJSON.
How do I convert a Shapefile or KML to GeoJSON?
Use GDAL: ogr2ogr -f GeoJSON -lco RFC7946=YES out.geojson input.shp. In QGIS, right-click the layer and choose Export, Save Features As.
How many decimal places should coordinates have?
Six is plenty: about 10 cm, finer than GPS. Five (about 1 m) is enough for most maps, and extra digits only make the file bigger.
Why does my polygon cover the whole world?
Usually its rings run in the direction the drawing tool doesn't expect. RFC 7946 uses counterclockwise outer rings, D3 expects clockwise. Rewind the polygon for the tool you use.
Related formats
Other file types explained
Keep going
Related
Sources
- RFC 7946: The GeoJSON Format
- IANA media type registration: application/geo+json
- GitHub Docs: Mapping GeoJSON/TopoJSON files on GitHub
- GDAL: GeoJSON driver
- Esri: Geoprocessing considerations for shapefile output
- D3: d3-geo
Last reviewed 27 October 2026.