An open map engine: a minimal 2D map plus a registry of layers you switch on and off — OSM points of interest, weather, routes, your own pins, and a 3D quest game rendered over the same viewport.
It runs with no API keys. A fresh clone gets a basemap (CARTO), POI search (OpenStreetMap via
Overpass), weather (Open-Meteo) and rain radar (RainViewer) without anyone signing up for
anything. Sources that do need a key announce themselves through GET /config and stay hidden
until one is present, so nothing breaks in a keyless install — it just offers less.
npm install
npm run db:up # PostGIS on :5434
npm run db:seed # demo data
npm run dev # API :4033 + web :5173Demo login: demo@mapos.test / demo1234.
Optional configuration lives in .env (copy from .env.example); every entry is optional. See
docs/environment.md for what each key unlocks.
apps/web— Vite, React and MapLibreapps/api— Fastify and PostGISpackages/layer-sdk— the shared contracts: layer plugins, place sources, info panelspackages/map-runtime— UI-neutral manifest registry, capability negotiation and MapLibre layer lifecycleapps/runtime-starter— keyless clean-room application over those two public workspaces
The engine is built around registries, and nearly every feature is a new entry in one of them rather than a change to the core. CONTRIBUTING.md walks through them with minimal examples:
- Layer plugins — anything drawn on the map.
- Place sources — anything that answers "what is near this bounding box".
- Info panels — anything shown in the place detail dialog, including embedded iframes.
- Quest sources — real places the game can anchor a quest to.
- Guide sources — editorial content for a region in Objevuj.
- Basemaps — the background everything else is drawn on.
Product architecture decisions are recorded in docs/adr: modes share an additive
layer stack, and UserLayer is the current ownership and publishing unit until a real multi-user
workspace workflow requires a Project.
The background is chosen separately from the sources of places, so anyone's imagery can sit under anyone else's pins. Keyless backgrounds cover street, terrain and satellite (CARTO, OpenFreeMap, OpenTopoMap, Sentinel-2 cloudless, NASA GIBS, Esri World Imagery); with a free key the picker also offers Mapy.com, Google, HERE, MapTiler, Thunderforest, Stadia, TomTom and Geoapify. Keyed tiles go through a server-side proxy, so no key reaches the browser. Aerial backgrounds can carry a label overlay, and vector ones can extrude buildings into 3D.
docs/basemaps.md lists where to register, how much each gives away for free and which of them ask for a credit card.
The core four, always present:
| ID | Kind | Description |
|---|---|---|
osm-poi |
pins | OSM travel POI (castles, viewpoints…) |
user-layers |
pins | Your own layers, with an edit mode |
weather |
raster | Rain radar, temperature, wind and more |
game |
custom-gl | 3D quest zones and encounters (Three.js) |
On top of those, six keyless tile overlays (CyclOSM, Waymarked Trails, OpenRailwayMap, OpenSeaMap, OpenTopoMap, OpenSnowMap) and a set of data layers — earthquakes, species observations, air quality, Commons photos, accessible toilets, shared mobility, and, with a free key, EV chargers, street imagery, active fires, air-quality stations, bird sightings and events. See docs/data-sources.md for what each needs.
npm run lint
npm run typecheck
npm test # unit tests
npm run test:e2e # Playwright, boots the in-memory API — no database neededDEPLOY_HOST=user@your-server ./scripts/deploy-vps.sh
# or directly:
docker compose -f infra/compose.production.yml up -d --buildMap data and imagery belong to their respective providers and carry their own terms — most notably OpenStreetMap under ODbL and Wikipedia/Wikivoyage under CC BY-SA. Attribution is a licence condition, not a courtesy: every layer and source declares its own, and the engine aggregates them into the map's attribution control. docs/data-sources.md lists what is integrated, under which terms, and what was deliberately left out.