|
1 | | -# Turborepo starter |
2 | | - |
3 | | -This Turborepo starter is maintained by the Turborepo core team. |
4 | | - |
5 | | -## Using this example |
6 | | - |
7 | | -Run the following command: |
8 | | - |
9 | | -```sh |
10 | | -npx create-turbo@latest |
11 | | -``` |
12 | | - |
13 | | -## What's inside? |
14 | | - |
15 | | -This Turborepo includes the following packages/apps: |
16 | | - |
17 | | -### Apps and Packages |
18 | | - |
19 | | -- `docs`: a [Next.js](https://nextjs.org/) app |
20 | | -- `web`: another [Next.js](https://nextjs.org/) app |
21 | | -- `@repo/ui`: a stub React component library shared by both `web` and `docs` applications |
22 | | -- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) |
23 | | -- `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo |
24 | | - |
25 | | -Each package/app is 100% [TypeScript](https://www.typescriptlang.org/). |
26 | | - |
27 | | -### Utilities |
28 | | - |
29 | | -This Turborepo has some additional tools already setup for you: |
30 | | - |
31 | | -- [TypeScript](https://www.typescriptlang.org/) for static type checking |
32 | | -- [ESLint](https://eslint.org/) for code linting |
33 | | -- [Prettier](https://prettier.io) for code formatting |
34 | | - |
35 | | -### Build |
36 | | - |
37 | | -To build all apps and packages, run the following command: |
38 | | - |
39 | | -``` |
40 | | -cd my-turborepo |
41 | | -
|
42 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
43 | | -turbo build |
44 | | -
|
45 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
46 | | -npx turbo build |
47 | | -yarn dlx turbo build |
48 | | -pnpm exec turbo build |
| 1 | +<div align="center"> |
| 2 | + |
| 3 | +# OpenMapX |
| 4 | + |
| 5 | +**A fully self-hostable, open-data Google Maps alternative — built entirely from open-source services and open data.** |
| 6 | + |
| 7 | +[](https://github.com/Medformatik/openmapx/actions/workflows/ci.yml) |
| 8 | +[](https://github.com/Medformatik/openmapx/actions/workflows/codeql.yml) |
| 9 | +[](https://github.com/Medformatik/openmapx/actions/workflows/docker.yml) |
| 10 | +[](https://nodejs.org) |
| 11 | +[](https://pnpm.io) |
| 12 | +[](https://www.typescriptlang.org) |
| 13 | +[](https://nextjs.org) |
| 14 | +[](https://fastify.dev) |
| 15 | +[](https://maplibre.org) |
| 16 | +[](https://turborepo.dev) |
| 17 | +[](#contributing) |
| 18 | + |
| 19 | +[Documentation (Wiki)](https://github.com/Medformatik/openmapx/wiki) • [Self-Hosting Guide](https://github.com/Medformatik/openmapx/wiki/Self-Hosting-Guide) • [Architecture](https://github.com/Medformatik/openmapx/wiki/Architecture) • [CLI Reference](https://github.com/Medformatik/openmapx/wiki/CLI-Reference) • [Integration System](https://github.com/Medformatik/openmapx/wiki/Integration-System) |
| 20 | + |
| 21 | +</div> |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +OpenMapX is a complete mapping platform you run on your own infrastructure: search, routing, public transit, street-level imagery, POI data, weather, reviews, and dozens of overlays — all served from open data and open-source backends. The application stack is described declaratively by **service plugins** (`services/<slug>/service.json`) and **integration plugins** (`integrations/<id>/manifest.json`), and the entire Docker Compose deployment is rendered on demand from those manifests. There is no hand-maintained `docker-compose.yml`. |
| 26 | + |
| 27 | +## Highlights |
| 28 | + |
| 29 | +- **Complete mapping platform** — geocoding, routing, public transit, live vehicles, street view, POI search, knowledge enrichment, reviews, weather, dozens of overlays |
| 30 | +- **Two-layer plugin system** — *services* (containers: Valhalla, Nominatim, MOTIS, …) and *integrations* (app features: providers, overlays, data sources, tools). Both support community plugins from any Git URL |
| 31 | +- **75+ built-in integrations** across 12 domains and **20+ built-in services** rendered into a generated `docker-compose.yml` |
| 32 | +- **Self-host everything** — no service is mandatory and every external dependency can be replaced by a self-hosted alternative |
| 33 | +- **Open data** — OpenStreetMap, GTFS via Transitous, Wikidata, Wikipedia, Mapillary, NASA, NOAA, ECCC, DWD, MeteoAlarm, OpenAQ, USGS, NPS, and more |
| 34 | +- **Privacy-first** — no third-party analytics; all upstream calls proxied through your API server so providers see your IP, not the user's |
| 35 | +- **First-class admin UI** — service catalog, integration config, capability bindings, audit log, users, jobs, compose preview, data workflows |
| 36 | +- **Modern stack** — Next.js 16, Fastify 5, MapLibre GL JS 5, MUI 7, PostgreSQL + PostGIS, Valkey (Redis), Drizzle ORM, Better Auth, TypeScript end-to-end |
| 37 | + |
| 38 | +## Two plugin systems |
| 39 | + |
| 40 | +OpenMapX has two complementary plugin layers. Knowing which is which makes everything else easier to read. |
| 41 | + |
| 42 | +| Layer | Lives in | Manifest | Purpose | |
| 43 | +|---|---|---|---| |
| 44 | +| **Services** | `services/<slug>/` | `service.json` | Backend daemons that run as Docker containers (databases, routing engines, geocoders, transit engines, tile servers). Each declares its image, ports, volumes, capabilities (`provides:`), data inputs (`consumes:`), and exposure. | |
| 45 | +| **Integrations** | `integrations/<id>/` | `manifest.json` | App-level features that consume services and external APIs (geocoding, routing, transit, overlays, data sources, photos, reviews, weather, knowledge). Each declares its domain, frontend components, backend routes, config schema, attribution, and which services it `requires:`. | |
| 46 | + |
| 47 | +Both layers support **community plugins** managed from the admin panel and the `openmapx` CLI. |
| 48 | + |
| 49 | +## Architecture at a glance |
| 50 | + |
| 51 | +```mermaid |
| 52 | +graph TD |
| 53 | + Internet((Internet)) --> Traefik |
| 54 | +
|
| 55 | + subgraph "Reverse Proxy" |
| 56 | + Traefik["Traefik :80/:443<br/>TLS via Let's Encrypt"] |
| 57 | + end |
| 58 | +
|
| 59 | + Traefik --> Web["app-web :3000<br/>Next.js"] |
| 60 | + Traefik --> API["app-api :3001<br/>Fastify"] |
| 61 | + Traefik --> TileServer["tileserver :8080<br/>Vector + raster tiles"] |
| 62 | + Traefik --> Martin["martin :3000<br/>PostGIS vector tiles"] |
| 63 | +
|
| 64 | + subgraph "API Server" |
| 65 | + IntHost["Integration Host<br/>75+ built-in + community"] |
| 66 | + Orchestrators["Domain orchestrators<br/>(geocoding, routing, transit, ...)"] |
| 67 | + SvcRegistry["Service Registry"] |
| 68 | + Bindings["Capability Bindings"] |
| 69 | + end |
| 70 | +
|
| 71 | + API --> IntHost |
| 72 | + IntHost --> Orchestrators |
| 73 | + IntHost --> SvcRegistry |
| 74 | + IntHost --> Bindings |
| 75 | +
|
| 76 | + subgraph "Routing" |
| 77 | + Valhalla["valhalla :8002"] |
| 78 | + OSRM["osrm :5000"] |
| 79 | + end |
| 80 | +
|
| 81 | + subgraph "Transit" |
| 82 | + MOTIS["motis :8081"] |
| 83 | + OTP["otp :8090"] |
| 84 | + end |
| 85 | +
|
| 86 | + subgraph "Geocoding" |
| 87 | + Photon["photon :2322"] |
| 88 | + Nominatim["nominatim :8088"] |
| 89 | + Pelias["pelias :4000"] |
| 90 | + end |
| 91 | +
|
| 92 | + subgraph "Infrastructure" |
| 93 | + PG["postgis :5432"] |
| 94 | + Redis["redis (Valkey) :6379"] |
| 95 | + ES["elasticsearch :9200"] |
| 96 | + DM["data-manager :4000"] |
| 97 | + end |
| 98 | +
|
| 99 | + Orchestrators --> Valhalla |
| 100 | + Orchestrators --> OSRM |
| 101 | + Orchestrators --> MOTIS |
| 102 | + Orchestrators --> OTP |
| 103 | + Orchestrators --> Photon |
| 104 | + Orchestrators --> Nominatim |
| 105 | + Orchestrators --> Pelias |
| 106 | + API --> PG |
| 107 | + API --> Redis |
| 108 | + Pelias --> ES |
| 109 | + Martin --> PG |
49 | 110 | ``` |
50 | 111 |
|
51 | | -You can build a specific package by using a [filter](https://turborepo.dev/docs/crafting-your-repository/running-tasks#using-filters): |
| 112 | +All containers communicate over the internal `openmapx` Docker network. Only Traefik (and any service that explicitly opts into `exposure.hostPorts`) is reachable from outside the host. See the [Architecture wiki page](https://github.com/Medformatik/openmapx/wiki/Architecture) for the full picture. |
52 | 113 |
|
53 | | -``` |
54 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
55 | | -turbo build --filter=docs |
56 | | -
|
57 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
58 | | -npx turbo build --filter=docs |
59 | | -yarn exec turbo build --filter=docs |
60 | | -pnpm exec turbo build --filter=docs |
61 | | -``` |
| 114 | +## CLI |
62 | 115 |
|
63 | | -### Develop |
64 | | - |
65 | | -To develop all apps and packages, run the following command: |
| 116 | +The `openmapx` CLI is the operator's command-line front end for the entire self-hosting workflow. It runs directly off TypeScript via Node's `--experimental-strip-types` (no build step). |
66 | 117 |
|
| 118 | +```bash |
| 119 | +pnpm openmapx services enable|disable|list|start|stop|restart|build|status|logs |
| 120 | +pnpm openmapx compose render|up|down |
| 121 | +pnpm openmapx data download|link|status |
| 122 | +pnpm openmapx repos list|add|refresh|remove # community service repositories |
| 123 | +pnpm openmapx integrations list|install|validate|build |
| 124 | +pnpm openmapx users list|create|promote |
| 125 | +pnpm openmapx check # environment + manifest validation |
67 | 126 | ``` |
68 | | -cd my-turborepo |
69 | 127 |
|
70 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
71 | | -turbo dev |
| 128 | +See the [CLI Reference](https://github.com/Medformatik/openmapx/wiki/CLI-Reference) for every command, flag, and preset. |
72 | 129 |
|
73 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
74 | | -npx turbo dev |
75 | | -yarn exec turbo dev |
76 | | -pnpm exec turbo dev |
77 | | -``` |
| 130 | +## Admin panel |
78 | 131 |
|
79 | | -You can develop a specific package by using a [filter](https://turborepo.dev/docs/crafting-your-repository/running-tasks#using-filters): |
| 132 | +Once the stack is running, `/admin` exposes the full operations surface (gated by `requireAdmin`): |
80 | 133 |
|
81 | | -``` |
82 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
83 | | -turbo dev --filter=web |
| 134 | +- **Services** — installed services with status, manifest viewer, per-service config, logs, start/stop/restart |
| 135 | +- **Service catalog** — community-installable services discovered from registered repositories |
| 136 | +- **Service repositories** — register, refresh, remove community service Git repositories |
| 137 | +- **Integrations** — per-integration config (5-layer cascade), capability binding picker, health, logs |
| 138 | +- **Capability bindings** — pick which provider satisfies an integration's capability when multiple installed services match |
| 139 | +- **Users** — Better Auth admin (roles, sessions, ban, impersonate) |
| 140 | +- **Audit log, jobs, compose preview, data workflows, status, settings, store, activity** |
84 | 141 |
|
85 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
86 | | -npx turbo dev --filter=web |
87 | | -yarn exec turbo dev --filter=web |
88 | | -pnpm exec turbo dev --filter=web |
89 | | -``` |
| 142 | +See [Admin Panel](https://github.com/Medformatik/openmapx/wiki/Admin-Panel) for screenshots and details. |
90 | 143 |
|
91 | | -### Remote Caching |
| 144 | +## Tech stack |
92 | 145 |
|
93 | | -> [!TIP] |
94 | | -> Vercel Remote Cache is free for all plans. Get started today at [vercel.com](https://vercel.com/signup?utm_source=remote-cache-sdk&utm_campaign=free_remote_cache). |
| 146 | +| Layer | Tech | |
| 147 | +|---|---| |
| 148 | +| Frontend | Next.js 16, React 19, MapLibre GL JS 5, MUI 7, Tailwind 4, Zustand, TanStack Query, next-intl, Framer Motion, Serwist | |
| 149 | +| API | Fastify 5, Drizzle ORM, Better Auth (email/password, OAuth OSM/Mapillary, passkeys, 2FA, admin role) | |
| 150 | +| Data | PostgreSQL 18 + PostGIS 3.6, Valkey 8 (Redis-compatible), Elasticsearch (Pelias backend) | |
| 151 | +| Routing & transit | Valhalla, OSRM, MOTIS, OpenTripPlanner | |
| 152 | +| Geocoding | Photon, Nominatim, Pelias | |
| 153 | +| Tiles | TileServer GL, Martin (PostGIS vector tiles) | |
| 154 | +| Tooling | Turborepo, pnpm 10, Biome, Vitest, Husky + Commitlint, Changesets, Docker Compose v2, Traefik | |
| 155 | +| Language | TypeScript end-to-end (Node 24+) | |
95 | 156 |
|
96 | | -Turborepo can use a technique known as [Remote Caching](https://turborepo.dev/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines. |
| 157 | +## Contributing |
97 | 158 |
|
98 | | -By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup?utm_source=turborepo-examples), then enter the following commands: |
| 159 | +Contributions are welcome — bug reports, feature requests, integrations, services, and documentation improvements all help. Before opening a PR: |
99 | 160 |
|
100 | | -``` |
101 | | -cd my-turborepo |
102 | | -
|
103 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
104 | | -turbo login |
105 | | -
|
106 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
107 | | -npx turbo login |
108 | | -yarn exec turbo login |
109 | | -pnpm exec turbo login |
110 | | -``` |
| 161 | +1. Open an issue if the change is non-trivial so we can align on scope. |
| 162 | +2. Run `pnpm lint`, `pnpm check-types`, and `pnpm test` locally — the CI workflow runs the same checks. |
| 163 | +3. Use [Conventional Commits](https://www.conventionalcommits.org/) (enforced by Commitlint + Husky). |
| 164 | +4. For new community plugins, see [Community Integrations](https://github.com/Medformatik/openmapx/wiki/Community-Integrations) or [Community Service Repositories](https://github.com/Medformatik/openmapx/wiki/Community-Service-Repositories). |
111 | 165 |
|
112 | | -This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview). |
| 166 | +## Acknowledgements |
113 | 167 |
|
114 | | -Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo: |
115 | | - |
116 | | -``` |
117 | | -# With [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation) installed (recommended) |
118 | | -turbo link |
119 | | -
|
120 | | -# Without [global `turbo`](https://turborepo.dev/docs/getting-started/installation#global-installation), use your package manager |
121 | | -npx turbo link |
122 | | -yarn exec turbo link |
123 | | -pnpm exec turbo link |
124 | | -``` |
| 168 | +OpenMapX stands on a huge stack of open data and open-source software. Special thanks to: |
125 | 169 |
|
126 | | -## Useful Links |
| 170 | +[OpenStreetMap](https://www.openstreetmap.org) contributors · [Valhalla](https://github.com/valhalla/valhalla) · [OSRM](https://github.com/Project-OSRM/osrm-backend) · [MOTIS](https://github.com/motis-project/motis) · [OpenTripPlanner](https://github.com/opentripplanner/OpenTripPlanner) · [Nominatim](https://nominatim.org) · [Photon](https://photon.komoot.io) · [Pelias](https://github.com/pelias/pelias) · [Transitous](https://transitous.org) · [MapLibre](https://maplibre.org) · [TileServer GL](https://github.com/maptiler/tileserver-gl) · [Martin](https://github.com/maplibre/martin) · [Overpass API](https://overpass-api.de) · [Mapillary](https://www.mapillary.com) · [Wikidata](https://www.wikidata.org) / [Wikipedia](https://www.wikipedia.org) · [Mangrove Reviews](https://mangrove.reviews) · the many transit agencies who publish open data feeds. |
127 | 171 |
|
128 | | -Learn more about the power of Turborepo: |
| 172 | +## License |
129 | 173 |
|
130 | | -- [Tasks](https://turborepo.dev/docs/crafting-your-repository/running-tasks) |
131 | | -- [Caching](https://turborepo.dev/docs/crafting-your-repository/caching) |
132 | | -- [Remote Caching](https://turborepo.dev/docs/core-concepts/remote-caching) |
133 | | -- [Filtering](https://turborepo.dev/docs/crafting-your-repository/running-tasks#using-filters) |
134 | | -- [Configuration Options](https://turborepo.dev/docs/reference/configuration) |
135 | | -- [CLI Usage](https://turborepo.dev/docs/reference/command-line-reference) |
| 174 | +A `LICENSE` file has not yet been added to this repository. Until one is published, all rights are reserved by the author. Please open an issue if you intend to use, fork, or redistribute the code. |
0 commit comments