Planisfy
July 29, 2026 ยท View on GitHub
Planisfy is an open-source, self-hostable Mapbox Platform layer for teams building with MapLibre, vector tiles, routing, geocoding, API keys, usage tracking, jobs, and map operations.
MapLibre is the open-source renderer. Planisfy is the platform/control-plane layer around it.
Why Planisfy?
Using MapLibre gives you an open renderer, but a production map platform usually needs more than rendering:
- MapLibre-compatible style publishing
- Vector tile and PMTiles-backed tileset delivery
- API keys, scopes, usage tracking, and rate limits
- Geocoding, reverse geocoding, routing, isochrones, matrices, optimized trips, elevation, and static maps
- Background jobs for uploads, imports, tiling, and artifact management
- Health checks, setup preflight, operational visibility, backup, restore, and upgrade paths
- Managed and self-hosted deployment modes from the same codebase
Planisfy focuses on that surrounding platform layer so teams do not have to stitch every map service, operational check, and control-plane concern together from scratch.
What This Repository Contains
This repository contains the open-source Planisfy platform implementation:
| Path | Purpose |
|---|---|
apps/api | Hono API gateway for public map APIs, auth, console APIs, internal routes, health, and metrics. |
apps/console | Customer Console for styles, tilesets, API keys, usage, platform readiness, operations, and account settings. |
apps/admin | Internal operations app for tenants, jobs, storage, usage, health, audits, and upgrades. |
apps/docs | Fumadocs public documentation site. |
apps/marketing | Public website and managed-mode auth entry pages. |
apps/worker-geodata | BullMQ/outbox worker for uploads, imports, tiling, and artifact ledger updates. |
apps/worker-billing | Scheduled managed-billing reconciliation, cleanup, and durable webhook processing. |
apps/elevation | Local SRTM HGT elevation lookup service used by the API in Docker Compose. |
apps/static-renderer | Local MapLibre PNG renderer used by the static map API route. |
apps/self-host-supervisor | Optional local-only supervisor for guarded backup, upgrade, and rollback actions. |
apps/tile-worker | Optional isolated PMTiles delivery runtime. The API serves tiles directly by default. |
packages/* | Shared auth, database, env, event, storage, style, policy, UI, and tooling packages. |
infra/docker | Docker Compose stack, engine configs, and ignored runtime data mounts. |
docs | Durable contributor and operator references. |
Public API Surface
The API gateway includes:
- Published assets:
/tiles/*,/styles/v1/*, and/fonts/* - Service APIs:
/geocoding/*,/directions/*,/isochrone/*,/matching/*,/matrix/*,/optimized-trips/*,/elevation/*, and/static/* - Console APIs:
/console/* - Internal, health, support, and setup endpoints:
/internal/*,/health,/health/detailed,/metrics, and/setup/preflight
External geospatial engines are configured separately. Geocoding needs Pelias, routing needs Valhalla graph data, tiles need Martin or uploaded PMTiles artifacts, elevation needs DEM tiles, and static maps need the static renderer.
Routing integrations may use structured POST contracts at
/directions/v1/:profile, /isochrone/v1/:profile,
/matrix/v1/:profile, and /matching/v1/:profile. These remain generic
Planisfy service APIs: callers provide Valhalla-compatible coordinates and
profiles, while Planisfy owns authentication, usage tracking, validation,
timeouts, and provider proxying.
Deployment Modes
Planisfy supports two deployment modes:
self_host: local or customer-managed infrastructure.managed: hosted operation using the same API, Console, Admin, Docs, Marketing, worker, database schema, publication model, and public route shapes.
The difference is policy and configuration, not separate codebases. See docs/deployment-modes.md for provider and capability details.
Documentation
Public user-facing docs live in apps/docs/content/docs.
Local Development
Install dependencies:
pnpm install
Copy the local environment:
cp .env.example .env
Run all development servers through Turborepo:
pnpm dev
Local dev uses portless hostnames for web apps:
| Surface | URL |
|---|---|
| Marketing | https://planisfy.localhost |
| Console | https://console.planisfy.localhost |
| Docs | https://docs.planisfy.localhost |
| Admin | https://admin.planisfy.localhost |
| API | https://api.planisfy.localhost |
Common verification commands are turbo-backed at the root:
pnpm verify
pnpm check-types
pnpm lint
pnpm test
pnpm build
Package-specific examples:
pnpm --filter api test
pnpm --filter docs check-types
pnpm db:migrate
Self-Host Quick Path
From the repository root:
cp .env.example .env
pnpm self-host:setup
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d
pnpm db:migrate
Default local ports:
| Service | URL |
|---|---|
| Marketing | http://localhost:3000 |
| Console | http://localhost:3001 |
| Docs | http://localhost:3002 |
| Admin | http://localhost:3003 |
| API | http://localhost:4000 |
| Martin | http://localhost:3005 |
| Valhalla | http://localhost:3007 |
| Pelias | http://localhost:3100 |
| Local elevation | http://localhost:4011 |
| Static renderer | http://localhost:4300 |
Check the stack:
curl http://localhost:4000/health
curl http://localhost:4000/health/detailed
curl http://localhost:4000/setup/preflight
Planisfy does not commit binary map, routing, geocoding, or DEM datasets. A clean stack can boot with degraded map service checks until compatible files are placed under infra/docker/data/* or provider URLs are configured.
Contributor Notes
Planisfy keeps user-facing app surfaces behind explicit package and HTTP contracts. Console should call the API through @planisfy/api-contracts and its local API client; it should not import API route internals, the database package, or Drizzle directly.
Admin is an internal operator surface and may depend on server-side packages such as @planisfy/database when it needs direct control-plane access. Shared runtime behavior that crosses apps should live in packages/* or behind an API route rather than as app-to-app imports.
Planisfy keeps workspace packages and apps on ESM by default with "type": "module". Node services use TypeScript directly in development, but production starts compiled JavaScript from dist/ after tsup builds. Next.js apps keep TypeScript source because Next owns compilation for client and server code.
License
Planisfy is licensed under AGPL-3.0-only.