How to use MapLibre GL JS
Kumpee Teeravech
Geoinformatics Program (GI)
Faculty of Computer Science and Information Technology (CSIT)
Rambhai Barni Rajabhat University (RBRU)
2025-03-01
Many of my projects require interactive web mapping applications, which play a crucial role in visualizing spatial data
and enhancing user engagement. There are several JavaScript libraries available for rendering maps in web browsers, each
with its own strengths and use cases. Some of the most widely used options include:
Among these, I have been using OpenLayers for nearly a decade and have grown to appreciate its flexibility and powerful
features. It has been my go-to library for handling various mapping needs. However, for some of my recent projects, I
need to transition to MapLibre GL JS, which provides enhanced support for vector tiles and improved performance with
WebGL rendering.
To familiarize myself with this shift, I decided to write this article as a quick review of the setup
process and basic configuration of MapLibre GL JS. This guide aims to help others who, like me, are making the
transition and need a straightforward starting point.
About the library
MapLibre GL JS is an open-source JavaScript library
for rendering interactive maps using WebGL. It is a community-driven fork of Mapbox GL JS (v1)
that allows developers to create high-performance, customizable, and vector-tile-based
maps without requiring a Mapbox subscription. The library supports various map styles,
dynamic data visualization, and user interactions such as zooming, panning, and rotating.
At its core, MapLibre GL JS is built on WebGL, a low-level JavaScript API that enables direct access to the GPU for
rendering both 2D and 3D graphics efficiently. Unlike traditional raster-based mapping libraries such as Google Maps or
Leaflet, which rely on pre-rendered image tiles, MapLibre GL JS dynamically renders vector tiles in real time. This
hardware-accelerated approach enables smooth transitions, rapid updates, and interactive features that enhance the
overall user experience.
How MapLibre GL JS Renders Maps
The rendering process in MapLibre GL JS follows several key steps to ensure efficient and accurate visualization of
geographic data. The first step is tile loading and parsing. Vector tiles are fetched from a tile server and then parsed
into different geometries, including points, lines, polygons, and labels. The raw geographic data is converted into
GPU-friendly formats such as vertex buffers, index buffers, and attribute buffers, which WebGL can efficiently process.
Once the data is prepared, MapLibre GL JS utilizes
GLSL
(OpenGL Shading Language) to define vertex shaders and fragment
shaders that execute rendering tasks on the GPU. Different shader programs handle various map elements. Fill layers are
used for polygons, such as landmasses and water bodies. Line layers render roads and boundaries, while symbol layers are
responsible for text labels and icons. Since WebGL operates in Normalized Device Coordinates (NDC) ranging from -1 to 1,
while map coordinates are defined in longitude and latitude, a projection matrix is required to convert geographic
coordinates into screen-space coordinates. MapLibre GL JS typically uses the Web Mercator projection, ensuring
consistency across different zoom levels and devices.
Once the geometries and textures are ready, WebGL draw calls, such as gl.drawArrays or gl.drawElements, execute the
rendering. Map features are drawn back to front, following a layer hierarchy based on z-index. The depth buffer and
stencil buffer in WebGL help maintain proper layering and occlusion of features, ensuring that overlapping elements are
displayed correctly.
How to install
There are several ways to install MapLibre GL JS, including using NPM, configuring Content Security Policy (CSP)
directives, or linking to a Content Delivery Network (CDN). For simplicity and ease of use, I will use the CDN method,
specifically the distribution from
unpkg.com.
This approach allows you to quickly integrate MapLibre GL JS into your web
application without additional dependencies or build configurations.
To add the library to your web page, include the following lines in the <head> section of your HTML document. This will load both the JavaScript library and the required CSS for proper styling
and functionality of the interactive map.
<script src="https://unpkg.com/maplibre-gl@^5.1.1/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@^5.1.1/dist/maplibre-gl.css" rel="stylesheet" />
Next, create a new map object to display the map. This involves initializing MapLibre GL JS and specifying the necessary
configuration parameters. The following code will use an HTML element with the ID "map" as the target canvas for
rendering the map. It will also apply a map style from https://demotiles.maplibre.org/style.json, which provides a basic
tile layer for visualization. The map's initial view will be centered at the origin of the geographic coordinate system (0, 0)
and the zoom level will be set to 2, providing a global overview.
var map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [0, 0],
zoom: 2
});
Adding markers
A marker can be added to the map using the Marker object in MapLibre GL JS. The default coordinates of the marker are
specified using the setLngLat method, which takes a longitude-latitude pair as input. After defining the marker’s
position, the addTo method is called on the Marker object to attach it to the parent map object,
var marker = new maplibregl.Marker()
.setLngLat([100.523186, 13.736717]) // Longitude, Latitude
.addTo(map); // Add to map
Adding popup label
The following methods can be added to the Marker object to adds a popup label that appears when the user clicks on the
marker. This is achieved by creating a Popup object and setting its content using the setHTML method. The popup is then
associated with the marker using the
setPopup method, allowing it to display when the marker is clicked. The offset parameter is used to specify the desired
distance between the marker and the popup label, ensuring that the
label appears at an appropriate position relative to the marker.
.setPopup(new maplibregl.Popup({ offset: 25 }) // Add a popup with some text
.setText("Hello from Bangkok!"))
Setting map center and zoom level
The center of the map can be adjusted dynamically using the setCenter method, which takes a longitude-latitude
coordinate pair as input. Similarly, the zoom level can be configured using the setZoom method, which determines how close or far the view
appears. A higher zoom value provides a more detailed, close-up view, while a lower zoom value offers a broader, global
perspective
map.setCenter([101.0, 14.0]); // Moves the map to a new location
map.setZoom(3); // Zoom into the city
Set background map style
The default map style provided by MapLibre GL JS uses the style URL from https://demotiles.maplibre.org/style.json.
However, there are several alternative map styles available from different providers, each offering unique visual
designs and features suited for various applications. Some alternative map style URLs are listed below,
but it's important to note that certain map styles require an API key for access.
The below code changes map style by using the setStyle method.
map.setStyle('https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json');
Result
After executing the above code, the map is successfully displayed with its center set to Chanthaburi, a province located
in the eastern part of Thailand. The map uses the default map style, providing a clear and interactive view of the area.
A marker is placed at the Chanthaburi, and when clicked, a popup label appears, displaying the text "Chanthaburi!".
Conclusion
This article provides a quick review and covers the basic usage of MapLibre GL JS. I found the setup process to be
straightforward and easy, making it a great choice for developers who need to quickly integrate interactive maps into
their web applications.
However, I have not yet explored some of its additional features, such as adding polygons and working with raster tile
maps. Another aspect I have yet to test is its support for interactive modifications, particularly real-time updates to
polyline vertex coordinates based on keyboard and mouse inputs. Many of my applications rely on these interactive
features, and I have already developed a custom implementation on top of OpenLayers to handle such requirements. It
would be interesting to evaluate whether MapLibre GL JS can offer similar flexibility or if additional workarounds would
be needed for these advanced interactions.
The English in this article has been revised using ChatGPS-4o.