Open-source project
headwaymaps/headway avatar
headwaymaps/headway

Headway: Self-Hosted OpenStreetMap Maps Stack

Self-hostable maps stack, powered by OpenStreetMap.

3,005 stars79 forksRustApache-2.0

At a glance

What is it?
Headway packages a map frontend, geocoder, routing engine, and tile server into a single Docker Compose deployment backed by OpenStreetMap. Transit routing is still unfinished, and the build process requires a dedicated machine with at least 8 GB of RAM.
Who is it for?
Headway is the right choice for teams that need private map infrastructure and are comfortable running Docker Compose on amd64 hardware. It is not the right choice for anyone who needs functional transit directions today, those who must support ARM or Windows builds, or projects that cannot dedicate 50 to 100 GB of disk during the data generation phase.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Headway Solves and Who It Is For

Commercial mapping APIs charge per request and route all location queries through third-party infrastructure. Headway addresses both problems by running a complete maps stack on hardware you control. The project targets engineers and teams who need to keep location data private, avoid usage-based API costs, or operate in environments where outbound connectivity to commercial map services is restricted.

The stack covers the four components that a self-hosted mapping deployment needs: a vector tile server backed by OpenStreetMap data, a geocoder for address and point-of-interest search, a routing engine for directions, and a web frontend that connects them. All four run together under a single Docker Compose file. The README describes the result as a "maps stack in a box" that comes up with just a few commands once the area data is prepared.

The project supports over 200 predefined city and region extracts. Users can also supply their own OpenStreetMap extract, covering anywhere from a single neighborhood to the full planet. The FULL_PLANET.md file in the repository documents the additional requirements for planet-scale deployments.

The Services Behind a Headway Deployment

The Docker Compose file defines a layered startup sequence. Each data-dependent service has a paired init container that copies bootstrap artifacts into a named volume before the main service starts. The tileserver-init container moves PMTiles, terrain MBTiles, and landcover MBTiles into the tileserver_data volume; tileserver then starts only after that init completes successfully.

Routing is handled by two services working together: Valhalla, which processes the actual graph traversal, and Travelmux, a Rust service that proxies requests to Valhalla at http://valhalla:8002 and enriches them with elevation data. The environment variable HEADWAY_AREA selects which set of pre-built data files to load, and the compose file reads area-specific configuration from a per-area env file:

yaml
env_file: builds/${HEADWAY_AREA:?}/.env

The Rust workspace at the root of the repository contains three members: travelmux, transit-zoner, and gtfout. Transit-zoner and gtfout are GTFS-related services, corresponding to the transit directions feature that the README marks as a work-in-progress. The workspace uses shared dependency versions for actix-web, clap, serde, and related crates, declared in the workspace-level Cargo.toml.

The full architecture is documented in ARCHITECTURE.md in the repository. The README does not reproduce those details inline, so understanding the complete data flow requires reading that file directly.

Setting Up a Development Environment

Headway uses a pre-commit hook to run formatting, linting, and test checks before each commit. After cloning the repository, configure Git to use the bundled hook path with one command:

bash
git config core.hooksPath .githooks

This runs .githooks/pre-commit automatically before each commit rather than requiring manual execution.

For the full build and deployment process, BUILD.md is the authoritative reference. The README defers to it for detailed instructions and does not reproduce the step-by-step commands inline. The build machine requires at least 8 GB of RAM; larger extracts may need more. Expect to provision 50 to 100 GB of disk space during the data generation phase. The data generation step produces the area-specific files that Docker Compose consumes at runtime.

At runtime, the hardware demands are lower. The README notes that a medium-sized metro area requires around 4 GB of memory to run the full stack. The project has been confirmed to work on amd64 machines running Linux and macOS. There is no documented support for ARM or Windows hosts.

After the area data is built and the compose file is started, the stack presents a web frontend where users can search for addresses and points of interest within the extract, view the map, and request turn-by-turn directions for driving, cycling, or walking routes.

Routing Modes and the Transit Gap

Headway supports three routing modes out of the box: driving, cycling, and walking. All three produce directions between any two points within the loaded OSM extract. Elevation data flows through travelmux-init into the travelmux service, which means the routing engine can account for terrain.

Transit directions, meaning bus and rail routes drawn from GTFS feeds, are explicitly marked as a work-in-progress in the README. The transit-zoner and gtfout services in the Rust workspace exist to support this feature, and the repository includes a docker-compose-with-transit.yaml file and a TRANSIT_ZONER.md document, but the README does not describe transit as functional for end users.

This gap matters in practice. A team deploying Headway for a city where users expect to plan journeys by public transport will need to wait for that feature to reach completion or find a separate solution. The three supported modes cover most car and active-transport use cases, but the absence of working transit routing is a meaningful constraint for urban deployment scenarios.

Headway Against Stand-Alone OpenStreetMap Components

Nominatim is the geocoding engine that powers search on openstreetmap.org. It handles address lookup and POI search from OpenStreetMap data and can be self-hosted, but it is a geocoder only. It provides no map tiles and no routing. Running Nominatim alongside a tile server and a routing engine requires configuring and maintaining each piece independently, with separate data pipelines and separate update schedules.

Headway takes a different approach: a single project with a single build process produces artifacts that all the services consume. The HEADWAY_AREA variable selects the data set, and every service in the compose file reads from volumes populated by that one build.

The trade-off is flexibility. Running components separately means each can be upgraded or swapped independently. Valhalla, the routing engine Headway uses, is a mature project with its own release cycle and community. If a team already runs Nominatim and wants to add routing, grafting Valhalla directly onto their existing setup might be simpler than migrating to Headway's build pipeline. Headway is the better starting point when none of those components exist yet and the goal is to have everything running quickly.

Maintenance Record and License

The last push to the repository was on 2026-09-26. The repository is not archived. The Rust workspace targets stable dependency versions, with actix-web at 4.15.0, serde at 1.0.229, and clap at 4.6.6 as of the most recent Cargo.toml. The repository has no GitHub releases, so there is no formal versioning scheme documented; deployments pull from Docker image tags published to ghcr.io/headwaymaps.

Headway is available under the Apache License, version 2.0. This is a permissive license that allows use, modification, and distribution, including in proprietary products, provided that the license notice is preserved. The README notes that the project welcomes pull requests for enhancements and bugfixes.

There is no published upgrade guide or migration documentation visible in the top-level repository entries. Teams running Headway in production should check whether new Docker image versions require a rebuild of area data files before updating, since the format of those files may change across versions.

Editorial conclusion

Headway is the right choice for teams that need private map infrastructure and are comfortable running Docker Compose on amd64 hardware. It is not the right choice for anyone who needs functional transit directions today, those who must support ARM or Windows builds, or projects that cannot dedicate 50 to 100 GB of disk during the data generation phase. Before deploying, confirm that BUILD.md documents a build path that fits your target area size and that the 4 GB runtime memory budget is within your server constraints.

Frequently asked questions

What operating systems does Headway support?

The README confirms that Headway works on amd64 machines running Linux and macOS. There is no documented support for ARM-based machines or Windows hosts.

Does Headway support transit directions?

Transit directions are listed as a work-in-progress in the README. The repository contains transit-related services (transit-zoner and gtfout) and a dedicated docker-compose-with-transit.yaml, but the feature is not described as ready for production use.

How do you choose which city or region to load in Headway?

The HEADWAY_AREA environment variable selects the area. The project provides over 200 predefined areas; the build process generates the data files for the chosen area, and the Docker Compose file reads configuration from builds/${HEADWAY_AREA}/.env.

Official sources

  1. headwaymaps/headway on GitHub
  2. Issues
  3. License: Apache-2.0
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/headwaymaps-headway.svg)](https://hysenlabs.com/projects/headwaymaps-headway)