Map tiles are fetched directly from the chosen basemap's own servers (OpenStreetMap, OpenTopoMap, or CyclOSM — all volunteer-run, no API key needed) — no proxy, no backend. None of them have retina tiles, so above 1x the route line, markers, and text render crisply at full resolution while the basemap itself is upscaled. Each requires attribution on every image using their tiles — only turn it off if you're previewing locally.
Powered by
gpxsnap
A dependency-free GPX route-preview renderer — no sharp, no libvips, no native bindings anywhere in the chain. The same library behind the demo above runs in Bun, Node (≥22.18), and Deno too.

Install
bun add gpxsnapimport { renderRoute } from "gpxsnap";
const png = await renderRoute({
coordinates: [[2.3522, 48.8566], [2.295, 48.8738], [2.2986, 48.8867]],
width: 1200,
height: 600,
});