A small, config-driven engine for chronological history maps: a sequence of named, dated points placed on one or more basemaps — Earth, the Moon, Mars, or the celestial sphere — connected as a route, with timeline playback and a date slider.
periplum — evoking the ancient Greek περίπλους (periplous, "a sailing-around"): an account of a coastal voyage, listing places in the order they are reached.
Don't wire anything up by hand — use the periplum template:
- On periplum/periplum, click “Use this template” → Create a new repository.
- Edit
index.html(title,basemaps,statusColors/statusIcons) anddata.json(your points). - Settings → Pages → deploy from
main. Your map is live athttps://YOUR-USER.github.io/YOUR-REPO/.
The template already pins this engine, ships the auto-update workflows (engine-version bump + data refresh), and works out of the box. See the live showcases: magellan, worldcup-soccer, lunar, exoplanets, olympics.
Load Leaflet, then this engine, then call Periplum.render(config):
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/gh/periplum/periplum-core@v0.3.4/dist/periplum.js"
integrity="sha384-8VbzNqGez//sGxFfaGNwxViCSNxylx9LPaTRCro0/+GyBsrjFwduCbRfHT/87CI+"
crossorigin="anonymous"></script>
<script>
Periplum.render({
title: "My voyage",
dataUrl: "data.json",
repo: "https://github.com/me/my-map",
basemaps: [
{ id: "earth", name: "🌍 Earth", type: "tiles",
tileUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution: "© OpenStreetMap", minZoom: 2, initialView: [10, 0], initialZoom: 2 }
],
statusColors: { "outbound": "#1f77b4", "return": "#2ca02c" }
});
</script>Each item carries one or more placements, each tied to a basemap id. Tile/image
basemaps use lat/lon; celestial basemaps use ra/dec.
Already have data in another shape? Pass adapt: (raw) => items[] to transform whatever
your dataUrl returns into the canonical items — no separate build step or duplicated data
file needed. (Or pass data: directly to skip the fetch.) This is how the
Tezos and
Ethereum upgrade maps consume Periplum from
their existing JSON.
tiles— an XYZ tile layer (Earth via OSM; Moon/Mars via planetary tile servers). Optionalcrs: "EPSG4326",subdomains,noWrap,tms.image— a single equirectangular image overlay (great for a global Moon/Mars map); usesimageUrlandbounds(default whole globe), rendered inL.CRS.EPSG4326.celestial— the RA/Dec star-chart renderer (constellations + bright stars for orientation). Placements usera/dec.
Marker styling: colour by statusColors, or set statusIcons (status → emoji, e.g.
{ "Summer": "☀️", "Winter": "❄️" }) for glyph markers.
- periplum/magellan — Magellan's circumnavigation (Earth, static).
- periplum/lunar — crewed & robotic Moon landings (Moon, updated from Wikidata).
- periplum/worldcup-soccer — World Cup host cities (Earth).
Start your own from the periplum template ("Use this template"). Released by git tag; served via jsDelivr. Pin a version in your consumer.
MIT © Corentin Méhat (@cmehat) / Oyatrino Solutions.
{ "items": [ { "name": "Strait of Magellan", "date": "1520-10-21", "status": "outbound", "pairing": null, "placements": [ { "map": "earth", "lat": -52.4, "lon": -68.4, "label": "Strait of Magellan", "popup": { "Event": "Entered the strait" } } ] } ] }