Comparison7 min readDecember 15, 2024

KML vs GeoJSON: Which is Better for Web Maps?

Both formats can show a point on a map, but they make wildly different trade-offs. Here's when KML wins, when GeoJSON wins, and why most web maps should use GeoJSON.

If you've inherited a KML file and need to put it on a web map, you have a choice: render it directly (some libraries support KML), or convert it to GeoJSON first. The right answer depends on which library you're using, how much styling matters, and how much you trust the source KML to be standards-conformant.

The fundamental difference

KML (Keyhole Markup Language) is an XML format designed by Keyhole, acquired by Google in 2004, and adopted as an OGC standard in 2008. It carries styling inline — colours, icons, line widths, balloon HTML — alongside geometry. A KML file says "here is a red dashed line that is 3 pixels wide labelled 'Marathon route'".

GeoJSON is a JSON-based format defined by RFC 7946. It carries only geometry and properties — no styling. A GeoJSON file says "here is a LineString with the property name = 'Marathon route'". The styling lives in your map library's code.

This single distinction drives every other trade-off.

Library support

The biggest practical question: does your map library actually render KML?

Google Maps renders KML natively via KmlLayer. It also renders GeoJSON via data.loadGeoJson. For a Google Maps target, both work.

Mapbox GL JS / MapLibre GL do not render KML natively. You must convert KML to GeoJSON first (using togeojson, ogr2ogr, or a server-side converter). Both render GeoJSON natively and well.

Leaflet does not render KML natively. The leaflet-kml plugin adds support, but it's a stale dependency that doesn't handle all KML constructs. GeoJSON is native via L.geoJSON.

OpenLayers renders both natively via dedicated format classes (ol/format/KML and ol/format/GeoJSON). For OpenLayers, either format works directly.

Practical recommendation: Unless you're targeting Google Maps or OpenLayers exclusively, convert KML to GeoJSON before loading. The conversion is fast and lossless for geometry.

File size

GeoJSON is consistently smaller. For the same dataset:

  • Geometry-only: GeoJSON is ~40% smaller than KML.
  • With styling: KML's inline styles add 20–50% to its file size, while GeoJSON does without entirely.

For a 10,000-feature dataset, expect a 3 MB KML to become a 1.5 MB GeoJSON. The savings come from KML's XML overhead — every coordinate pair is wrapped in element tags with namespace prefixes (<gml:pos>53.5 10.0</gml:pos> vs [10.0, 53.5]).

Coordinate order — the bug that won't die

KML uses lon,lat[,alt] — comma-separated, longitude first. GeoJSON uses [lon, lat] — array, longitude first. Both formats agree that longitude comes first, against the human convention of saying "lat/lon".

When converting between them, this rarely causes problems because tools handle it correctly. When hand-editing either format, this is the #1 cause of points appearing in the wrong hemisphere or in the ocean. Always double-check coordinate order when you write either format by hand.

Styling: KML wins for fidelity

This is the area where KML genuinely matters. A KML file produced by Google Earth carries the exact symbology its author intended:

  • Icon style (custom PNG, colour tint, scale)
  • Line style (colour, width, dash pattern)
  • Polygon style (fill, outline, opacity)
  • Label style (font, size, scale)
  • Balloon HTML for popups

If you convert that KML to GeoJSON and feed it to Mapbox, all of this is lost. You'll keep the geometry and name/description properties; you'll lose every visual property.

For maps where the source's exact symbology matters — a Google Earth tour, a marked-up reconnaissance map, a Realtor's annotated property map — KML preserves intent. For web maps where you control the styling anyway, the styling loss is not a loss at all.

Reading KML in JavaScript

If you must render KML in a Mapbox or Leaflet map without converting it server-side, the best library is [togeojson](https://github.com/placemark/togeojson) (originally by Mapbox, maintained by Placemark/Felt). It parses KML in the browser and returns standard GeoJSON:

import { kml } from '@tmcw/togeojson';

fetch('routes.kml')
  .then(r => r.text())
  .then(text => new DOMParser().parseFromString(text, 'text/xml'))
  .then(doc => kml(doc))
  .then(geojson => map.addSource('routes', { type: 'geojson', data: geojson }));

The library is ~30 KB minified and handles the common KML constructs cleanly. Styles are dropped, but feature properties (name, description, gx:tracks) are preserved.

Reading GeoJSON in JavaScript

It is JSON.parse and then pass to your map library. No third-party parser needed.

fetch('routes.geojson')
  .then(r => r.json())
  .then(geojson => map.addSource('routes', { type: 'geojson', data: geojson }));

That's the entire story. Native browser JSON parsing is fast, and every map library accepts a parsed GeoJSON object as input.

The KMZ wrinkle

KML's sibling KMZ is a ZIP archive containing a KML plus referenced resources (icons, photo overlays). Browsers can't unpack KMZ natively, so you need a JavaScript ZIP library (fflate or jszip) to extract the inner KML before parsing.

This extra step makes KMZ awkward for web use. For Google Earth distribution, KMZ is great; for web maps, extract and convert to GeoJSON server-side.

The 2025 recommendation

For web maps, use GeoJSON. Convert KML to GeoJSON during your build process or in a one-time conversion step. Apply styling in your map library's code, where it's easier to maintain, version, and theme.

Keep KML in the workflow only when:

  • The target is Google Earth or Google My Maps.
  • The source styling is the point of the data and you can't recreate it.
  • A client explicitly demands KML deliverables.

Our online KML to GeoJSON converter handles the conversion in seconds with no install required. For batch work, the command line:

ogr2ogr -f GeoJSON output.geojson input.kml

Is all you need. Add -lco RFC7946=YES for strict conformance.

Related Converters

Format References