A self-contained, fully offline OpenStreetMap viewer you can run from a USB stick — no internet, no cloud, no runtime dependencies.
Two servers start together when you run start.sh:
| Server | Default port | Role |
|---|---|---|
| Martin (tile server) | 3000 |
Serves vector tiles from planet.pmtiles, generates font glyphs on-the-fly from TTF/OTF files, and generates map sprites on-the-fly from SVG icons |
| BusyBox httpd (or Python fallback) | 8080 |
Serves the static map viewer (index.html, maplibre-gl.js/css, style.json) |
The browser loads the map from http://localhost:8080 and pulls tiles, fonts, and sprites from http://localhost:3000.
# 1. Copy the repository (or USB stick contents) to a local directory
# 2. Obtain planet.pmtiles and place it in the same directory (see Build section)
# 3. Launch
./start.sh
# Browser opens automatically at http://localhost:8080Press Ctrl+C to stop both servers.
start.sh auto-detects your platform and picks the right binaries. No configuration needed.
| Platform | Martin binary | BusyBox binary |
|---|---|---|
| Linux x86_64 (glibc) | martin-x86_64-unknown-linux-gnu/martin |
busybox-x86_64-linux |
| Linux x86_64 (musl) | martin-x86_64-unknown-linux-musl/martin |
busybox-x86_64-linux |
| Linux aarch64 (glibc) | martin-aarch64-unknown-linux-gnu/martin |
busybox-aarch64-linux |
| Linux aarch64 (musl) | martin-aarch64-unknown-linux-musl/martin |
busybox-aarch64-linux |
| macOS x86_64 | martin-x86_64-apple-darwin/martin |
python3 fallback |
| macOS arm64 | martin-aarch64-apple-darwin/martin |
python3 fallback |
| Windows x86_64 (Git Bash / MSYS2) | martin-x86_64-pc-windows-msvc/martin.exe |
busybox64.exe |
| Windows arm64 (Git Bash / MSYS2) | (not bundled — specify manually) | busybox64a.exe |
| WSL | Same as Linux above | Same as Linux above |
Note:
busybox64u.exeis also bundled (Unicode/UTF-8 variant for Windows) but is not selected automatically. If you have display issues on Windows, start the HTTP server manually withbusybox64u.exe httpd -f -p 0.0.0.0:8080 -h .and pass--no-browsertostart.shso it skips launching the built-in static server.
./start.sh [OPTIONS]
Options:
--no-browser Skip launching the web browser automatically.
--martin-bin PATH Path to the martin binary (default: ./martin or auto-detected).
--martin-port PORT Port for the Martin tile server (default: 3000).
--http-port PORT Port for the static HTTP server (default: 8080).
Environment variables:
MARTIN_PORT=3000 Same as --martin-port
HTTP_PORT=8080 Port for the static web server
planet-offline/
├── start.sh # Launcher (auto-detects platform)
├── build.sh # Dependency downloader / build helper
├── martin-config.yaml # Martin server configuration
├── httpd.conf # MIME types for BusyBox httpd
├── index.html # Map viewer web UI (MapLibre GL JS)
├── style.json # MapLibre GL map style
├── maplibre-gl.js # MapLibre GL JS (vendored)
├── maplibre-gl.css # MapLibre GL CSS (vendored)
├── fonts/ # Noto Sans TTF/OTF fonts (martin serves glyphs from these)
│ ├── NotoSans-Regular.ttf
│ ├── NotoSans-Bold.ttf
│ ├── NotoSans-Italic.ttf
│ ├── NotoSans-BoldItalic.ttf
│ └── NotoSansCJKsc-Regular.otf # CJK labels (~16 MB)
├── sprites/icons/ # 221 Maki SVG icons (martin serves sprites from these)
├── martin-x86_64-unknown-linux-gnu/
├── martin-x86_64-unknown-linux-musl/
├── martin-aarch64-unknown-linux-gnu/
├── martin-aarch64-unknown-linux-musl/
├── martin-x86_64-apple-darwin/
├── martin-aarch64-apple-darwin/
├── martin-x86_64-pc-windows-msvc/
├── busybox-x86_64-linux
├── busybox-aarch64-linux
├── busybox64.exe # Windows x86_64
├── busybox64a.exe # Windows arm64
└── busybox64u.exe # Windows (Unicode variant)
# Not included — must be obtained separately:
└── planet.pmtiles # ~80 GB planet vector tile archive
planet.pmtiles is not included in the repository (it is ~80 GB). Use build.sh as a guide or follow these steps manually:
- ~250 GB free disk space
- 64 GB RAM recommended (32 GB minimum)
- Java 21+
curl,git
# 1. Download the latest OSM planet dump (ODbL licensed)
curl -L -C - -o planet.osm.pbf \
"https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf"
# 2. Download Planetiler
curl -L -o planetiler.jar \
"https://github.com/onthegomap/planetiler/releases/latest/download/planetiler.jar"
# 3. Generate planet.pmtiles (adjust -Xmx to your available RAM)
java -Xmx32g -jar planetiler.jar \
--osm-path=planet.osm.pbf \
--output=planet.pmtiles \
--output-format=pmtiles \
--download \
--maxzoom=14 \
--nodemap-type=array \
--storage=mmap
# --download fetches Natural Earth + ocean polygons automatically
# --nodemap-type=sparsearray if RAM < 32 GB
# 4. Place planet.pmtiles next to start.shbuild.sh also downloads MapLibre GL JS, Noto Sans fonts, and Maki icons if they are missing.
martin-config.yaml controls the tile server:
listen_addresses: '0.0.0.0:3000' # changed automatically by start.sh --martin-port
web_ui: enable-for-all # Martin's built-in Web UI at /
fonts:
- fonts # directory of TTF/OTF files
sprites:
paths:
- sprites/icons # directory of SVG icons
pmtiles:
sources:
planet:
path: planet.pmtiles # the tile archivestart.sh patches listen_addresses in this file at runtime to match --martin-port / $MARTIN_PORT.
| Asset | Source | License |
|---|---|---|
| OpenStreetMap planet data | openstreetmap.org | ODbL |
| Martin tile server | github.com/maplibre/martin | MIT |
| MapLibre GL JS | maplibre.org | BSD-3-Clause |
| Noto Sans fonts | github.com/notofonts | Apache 2.0 |
| Noto Sans CJK | github.com/notofonts/noto-cjk | SIL OFL 1.1 |
| Maki icons | github.com/mapbox/maki | CC0 |
| BusyBox (Linux) | busybox.net | GPL-2.0 |
| BusyBox (Windows) | frippery.org/busybox | GPL-2.0 |