Introduction #
In this section, you’ll learn how to style your own base map. You’ll begin with a default template style as your starting point. From there, you’ll use a visual editor to customize the map’s appearance — including colors, filters, and layers — to suit your preferences.
To do this, we’ll be using Maputnik, an open-source visual style editor, throughout this guide.
If you’re new to styling maps, we recommend starting with the more beginner-friendly Maputnik documentation, which offers a visual and accessible introduction. For technical details, refer to the MapLibre Style Specification — a comprehensive reference intended mainly for developers.
Start from Existing Style #
The easiest way to begin styling your own map is by starting from a template that’s already been created. You can then simply adjust the colors and other visual elements as needed.
To do this:
- Open the Maputnik editor.
- Click “Open”.
- Under “Load from URL” paste the following style URL:
https://api.situm.com/uploads/mapstyles/default/light-v10.json

This will load the template style into the editor. However, at first, you won’t see anything on the map — don’t worry, that’s expected!
The reason is that this style requires authentication to display properly. You’ll need to add an access token that you can generate using your API key (Learn how to generate an access token). In order to add the access token you’ll have to do as follows:
- In Maputnik, go to the “Data Sources” section.
- Find the source named “protomaps” and look for the field labeled “TileJSON URL”.
- Add this to the end of the URL:
?access_token=YOUR_ACCESS_TOKEN(ReplaceYOUR_ACCESS_TOKENwith the actual token you generated.)

Once you’ve added the token, the map should load correctly — and you’ll be ready to start editing styles!
Understanding Map Styling #
Now that you’ve loaded a style into Maputnik, you can edit the visual appearance of the map by adjusting its layers. This guide focuses on visual styling only—changing how features like roads, parks, and buildings look on the map.
If you’re just getting started, we recommend focusing on:
- Adjusting colors, sizes, and labels
- Hiding or showing specific features
- Reordering visual elements for clarity
Once you’re comfortable, you can explore advanced options like:
- Adding new data sources
- Customizing fonts and icons
- Styling based on zoom levels or feature properties
What are Layers? #
A layer defines how a particular group of map features should appear—such as roads, buildings, water, or labels. For example, one layer might draw all motorways as thick red lines, while another shows city names in bold text.
Note that layers don’t contain data directly—they reference a source (like a vector tileset) and apply styling rules to it.
When you open a style, the list of layers appears in the left-hand panel. Layers are drawn in order from bottom to top— a layer on the bottom is painted above all the layers before it on the list. For example, labels typically appear above buildings.

When you click on a layer this opens its settings in the right panel. There, you’ll see its main sections:
- Layer Information: includes basic details about the layer, like its name, what kind of shapes it draws (lines, areas, or icons), where its data comes from, and the zoom levels when it appears on the map.
- Filter: defines which features this layer applies to. For example a “roads layer” might only show highways, not smaller streets.
- Layout: controls how features are placed or whether they’re visible. For example, you can toggle whether road names are shown, or change text size.
- Paint: controls visual appearance like colors, opacity, and line width, etc. For example, you can change water bodies to a different shade of blue, or make them semi-transparent.
Creating New Layers #
To better understand how styles work in Maputnik, we’ll start with an example using a layer that styles roads. We’ll begin by focusing mainly on how to style the roads as lines, and then briefly cover how to style the labels for road names. This is a great example because it includes both visual geometry and text elements.
Styling Road Lines: A Line Layer Example #
For this line layer example, we’ll create a new layer from scratch to properly exemplify the whole editing process. Then we’ll work on configuring the properties of that layer.
To create a new layer in Maputnik:
- In the left panel, click the “Add layer” button at the top of the layers list
- This will open a dialog where you can configure your new layer. For the roads example, replicate the configuration exactly as shown in the image on the right. We’ll explain the meaning of each field in detail later.


After clicking “Add layer”, the new layer will appear at the bottom of the layer list in the left-hand panel. Keep in mind that layers are rendered in the order they appear—those lower in the list are drawn on top of those above them. You may want to move the new layer up to adjust its rendering order.

1. Layer Information #
To start styling any layer, we first need to fill out the Layer Information. This section contains the basic identifying details of the layer and tells the renderer what kind of features it will draw and where to get them from.
- ID: A unique name for the layer used internally to identify it.
- Type: Specifies the type of geometry the layer will render. For example, in the case of roads, using the type
"line"tells Maputnik to draw linear features. Other common values include"fill"for areas like parks or lakes, and"symbol"for icons and text labels (which we’ll briefly cover later on). - Source: The dataset or tileset from which the layer fetches its features. For now it will always be
"protomaps"(see the Start from Existing Style section to learn where datasets are defined).- Source-layer: Refers to the specific layer within the vector tileset that the style will use. In the case of roads, the source layer is
"roads", this contains linear transportation features designed for movement, including highways, streets, railways and piers from OpenStreetMap.
- Source-layer: Refers to the specific layer within the vector tileset that the style will use. In the case of roads, the source layer is
Keep in mind, the source layer name depends on the dataset you use—here, we’re using Protomaps’ data, but if you were working with Mapbox, for example, the source and layer names would be different (if you are curious you could also check out one of Mapbox’s datasets specification).
- Minzoom / Maxzoom: The zoom levels between which the layer is visible. This helps control map detail at different zooms.
For example, here’s how we could configure a layer to display minor roads, such as local streets or service roads.

This layer draws lines from the roads source-layer in the protomaps dataset (for reference on available layers within this dataset, see Basemap Layers), and it appears between zoom levels 0 and 24. The type set to "line" tells Maputnik to render linear features. In the image above, you can see that all lines are currently shown in black. This is the default appearance, since we haven’t yet applied any filtering or custom styling.
2. Filter #
Once this is set up, we can control which features from that data source the layer should apply to by using the Filter section. You can filter using feature properties (like road type or name), but also metadata like geometry type or feature ID.
For example, to style only minor roads, we can apply a filter based on the kind property. (To see which values are available for this property in your specific source layer, refer to Basemap Layers.).
Inspect the Map #
To help decide which specific values to filter by, you can explore the actual data on the map using Maputnik’s Inspect view. Go to the top toolbar and under “View” switch the view from Map to Inspect. Then, hover over any feature on the map to see its data properties.

Keep in mind that multiple features can exist under your cursor at once. When that happens, Maputnik will group them by their source layer. In the example shown above, the popup displays three features: the first one comes from the roads source layer—which is relevant for the layer we’re currently styling—while the other two come from the landuse and earth layers, which we can ignore in this context.
Apply your Filters #
Let’s go ahead and apply a filter for "minor_road" on our layer. In the image below, with the Inspect view enabled, you’ll notice that the features highlighted in orange are the ones currently selected by the filter—they represent the features that this layer will now style.

You can add multiple filters using the UI, or switch to Expression mode to write custom MapLibre expressions. However, since expressions can be complex and hard to read we recommend sticking with the basic UI filtering options for now.
Using Expressions: For more dynamic styling, you can click the “Convert to expression” button next to any property. This lets you define rules that adapt based on zoom levels, feature properties, or other conditions. For an example, see the section “Advanced Styling: Exploring Functions and Expressions.”
In the image below, after adding another filter, you’ll notice significantly fewer lines—indicating that we’re now only styling minor roads classified as residential.

3. Paint #
Once we’ve filtered the features we want to target we can start adjusting how those features look using the Paint section. These properties control the visual appearance of the features: their color, opacity, line width, and more. Since we’re styling a line layer, we have access to a number of line-specific options.
For example:
- To change the road color, set the
line-colorto a new value like#9AA8C5. This gives the roads a light-blue tone. - To make them less visually dominant, reduce the
line-opacityto0.8. - To emphasize the lines slightly more, you could increase the
line-widthto5.

You’ll see the changes reflected instantly on the map. The image above shows how the residential minor roads look after tweaking these paint properties.
4. Layout #
Next on we’ll focus on the Layout section, which controls how features are placed or rendered, rather than how they look. For line layers like this one, layout options are fairly limited. These options can be useful in some cases, but they don’t offer much room for creativity.
For line layers like roads, layout options are somewhat limited. While they don’t allow for much visual creativity, they can still influence the overall appearance in subtle but important ways.
One example is the line-join property. This setting controls how the corners (or joins) between line segments are rendered. You can choose between:
miter(sharp corners),bevel(flattened corners),- or
round(smooth, curved joins).
Each option slightly changes the look and feel of how connected road segments appear — see the image below for a visual example.

Styling Road Labels: A Symbol Layer Example #
Now let’s create a separate layer for road labels using a symbol layer, which is used to render icons or text—such as road names. Unlike the line layer we styled earlier, symbol layers have their own set of configuration options, especially in the Layout section where text-related properties are defined.
We’ll keep this section brief and focus on some key aspects of symbol layers. To start, create a new layer similar to the “roads-minor” layer. Most settings will remain the same, but be sure to update the layer ID to something unique and descriptive, and set the layer type to symbol, since this layer will render text instead of lines.

1. Layer Information #
For the symbol layer, we’ll use the same data source but configure it differently:
- ID: A unique name for the label layer (in our case: “road-labels”).
- Type: Set to “symbol” to render text labels.
- Source: Still “protomaps” as we’re using the same dataset.
- Source-layer: Still “roads” as we want to label the same roads we styled.
2. Layout #
For symbol layers, the Layout section offers many more options, especially for text styling. We will adjust the relevant options under General layout properties and Text layout properties:
- To display the road name as a label, set the
text-fieldproperty to{name}. This tells the style to use thenameproperty from each feature as the label text shown on the map. - You can set
text-placementtopoint, so the text appears at a single location instead of being repeated along the shape of the road. - To ensure road names aren’t upside down, set
rotation-alignmenttomap, so the labels rotate naturally with the map’s orientation.

In the image above, we adjusted the relevant options under General layout properties and Text layout properties. Just like with Paint properties, any changes you make here are reflected immediately on the map. If you explore this type of layer further, you’ll notice that symbol layers include several additional sections—because they can display both text and icons. That’s why the layout settings are split into Text layout and Icon layout, and the same applies to the Paint section, which has separate controls for text and icons.
For a complete overview of all styling options across different layer types, refer to the MapLibre Layer Specification. The most commonly used types—"fill", "line", "symbol", and "fill-extrusion"—each offer their own set of configurable properties.
Advanced Styling: Exploring Functions and Expressions #
Now that you’ve got the basics down, let’s take a peek at what you can do with functions and more complex expressions in your styles.
Functions #
Imagine you want your roads to gradually change color as you zoom in and out. Maputnik provides controls that let you apply predefined functions to style properties. One of these is the interpolate function, which we’ll use to adjust road colors and widths dynamically based on the zoom level.
To apply a zoom-based function, click “Convert property into zoom function” (see images below). This will enable zoom-based styling. From there, you can customize the values and adjust the number of stops to fine-tune the interpolation to your liking.


For example, you could have roads fade from black at a city-wide view to red as you zoom in. This creates a subtle visual effect that adds depth and helps users focus on details only when they’re most relevant.


Expressions #
You can also combine multiple conditions within a single expression. To view a property as an expression, click the “Convert to expression” button. This will switch from the visual UI controls to the underlying MapLibre expression, giving you more flexibility and control over the styling logic.


The image below shows an example of how to use expressions: residential roads are styled in green, service roads in orange, and all other roads in a neutral gray.

This powerful syntax lets you customize your styles in countless ways. Let us take a closer look at the expression used in this example:
[
"interpolate",
["linear"],
["zoom"],
13,
["case",
["==", ["get", "kind_detail"], "residential"],
"green",
["==", ["get", "kind_detail"], "service"],
"orange",
"gray"
],
18,
["case",
["==", ["get", "kind_detail"], "residential"],
"cyan",
["==", ["get", "kind_detail"], "service"],
"red",
"black"
]
]
This expression controls the color of roads based on two things: the zoom level (how far in or out you are on the map) and the type of road.
"interpolate"means it will smoothly change colors as you zoom in or out."linear"means the change happens gradually and evenly between zoom levels.["zoom"]tells it to use the current zoom level as the input.
Now, there are two main zoom points here: 13 and 18. At zoom level 13:
- It checks the road type using
"kind_detail"(a property that says if a road is “residential”, “service”, etc.). - If the road is
"residential", the color will be green. - If the road is
"service", the color will be orange. - For all other road types, it will be gray.
While at zoom level 18:
- It again checks the road type
"kind_detail". - If
"residential", the color changes to cyan (a lighter blue-green). - If
"service", it changes to red. - All other roads become black.
Between zoom 13 and 18, the colors smoothly transition from the first set to the second set. So as you zoom in, the roads change color gradually based on their type.

As you can see, these expressions can quickly become complex and harder to read compared to the straightforward UI controls. That’s why we recommend using Maputnik’s UI tools whenever possible, especially if you’re just starting out. But once you’re comfortable, feel free to dive in and explore the full power of expressions and styling options.
Saving and loading your Base Map Style #
After you finish customizing your map style, it’s important to save your work so you can use it later or share it with others.
First, give your style a meaningful name. This helps you keep track of your different styles, especially if you create multiple versions. To do so, click on “Style Settings” in the top toolbar, then edit the “Name” field to your desired title.

Once your style is ready, export it as a JSON file. This file stores all the details needed to recreate your style, either in Maputnik or in our Map Viewer. To export, click on “Export” in the top toolbar. A dialog will appear—simply click Save and choose the location on your local machine where you want to store the JSON file. There’s no need to fill in any access tokens in the dialog.

Suppose you have saved your style locally as “my_custom_style.json.” To import it into Maputnik, click on “Open” in the top toolbar (just like at the start of this guide). Instead of loading a style from a URL, select “Open Style” to load your style directly from the local file.

Once your style is saved, contact our support team for help with uploading it to the platform and using it in the Map Viewer.