A modern web client for the BlueSky Air Traffic Management (ATM) simulator. WebATM provides a standalone web interface with interactive aircraft visualization to control air traffic management simulations from the Web.
- Intuitive Aircraft Interaction: Single-click to fly to any aircraft, double-click to activate follow mode
- Customizable Aircraft Display: Toggle visibility of labels, icons, trails, routes, and shapes
- Aircraft Type in Labels & Info Panel: View aircraft type directly on map labels and in the aircraft information panel
- Flexible Aircraft Styling: Choose from chevron, drone, triangle, or aircraft icon styles and customise colors
- 3D Aircraft Visualization: Render aircraft as 3D models (A320, A350, A380, drones, and more).
- Smart Command Input: Tab completion for BlueSky commands with autosuggestion
- Command Palette: Quickly browse and search available BlueSky stack commands from the console
- Console Map Picker: Select coordinates directly from the map when entering commands
- Scenario File Management: Upload, organize, and run BlueSky scenario (
.scn) files and folders straight from the web interface - Flexible Map Projection: Switch between Web Mercator and 3D globe view powered by MapLibre GL
- Custom Map Sources: Configure custom tile sources to personalize your base map layer
- Configurable Scenario Path: Set your BlueSky scenario directory from the settings modal
- Multi-Node Simulation: Spawn and manage multiple parallel simulation nodes from one interface
- BlueSky Integration: Seamless connection to BlueSky ATM simulator servers
- Modern TypeScript Architecture: Fully type-safe, maintainable client-side codebase
WebATM ships in two flavors, both open source and published to GHCR:
webatm(standalone) — the web client only. Connects to a BlueSky server you run yourself, on the docker host or elsewhere on the network. This is the default everywhere in this README.webatm-integrated— bundles BlueSky inside the same container and adds in-app Start / Stop / Restart / Kill server controls plus a live server-log tab. File management auto-wires to BlueSky's working directory, so there's no base-path step. Useful if you want a single-container deployment with no separate BlueSky process to manage. See WebATM Integrated below for usage.
Looking for more advanced features? WebATM Pro includes everything in the open source version, plus additional capabilities:
- Custom Simulation Engine: Built on amvlab's custom simulator, controllable end-to-end from the WebATM interface
- Server Development Environment: Modify and develop simulation server code directly from the web interface
- Pro-Only Roadmap: In-browser scenario editor, simulation rewind, and client-side command validation
- Flexible Deployment: amvlab can provide managed hosting or deploy on your local network for full data sovereignty
Visit amvlab.eu for Pro Version
- Python 3.13 or higher
- Node.js 22+ and npm (for TypeScript development)
- BlueSky ATM simulator (amvlab fork recommended) or TUDelft-CNS-ATM/bluesky version 1.1.1
WebATM works best with the amvlab fork of BlueSky, but is also compatible with the latest BlueSky from TU Delft.
The quickest way to run WebATM is to use the provided docker-compose.yml to pull the prebuilt image from GHCR.
-
Download the compose file
wget https://raw.githubusercontent.com/amvlab/WebATM/main/docker-compose.yml
-
Start the stack
docker compose up -d
-
Access the web interface
Open your browser to: http://localhost:8082
-
View logs
docker compose logs -f webatm
By default the container connects to a BlueSky server on the Docker host via host.docker.internal. To enable the in-app file manager for scenarios, plugins, and settings, uncomment the volumes: block in docker-compose.yml and point it at your local BlueSky working directory.
Use this if you want to run WebATM directly from source without installing Node.js or building the frontend yourself. You still clone the repo for the Python source, then drop in two tarballs that contain the runtime assets that aren't checked into git: a small per-version code tarball and a larger static-asset tarball that changes rarely.
-
Clone the repository
git clone https://github.com/amvlab/WebATM cd WebATM -
Download and extract the prebuilt code tarball
Grab the latest
webatm-prebuilt-<version>.tar.gzfrom the Releases page and extract it from the repo root:tar -xzf ~/Downloads/webatm-prebuilt-<version>.tar.gz
This lands:
WebATM/static/dist/— prebuilt webpack bundlesWebATM/static/vendor/— third-party CSS/fonts (FontAwesome, MapLibre)
-
Download and extract the static-asset tarball
Grab the assets tarball pinned by
.assets-versionin this repo (e.g.webatm-assets-v1.tar.gz) from the Releases page and extract it from the repo root:tar -xzf ~/Downloads/webatm-assets-<tag>.tar.gz
This lands:
WebATM/static/tiles/— offline basemap (world.pmtiles) and navigation overlay (navdata.pmtiles)WebATM/static/glyphs/— map fontsWebATM/static/navdata/— navigation database
This bundle changes rarely (only when tiles, fonts, or navdata roll), so a single download usually carries across many code releases.
-
Install Python dependencies
Dependencies are managed with uv from
pyproject.tomland the pinneduv.lock:uv sync
-
Start the application
uv run script/run_webatm.sh
-
Access the web interface
Open your browser to: http://localhost:8082
-
(Optional) Enable the offline basemap
The assets tarball already includes
WebATM/static/tiles/world.pmtiles. To use it, open Settings → Map Display Configuration → Offline (Local PMTiles) in the web UI.
-
Clone the repository
git clone https://github.com/amvlab/WebATM cd WebATM -
Install Python dependencies
Dependencies are managed with uv from
pyproject.tomland the pinneduv.lock:uv sync
-
Build frontend assets
script/build_frontend.sh
-
Start the application
uv run script/run_webatm.sh
-
Access the web interface
Open your browser to: http://localhost:8082
The integrated image bundles BlueSky inside the same container and exposes its lifecycle (Start / Stop / Restart / Kill) plus a live server-log tab from the web UI. File management is pre-wired to BlueSky's working directory — no base-path configuration needed.
The image is published alongside the standalone one on every release tag at ghcr.io/amvlab/webatm-integrated. To run it, uncomment the webatm-integrated service in docker-compose.yml and bring it up:
docker compose up -d webatm-integratedOpen http://localhost:8082 and use the Start button in the Server Log tab (or in Settings → BlueSky Server Controls) to launch BlueSky inside the container.
The integrated image pulls BlueSky from amvlab/bluesky on its main branch by default. To build against your own fork, branch, or tag, edit the bluesky-simulator dependency line in WebATM-integrated/pyproject.toml:
dependencies = [
"bluesky-simulator[headless] @ git+https://github.com/<your-org>/bluesky.git@<branch-or-tag>",
]Then build and run the image locally:
docker build -f Dockerfile.integrated -t webatm-integrated:dev .
docker run --rm -p 8082:8082 webatm-integrated:devYour fork must keep BlueSky's pip distribution name (bluesky-simulator) and the bluesky = bluesky.__main__:main console script entry point — the container spawns the server as bluesky --headless.
| Variable | Description | Default |
|---|---|---|
WEB_HOST |
Web server bind address | localhost |
WEB_PORT |
Web server port | 8082 |
BLUESKY_SERVER_HOST |
BlueSky server hostname/IP | localhost |
WebATM connects to BlueSky servers using the standard BlueSky network ports (11000 and 11001).
Important: These ports are currently not configurable. Ensure your BlueSky server runs with default port configuration.
WebATM can render the map from a local PMTiles archive instead of an online tile provider — useful for air-gapped deployments or unreliable networks. The offline MapLibre styles live in WebATM/static/map/ (offline-style.json and offline-style-light.json) and expect a tile archive at WebATM/static/tiles/world.pmtiles.
The prebuilt release tarball (Option 1) already ships world.pmtiles. If you built from source, generate your own archive as follows.
# macOS / Linux with Go installed:
go install github.com/protomaps/go-pmtiles@latest
export PATH="$HOME/go/bin:$PATH"
ln -sf "$HOME/go/bin/go-pmtiles" "$HOME/go/bin/pmtiles" # optional aliasOr download a prebuilt binary from the go-pmtiles releases page.
Pick a daily planet build date from maps.protomaps.com/builds (e.g. 20260415) and extract only the zoom levels you need. Zoom 0–8 worldwide is roughly 400 MB – 1.2 GB and covers coastlines, major roads, and country/state boundaries — enough context for ATM visualization:
mkdir -p WebATM/static/tiles
pmtiles extract \
https://build.protomaps.com/<YYYYMMDD>.pmtiles \
WebATM/static/tiles/world.pmtiles \
--maxzoom=8To add street-level detail for a specific region, run a second extract with a bounding box and a higher max zoom, then add it as an extra source in WebATM/static/map/offline-style.json:
pmtiles extract \
https://build.protomaps.com/<YYYYMMDD>.pmtiles \
WebATM/static/tiles/region.pmtiles \
--bbox=<minLon,minLat,maxLon,maxLat> \
--maxzoom=12pmtiles show WebATM/static/tiles/world.pmtilesThen enable it in the UI via Settings → Map Display Configuration → Offline (Local PMTiles).
The
*.pmtilesarchives can grow to hundreds of MB or more, so distribute them via GitHub releases rather than committing them to the repository.
WebATM can also render an offline navdata overlay (airports, heliports, runways, taxiways, and waypoints) with a search box backed by a local SQLite index. This is built from X-Plane apt.dat/earth_fix.dat plus OurAirports and produces WebATM/static/tiles/navdata.pmtiles and WebATM/static/navdata/navdata.sqlite. See script/README.md for the build pipeline and tuning options.
Python:
# Linting with Ruff
ruff check .
# Format code
ruff format .TypeScript:
cd frontend/
npm run type-checkPython tests are driven by pytest and managed through uv. A bare run collects
both suites (the core webatm package and the optional webatm_integrated
package); use the core/integrated markers to pick a subset:
uv run pytest # everything (core + integrated)
uv run pytest -m core # core webatm package only
uv run pytest -m integrated # optional webatm_integrated package onlyCopyright (c) 2025 amvlab
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE file for details.
This software incorporates BlueSky - The Open Air Traffic Simulator technology developed by TU Delft (Delft University of Technology). We acknowledge and thank TU Delft for their contribution to the open aviation simulation community.
The offline basemap is built from Protomaps planet builds distributed as PMTiles, derived from OpenStreetMap data (© OpenStreetMap contributors, ODbL). The airport, runway, taxiway, and waypoint overlay is built from X-Plane navigation data (apt.dat and earth_fix.dat) released by Laminar Research under the GNU GPL, with airport importance ranking and IATA codes sourced from OurAirports (public domain).
For inquiries and support, please contact amvlab.