Maps are a frequent resource in websites and applications. You may need to display a location on your site or allow people to interact with maps.
You need a service that provides the maps' metadata to integrate a map into your application, such as Google Maps or Felt. These services are typically offered through APIs that often have a free tier but will can also increase your costs drastically when the popularity of your application grows. Self-hosting is an alternative to using these third-party services.
In this article you will learn how to host your own maps service API at a fraction of the cost with Protomaps and Wasm Workers Server. We also showed this project in the Wasm I/O 2023 conference in Barcelona. In that talk we also introduced Wasm Workers Server main concepts. If you are interested, you can watch the recording on YouTube.
What is Protomaps?
From the Protomaps site:
Protomaps is a serverless system for planet-scale maps.
An alternative to map APIs at 1% the cost, via single static files on your own cloud storage.
The Protomaps project is composed of two parts:
- The PMtiles open specification is an efficient format to store map metadata in a single file. You can store any map into a single
.pmtilesfile and query the information.
- An open-source set of libraries to interact with this format: you can read, query, write and convert others formats to
The combination of an efficient single-file format and the available libraries make this project suitable for hosting as a serverless app. With Wasm Workers Server, you can run it in 3 commands.
Running Protomaps with Wasm Workers Server
To run Protomaps with Wasm Workers Server, follow these steps:
Download Wasm Workers Server:
curl -fsSL https://workers.wasmlabs.dev/install | bash
Clone the project repository and change your directory to
git clone --depth=1 https://github.com/vmware-labs/wasm-workers-server && \
Setup and run
wwswith Make (using a pre-downloaded map in
Access your map at http://localhost:8080
You can create a different map or download the planet-scale example map (2.62Gb). Just make sure that the
MAP_FILE variable in
[z]/[x]/[y]/index.toml below points to the correct file name. You can use the
make planet command to download that map and run
The site you see comes from the
public/index.html file. It uses the Leaflet and the Protomaps client libraries. We included it to showcase the final result, although you can remove the file and use only the API.
How does it work?
All the API requests from the map client access the
/Z/X/Y URL, where X, Y, and Z represent the location. The
./[z]/[x]/[y]/index.py file is the worker that processes the request and returns the map metadata.
To mount the folders, we are using the Mount folders feature from Wasm Workers Server v1.1.0. This feature allows you to mount folders in the workers' configuration.
This is the
[z]/[x]/[y]/index.toml configuration file:
version = "1"
MAP_FILE = "map"
from = "../../../_libs"
to = "/src/libs"
from = "../../../_maps"
to = "/src/maps"
As you can see, the worker also mounts the
_libs folder to access the shared libraries.
Read more information about all the Wasm Workers Server features in the documentation.
Hosting your maps server
You can host Wasm Workers Server in many different ways. You only need the
wws server and the project files. You can reproduce the same installation steps in any remote server you manage. For example, on Digital Ocean, Amazon Web Services, or a traditional dedicated server.
For convenience, we also added a
Dockerfile to the project. It's a minimal container that only includes
wws and the project files. By default, the Dockerfile downloads the Protomaps planet-scale example map, so you may want to edit it if you need a different map.
Maps for everyone
Thanks to Protomaps, now you can run your serverless maps service API. With Wasm Workers Server, you have the flexibility to run it anywhere. Just add the map you need and deploy it to your preferred platform.