Skip to content

Repository files navigation

GitHub package.json version (branch) npm bundle size contributions welcome ViewCount License: MIT NPM Downloads Coverage

GPX.JS

Based on GPXParser.js, which has been unmaintained, this updated library is intended to bring modern JavaScript features to GPX parsing, including extensions in tracks and fully featured typescript support.

I'm also open to any improvements or suggestions with the library, so feel free to leave an issue (Contributing).

Warning

Upgrading from 1.1.0 or earlier? 1.2.0 includes four breaking changes (link fields are now arrays, stringifyGPX/applyToTrack/applyToRoute return [result, error] tuples instead of throwing, and metadata.time is now a Date). See Migrating to 1.2.0 before upgrading.

GPX Schema

The schema for GPX, a commonly used gps tracking format, can be found here: GPX 1.1.

See Documentation for more details on how GPX data is represented by the library.

Documentation

The docs/ folder holds longer-form guides that don't belong inline here, including:

For the shape of the parsed output, see Types below and types.ts.

Usage

This library does include support for non-browser execution.

Right now, to use this in Node.js without a browser or in something like React Native, use xmldom-qsa instead.

See instructions below on how to use a custom DOM parser.

Install using NPM

npm i @we-gold/gpxjs

Then, import the parseGPX method:

import { parseGPX } from "@we-gold/gpxjs"

const [parsedFile, error] = parseGPX(myXMLGPXString)

// Or use a try catch to verify
if (error) throw error

const geojson = parsedFile.toGeoJSON()

Include JavaScript File

In an HTML document:

<script src="./src/gpxjs.js"></script>

<script type="module">
	import { parseGPX } from "@we-gold/gpxjs"

	const [parsedFile, error] = parseGPX(myXMLGPXString)

	// Or use a try catch to verify
	if (error) throw error

	const geojson = parsedFile.toGeoJSON()
</script>

Fetching a GPX File

While this feature isn't included, it is fairly simple to fetch a GPX file and format it as a string.

import { parseGPX } from "@we-gold/gpxjs"

fetch("./somefile.gpx")
	.then((response) => {
		if (!response.ok) {
			throw new Error("Failed to fetch the file")
		}
		return response.text()
	})
	.then((data) => {
		const [parsedFile, error] = parseGPX(data)

		// Or use a try catch to verify
		if (error) throw error

		const geojson = parsedFile.toGeoJSON()
	})

parseGPX has an additional optional argument removeEmptyFields which removes empty or null values from the output. It is true by default. This argument is also available in parseGPXWithCustomParser.

Use the Parsed GPX

const totalDistance = gpx.tracks[0].distance.total

const extensions = gpx.tracks[1].extensions

Use parsedGPX functions

/// export to GPX
const geoJSON = parsedGPX.toGeoJSON()


/// stringify GPX function
import { stringifyGPX } from "@we-gold/gpxjs"

const [xmlAsString, stringifyError] = stringifyGPX(parsedGPX);
if (stringifyError) throw stringifyError;

// math functions
import { calculateDistance, calculateDuration, calculateElevation, calculateSlopes } from "@we-gold/gpxjs"

/// recalculates the distance, duration, elevation, and slopes of the track
const [dist, distError] = parsedGPX.applyToTrack(0, calculateDistance);
if (distError) throw distError;
const [dur] = parsedGPX.applyToTrack(0, calculateDuration);
const [elev] = parsedGPX.applyToTrack(0, calculateElevation);
const [slope] = parsedGPX.applyToTrack(0, calculateSlopes, dist.cumulative)

applyToTrack/applyToRoute return a [result, error] tuple, the same convention as parseGPX: error is set if the track/route index is out of bounds or the supplied function throws, in which case result is null.

Using a Custom DOM Parser

If working in an environment where a custom DOM Parser is required, you can include it like so:

Note, this is significantly slower than using the browser parser.

import { parseGPXWithCustomParser, stringifyGPX} from "@we-gold/gpxjs"
import { DOMParser, XMLSerializer } from "xmldom-qsa"

const customParseMethod = (txt: string): Document | null => {
	return new DOMParser().parseFromString(txt, "text/xml")
}

const [parsedFile, error] = parseGPXWithCustomParser(
	myXMLGPXString,
	customParseMethod
)

const [xml, stringifyError] = stringifyGPX(parsedFile, new XMLSerializer());
if (stringifyError) throw stringifyError;

Contribution

If you are having an issue and aren't sure how to resolve it, feel free to leave an issue.

If you do know how to fix it, please leave a PR, as I cannot guarantee how soon I can address the issue myself.

I do try to be responsive to PRs though, so if you leave one I'll try to get it merged asap.

Also, there are some basic tests built in to the library, so please test your code before you try to get it merged (just to make sure everything is backwards compatible). Use npm run test to do this.

You will need playwright installed to run the tests. Use npx playwright install to install it. Follow any additional instructions given by the installer to ensure it works on your operating system.

If your change might affect performance, run npm run bench before and after to compare. It benchmarks parseGPX/parseGPXWithCustomParser and toGeoJSON separately, for both the browser DOMParser path and the non-browser xmldom-qsa path, since they perform quite differently.

Benchmarks

Last updated 2026-07-04 by npm run bench:update-readme, normally run in CI on push to main. Shared CI hardware is noisy, so treat these as a rough trend rather than a precise number; run npm run bench locally to compare branches on the same machine.

Environment Operation Mean time Ops/sec
Node (xmldom-qsa) parseGPXWithCustomParser: parses a 10000-point track 214.46 ms 4.66 (±7.02%)
Node (xmldom-qsa) toGeoJSON: converts a 10000-point track 0.798 ms 1,253 (±1.23%)
Browser (DOMParser) parseGPX: parses a 10000-point track 162.95 ms 6.14 (±1.94%)
Browser (DOMParser) toGeoJSON: converts a 10000-point track 0.935 ms 1,070 (±4.28%)

Options

You can also run parseGPX() with custom options for more control over the parsing process. See options.ts for more details.

const [parsedFile, error] = parseGPX(data, {
    avgSpeedThreshold: 0.1,
})
// same for parseGPXWithCustomParser()
Property Type Description
removeEmptyFields boolean delete null fields in output
avgSpeedThreshold number average speed threshold (in m/ms) used to determine the moving duration

Types

These descriptions are adapted from GPXParser.js, with minor modifications.

For specific type definition, see types.ts.

Property Type Description
xml XML Document XML Document parsed from GPX string
metadata Metadata object File metadata
waypoints Array of Waypoints Array of waypoints
tracks Array of Tracks Array of waypoints of tracks
routes Array of Routes Array of waypoints of routes
extensions Object Arbitrary extra data from the root <extensions>
version String The version attribute of the root <gpx> element
creator String The creator attribute of the root <gpx> element

Metadata

Property Type Description
name String File name
description String Description
link Array of Links Web addresses
author Author object Author object
time Date Time
copyright Copyright object Copyright holder and license
keywords String Comma-separated list of keywords
bounds Bounds object Minimum and maximum coordinates covered
extensions Object Arbitrary extra data from <extensions>

Waypoint

Property Type Description
name String Point name
comment String Comment
description String Point description
latitude Float Point latitude
longitude Float Point longitude
elevation Float Point elevation
time Date Point time
magneticVariation Float Magnetic variation at the point
geoidHeight Float Height of the geoid above the WGS84 ellipsoid
src String Source device
link Array of Links Web addresses
type String Waypoint classification
fix String GPS fix type: none, 2d, 3d, dgps, or pps
satellites Integer Number of satellites used to calculate the fix
hdop Float Horizontal dilution of precision
vdop Float Vertical dilution of precision
pdop Float Position dilution of precision
ageOfDgpsData Float Seconds since the last DGPS update
dgpsId Integer ID of the DGPS station used
extensions Object Arbitrary extra data from <extensions>

Track

Property Type Description
name String Point name
comment String Comment
description String Point description
src String Source device
number String Track identifier
link Array of Links Web addresses
type String Track type
points Array Array of Points
distance Distance Object Distance information about the Track
duration Duration Object Duration information about the Track
elevation Elevation Object Elevation information about the Track
slopes Float Array Slope of each sub-segment
extensions Object Arbitrary extra data from <trk>'s <extensions>
segmentExtensions Object Arbitrary extra data from <trkseg>'s <extensions>

Route

Property Type Description
name String Point name
comment String Comment
description String Point description
src String Source device
number String Track identifier
link Array of Links Web addresses
type String Route type
points Array Array of Points
distance Distance Object Distance information about the Route
duration Duration Object Duration information about the Route
elevation Elevation Object Elevation information about the Route
slopes Float Array Slope of each sub-segment
extensions Object Arbitrary extra data from <extensions>

Point

The GPX 1.1 XSD defines <trkpt>/<rtept> as the same element type as a standalone <wpt>, so Point (a track/route point) has the exact same fields as Waypoint above.

Distance

Property Type Description
total Float Total distance of the Route/Track
cumulative Float Cumulative distance at each point of the Route/Track

Duration

Property Type Description
cumulative Float Cumulative duration at each point of the Route/Track
movingDuration Float Total moving duration of the Route/Track in seconds
totalDuration Float Total duration of the Route/Track in seconds
startTime Date or null Start date, if available
endTime Date or null End date, if available

Elevation

Property Type Description
maximum Float Maximum elevation
minimum Float Minimum elevation
positive Float Positive elevation difference
negative Float Negative elevation difference
average Float Average elevation

Author

Property Type Description
name String Author name
email Email object Email address of the author
link Link object Web address

Email

Property Type Description
id String Email id
domain String Email domain

Link

Property Type Description
href String Web address
text String Link text
type String Link type

Copyright

Property Type Description
author String Copyright holder
year String Copyright year
license String License URI

Bounds

Property Type Description
minLatitude Float Minimum latitude of the file
minLongitude Float Minimum longitude of the file
maxLatitude Float Maximum latitude of the file
maxLongitude Float Maximum longitude of the file

About

A modern library for parsing GPX files and converting them to GeoJSON.

Topics

Resources

Stars

Watchers

Forks

Releases

Used by

Contributors

Languages