CLI tool
mapbox/polyline avatar
mapbox/polyline

@mapbox/polyline: encoding a path into a URL-safe string

polyline encoding and decoding in javascript

675 stars100 forksJavaScriptBSD-3-Clause

At a glance

What is it?
@mapbox/polyline is a small JavaScript implementation of the Google-style polyline encoding, with decoding and encoding of lat, lng pairs, GeoJSON conversion and a command line wrapper. It is BSD-3-Clause licensed and dependency-light, but the npm package is deprecated in favour of the scoped name and the last release was in 2023.
Who is it for?
polyline fits a web or mobile team that has to move a path through a URL, a database column or a message payload and wants the same encoding the map clients already understand, and that is willing to add a scoped npm dependency.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 121 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The format is the product, not the geometry

The polyline format compresses a sequence of latitude and longitude pairs into a short ASCII string, and the encoding is close enough to the one Google documents that the two are interchangeable in practice. The README calls this a simple google-esque polyline implementation in Javascript. The consequence for a user is that the output is not an internal detail you can change later. Once a path is stored as a polyline string in your database, any client that draws it needs a decoder, and most mapping clients already have one. That is the real reason to use this format rather than a JSON array of coordinates, and it is also the reason not to treat the library as a general spatial tool. What you get here is a codec, plus the small amount of glue needed to move data in and out of GeoJSON.

decode and encode work on lat, lng pairs

The core API is four functions. decode takes an encoded string and returns an array of lat, lon pairs, and encode takes an array of coordinate pairs and returns the encoded string.

js
var polyline = require('@mapbox/polyline');

// returns an array of lat, lon pairs
polyline.decode('_p~iF~ps|U_ulLnnqC_mqNvxq`@');

// returns an array of lat, lon pairs from polyline6 by passing a precision parameter
polyline.decode('cxl_cBqwvnS|Dy@ogFyxmAf`IsnA|CjFzCsHluD_k@hi@ljL', 6);

// returns a GeoJSON LineString Geometry
polyline.toGeoJSON('_p~iF~ps|U_ulLnnqC_mqNvxq`@');

// returns a string-encoded polyline (from coordinate ordered lat,lng)
polyline.encode([[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]]);

Two details are worth reading twice. The first is the coordinate order. The README is explicit that the coordinate array is ordered lat, lng, which is the opposite of the GeoJSON convention, and the example encode call shows the same order. Get that wrong and your path lands in the wrong hemisphere rather than failing loudly. The second is the precision parameter. The default decoding assumes five decimal places of precision, and passing 6 as the second argument to decode handles the polyline6 variant, which is a different variant of the format rather than a display option.

GeoJSON in and out, and the coordinate swap in between

The GeoJSON helpers exist so that a path can come from a mapping library or a server API without a hand-written transform. fromGeoJSON encodes a GeoJSON object into a polyline string, and toGeoJSON decodes a polyline string into a GeoJSON LineString Geometry.

js
// returns a string-encoded polyline from a GeoJSON LineString
polyline.fromGeoJSON({ "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-120.2, 38.5], [-120.95, 40.7], [-126.453, 43.252]]
  },
  "properties": {}
});

Notice the coordinate order in the GeoJSON input: it is longitude first, the standard GeoJSON order, and the helper handles the swap into the lat, lng order the codec wants. This is the reason to prefer fromGeoJSON over calling encode by hand. A hand-written conversion is exactly where the order gets reversed, and the failure is a plausible-looking map in the wrong place. The README points at an API Documentation file in the repository for the full function reference, which is where the exact argument and return shapes live.

A command line wrapper for pipes and scripts

The package also ships a binary, which is the feature that makes the library usable outside a JavaScript program. It can be installed globally or run directly from the node_modules bin directory, and it reads input from stdin. The four flags are --decode, --encode, --toGeoJSON and --fromGeoJSON, and if no flag is given it defaults to --decode.

bash
cat file.json | ./bin/polyline.bin.js --fromGeoJSON > result.txt

That one-liner is a Unix pipeline, so the tool composes with jq, with a file watcher, or with a cron job, which is how a lot of the real usage of a codec like this happens. The package.json shows where the binary lives, with the bin entry mapping the polyline command to bin/polyline.bin.js and main pointing at src/polyline.js. Note that the CLI pulls in a dependency, meow at 9.0.0, which is a command line argument parser, while the library entry itself has no runtime dependencies at all. The README says the library is compatible with nodejs and with the browser, and for the browser the instruction is simply to copy src/polyline.js, which works precisely because that file has no dependencies to resolve.

Copying one file is the browser story

The browser integration deserves more attention than it usually gets. The README states the library is compatible with nodejs and with the browser, and the way to use it in a browser is to copy src/polyline.js. There is no bundler step, no module loader configuration and no build. A single file with no runtime dependencies is a genuinely useful property for a library that will end up inside a map application, where a dependency tree is a cost you pay in bytes, in version conflicts and in supply chain review. The package layout supports this: index.js at the root, src/ for the implementation, bin/ for the command line entry, test/ for the specs, an .eslintrc, a .travis.yml and a Makefile whose test target runs mocha with the spec reporter. The npm test script is eslint over src followed by nyc and tap against test/polyline.test.js, so linting and coverage are wired into the normal workflow rather than being a separate chore.

The old polyline package is deprecated, the scoped one is not

There is a naming trap here. The README notes that the old package polyline has been deprecated in favor of @mapbox/polyline, and that the old package remains but will not receive updates. Anyone following an older tutorial will install polyline and get a package that no longer moves. The current package.json confirms the scoped name @mapbox/polyline, version 1.2.1, licence BSD-3-Clause, authored by Mapbox, with the repository pointing at git+https://github.com/mapbox/polyline.git. The licence is the permissive three-clause BSD, which is the right choice for a format implementation that other vendors are expected to reimplement, and it means a server that wants to decode paths without a JavaScript runtime can port it without a licensing conversation. The default branch is master, and the last push to the repository was on 2026-06-24.

A small library with a slow release trail

The version history is short and the recent tags are old: 1.2.1 from 2023-09-14, 1.2.0 from 2023-04-06, and 1.1.0 from 2019-05-06. A push in June 2026 shows the branch still receives work, but the published versions have not moved since 2023, which means a project that pins this dependency is pinning a 2023 artefact. For a codec whose format is fixed and whose test surface is small, that is a low-risk dependency, and the absence of releases in four years is not by itself a sign of neglect; it is a sign of a finished format. But it does mean that if you find a bug, you are not waiting for a patch, and if you need the library to match a newer variation of the polyline spec, the library is not where that change will land. The repository carries a CHANGELOG.md and a separate API.md, so the history of the format and the history of the code are both readable without running anything.

Editorial conclusion

polyline fits a web or mobile team that has to move a path through a URL, a database column or a message payload and wants the same encoding the map clients already understand, and that is willing to add a scoped npm dependency. It does not fit a project that needs geometry algorithms beyond the encode and decode pair, since the library is the format and not a spatial toolkit, and it does not fit a team that wants a maintained release train, because the last tag is 1.2.1 from 2023-09-14 and the last push was on 2026-06-24. Before you adopt it, install @mapbox/polyline rather than the deprecated polyline package, and decide early whether you need the GeoJSON helpers or the bare codec, because the CLI depends on the meow package while the browser path does not.

Frequently asked questions

What is @mapbox/polyline used for?

It is a JavaScript implementation of the Google-style polyline encoding, which compresses a path of lat, lng pairs into a short string. It decodes a string into an array of lat, lon pairs and encodes an array of such pairs back into a string, and it converts to and from GeoJSON LineString objects.

How do I install the polyline package?

The README gives npm install @mapbox/polyline, and warns that the old polyline package has been deprecated in favor of the scoped one and will not receive updates. For browser use the README suggests copying src/polyline.js, which works because the library has no runtime dependencies.

What coordinate order does polyline use?

The codec uses lat, lng pairs, the opposite of the usual GeoJSON order. The README's encode example shows [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]], and the fromGeoJSON helper takes GeoJSON in longitude-first order and handles the swap itself.

How do I decode a polyline with six decimal places of precision?

Pass the precision as a second argument to decode, as in the README example that decodes a polyline6 string with the value 6. Polyline6 is a different variant of the format rather than a display option, so the precision tells the decoder how the coordinates were quantised in the first place.

Does polyline have a command line tool?

Yes. The README says you can install it globally or run ./node_modules/.bin/polyline, send input via stdin and use the --decode, --encode, --toGeoJSON or --fromGeoJSON flags, with --decode as the default. The example given is cat file.json piped into the binary with --fromGeoJSON.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. mapbox/polyline on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mapbox-polyline.svg)](https://hysenlabs.com/projects/mapbox-polyline)

Was this useful?