# Style file format

Last updated:

<!-- -->

October 13, 2026

<!-- -->

\| 16 minutes read

<br />

<br />

For developers: the JSON file that **Style (JSON)** in the Download dialog gives you, and the JSON Schema that checks it. Your app does not need this file; it loads the `.style` file (see [Download and use in your app](/docs/guides/map-studio/getting-started/download-and-use.md)). Use the JSON to keep a copy of a style, upload it to the portal, or write or check a style with your own tools.

To have an AI assistant write a style, give it the [Studio llms.txt](/docs/guides/map-studio/llms.txt), which lists the four files it needs: this page, [Map data sources](/docs/guides/map-studio/reference/map-data-sources.md), the [layer types reference](/docs/guides/map-studio/reference/layer-types-reference.md) and the [JSON Schema](/docs/schemas/engine-style.schema.json). Check what it writes with the schema (see [The JSON Schema](#the-json-schema)), then upload it to the portal and open it in Studio (see [Start from a style file](/docs/guides/map-studio/getting-started/create-a-style.md#start-from-a-style-file)). An assistant cannot write a font: leave `fonts_section` out, and add the font in Studio afterwards (see [Fonts](#fonts)).

## Coming from other map style formats[​](#coming-from-other-map-style-formats "Direct link to Coming from other map style formats")

The format is not the JSON style format that other web map libraries use. If you, or an AI assistant, have written styles in that format, these are the differences that matter:

| In other map style formats                   | In a Magic Lane style file                                                                                                                    |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `layers` at the top of the file              | Layers sit in `map_schemes_section.map_schemes[0].definition.layers`.                                                                         |
| `"source-layer": "water"` names the data     | The layer's `type` and `sourcedata_id` together name the data. See [Map data sources](/docs/guides/map-studio/reference/map-data-sources.md). |
| Expressions such as `["interpolate", ...]`   | Every paint property is a stop list, even a constant. See [Paint values](#paint-values).                                                      |
| Colours as `"#ff8800"` or `rgba()`           | Colours are integers. See [Colours](#colours).                                                                                                |
| The first layer is drawn at the bottom       | The first layer is drawn **on top**; `background` is the last layer.                                                                          |
| `"id": "water"` names the layer              | `id` is a number that goes down from layer to layer and ends at 1; the name goes in `COMMENT`.                                                |
| Zoom 0 to 22                                 | Zoom 0 to 17.                                                                                                                                 |
| `"text-field": "{name}"`                     | Layers on map data draw their names by themselves; `label_text` is for your own data. See [Text](#text).                                      |
| `"filter": ["==", ...]`                      | A filter object. See [Filters](#filters).                                                                                                     |
| A sprite sheet                               | Images sit inside the file, in `icons_section`. See [Images](#images).                                                                        |
| `text-font` on each layer, with a glyphs URL | One font for the whole style, as font files inside the file, in `fonts_section`. See [Fonts](#fonts).                                         |

## The file[​](#the-file "Direct link to The file")

A style file is one JSON object with three sections, and a fourth when the style has its own font:

| Key                   | What it holds                                                                                                                             |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `sources_list`        | `{ "sources": [...] }`. Usually empty: layers use built-in sources. The external satellite source, `satelliteExternal`, is declared here. |
| `map_schemes_section` | `{ "COMMENT": "...", "map_schemes": [ scheme ] }`, with exactly one scheme.                                                               |
| `icons_section`       | `{ "COMMENT": "...", "icons": [ ... ] }`, the style's images. See [Images](#images).                                                      |
| `fonts_section`       | Optional. `{ "regular": "data:font/ttf;base64,...", ... }`, the style's font. See [Fonts](#fonts).                                        |

The scheme:

| Key              | What it holds                                                                                                                                   |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`             | Always `1`.                                                                                                                                     |
| `name`           | The style's name.                                                                                                                               |
| `groups_section` | `{ "groups": [ { "id", "name", "collapsed"?, "parent_id"? } ] }`, the groups of the layer list. `parent_id` names the parent of a nested group. |
| `definition`     | `{ "layers": [ layer, ... ] }`. The first layer is drawn last, on top.                                                                          |

### Drawing order[​](#drawing-order "Direct link to Drawing order")

The order of `definition.layers` is the drawing order: the first layer is drawn on top, the last at the bottom. The official templates use this order, from top to bottom:

1. `atmosphere`, if the style has one, then POIs, road names, one-way arrows and road shields
2. City, area, country and water labels
3. The layers an app draws at run time: routes, traffic, drawings
4. Borders, then roads
5. Buildings
6. Lines that are not roads (rail, runways, narrow water lines), then areas: lakes and rivers (Water) above parks and other land use
7. Island, Water Sea and Land
8. `background`, always last. The templates give it the water colour.

### A layer[​](#a-layer "Direct link to A layer")

| Key                  | Required | What it holds                                                                                                                                                                                                                                                                   |
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `COMMENT`            | yes      | The layer's name.                                                                                                                                                                                                                                                               |
| `id`                 | yes      | A number in drawing order: the first layer has the highest `id`, the last has `1`, and each `id` is lower than the one before. Gaps are allowed; the official templates have them.                                                                                              |
| `type`               | yes      | The layer type, such as `polygon`, `line`, `symbol`, `street` or `areaname`. See the [layer types reference](/docs/guides/map-studio/reference/layer-types-reference.md).                                                                                                       |
| `source`             | no       | A built-in source: `map`, `overlay`, `satellite`, `satelliteExternal`, `elevation`, `weather` (wind) or `contourpolyline` (contour lines).                                                                                                                                      |
| `sourcedata_id`      | no       | The data the layer draws: a public data source's number, or the tileset number of one of your data sources. The same number means different data in different layer types; see [Map data sources](/docs/guides/map-studio/reference/map-data-sources.md). One number per layer. |
| `minzoom`, `maxzoom` | no       | The zoom range the layer is drawn in, 0 to 17.                                                                                                                                                                                                                                  |
| `group_id`           | no       | The `id` of the layer's group.                                                                                                                                                                                                                                                  |
| `filter`             | no       | Which features are drawn. See [Filters](#filters).                                                                                                                                                                                                                              |
| `label_text`         | no       | The text a symbol layer draws. See [Text](#text).                                                                                                                                                                                                                               |
| `metaCategoryID`     | no       | The point-of-interest category a POI layer draws; the engine draws that category's icon.                                                                                                                                                                                        |
| `contour_interval`   | no       | The interval between lines, on contour layers.                                                                                                                                                                                                                                  |
| `isTemplate`         | no       | `1` on layers an app draws at run time (routes, traffic). Leave it out on other layers.                                                                                                                                                                                         |
| `paint`              | yes      | The paint properties. See [Paint values](#paint-values).                                                                                                                                                                                                                        |

### Paint values[​](#paint-values "Direct link to Paint values")

Every paint property is a stop list, even when it does not change with zoom:

```json
"line-width": {
  "line_width_stops": {
    "line_width_stop": [
      { "level_id": 5, "width": 0.5 },
      { "level_id": 10, "width": 1 },
      { "level_id": 13, "width": 1.75 }
    ],
    "easing_type": 1
  }
}

```

These are the first three stops of the Residential street line in Basic 1.

Text sizes and icon sizes are millimetres on screen. Line widths are not screen units: the map engine scales them with the camera height, so start from the values in the official templates. A border width (`line-outline-width`) is added on each side of the line.

`level_id` is the zoom of the stop, 0 to 17; a constant is a single stop. `easing_type` sets how the value moves between stops (see [Easings](#easings)). The one exception is `3dMesh` (`0` for 2D, `1` for 3D), written as a bare number under `paint`.

Colours are integers; see [Colours](#colours).

Each property has its own wrapper, stop array and value key:

| Property                                                                                                                                  | Wrapper                                                             | Stop array                                                       | Value key     |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------- |
| `fill-color`, `fill-outline-color`, `line-inner-color`, `line-outer-color`, `text-color`, `text-outline-color`, `background-symbol-color` | `color_stops`                                                       | `color_stop`                                                     | `color`       |
| `fill-opacity`, `fill-outline-opacity`                                                                                                    | `opacity_stops`                                                     | `opacity_stop`                                                   | `opacity`     |
| `line-width`, `line-outline-width`                                                                                                        | `line_width_stops`                                                  | `line_width_stop`                                                | `width`       |
| `line-blur`                                                                                                                               | `line_blur_stops`                                                   | `line_blur_stop`                                                 | `blur`        |
| `text-size`, `text-outline-size`                                                                                                          | `text_size_stops`                                                   | `text_size_stop`                                                 | `size`        |
| `text-padding`                                                                                                                            | `text_padding_stops`                                                | `text_padding_stop`                                              | `size`        |
| `text-max-width`                                                                                                                          | `text_max_width_stops`                                              | `text_max_width_stop`                                            | `size`        |
| `text-row-height`                                                                                                                         | `text_row_height_stops`                                             | `text_row_height_stop`                                           | `size`        |
| `icon-size`                                                                                                                               | `icon_size_stops`                                                   | `icon_size_stop`                                                 | `size`        |
| `icon-padding`                                                                                                                            | `icon_padding_stops`                                                | `icon_padding_stop`                                              | `size`        |
| `icon`                                                                                                                                    | `icon_stops`                                                        | `icon_stop`                                                      | `custom_icon` |
| `text-rotation-angle`                                                                                                                     | `angle-stops` (with a hyphen)                                       | `angle_stop`                                                     | `angle`       |
| `icon-rotation-angle`                                                                                                                     | `angle_stops`                                                       | `angle_stop`                                                     | `angle`       |
| `translate-on-X`, `translate-on-Y`                                                                                                        | `translate_stops`                                                   | `translate_stop`                                                 | `value`       |
| `offset-on-X`, `offset-on-Y`                                                                                                              | `offset_stops`                                                      | `offset_stop`                                                    | `value`       |
| `text-anchor`                                                                                                                             | `text_anchor_stops`                                                 | `text_anchor_stop`                                               | `intvalue`    |
| `text-transform`                                                                                                                          | `text_transform_stops`                                              | `text_transform_stop`                                            | `intvalue`    |
| `text-style`                                                                                                                              | `text_style_stops`                                                  | `text_style_stop`                                                | `intvalue`    |
| `text-justify`                                                                                                                            | `text_justify_stops`                                                | `text_justify_stop`                                              | `intvalue`    |
| `text-overlap`, `text-optional`, `text-placement`                                                                                         | `text_overlap_stops`, `text_optional_stops`, `text_placement_stops` | `text_overlap_stop`, `text_optional_stop`, `text_placement_stop` | `boolvalue`   |
| `icon-overlap`, `icon-optional`, `icon-placement`                                                                                         | `icon_overlap_stops`, `icon_optional_stops`, `icon_placement_stops` | `icon_overlap_stop`, `icon_optional_stop`, `icon_placement_stop` | `boolvalue`   |

Options are stored as numbers:

| Property         | Values                                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `text-anchor`    | left-top 6, left-center 4, left-bottom 7, center-top 2, center-center 9, center-bottom 1, right-top 8, right-center 3, right-bottom 5 |
| `text-transform` | none 0, lowercase 1, uppercase 2                                                                                                      |
| `text-style`     | normal 0, bold 1, italic 2                                                                                                            |
| `text-justify`   | left 1, center 4, right 7                                                                                                             |

Which properties each layer type takes is in the [layer types reference](/docs/guides/map-studio/reference/layer-types-reference.md).

### Colours[​](#colours "Direct link to Colours")

A colour is one 32-bit integer in ABGR order: `(a << 24) | (b << 16) | (g << 8) | r`, where `a` is the opacity (255 opaque, 0 invisible). To turn `#rrggbb` into the integer: take the red, green and blue values as numbers from 0 to 255, then compute `a × 16777216 + b × 65536 + g × 256 + r`.

| Colour                        | `a`, `b`, `g`, `r` | Integer    |
| ----------------------------- | ------------------ | ---------- |
| white `#ffffff`               | 255, 255, 255, 255 | 4294967295 |
| black `#000000`               | 255, 0, 0, 0       | 4278190080 |
| orange `#ff5a1f`              | 255, 31, 90, 255   | 4280244991 |
| light blue `#aadaff`          | 255, 255, 218, 170 | 4294957738 |
| pink `#ff69b4`                | 255, 180, 105, 255 | 4290013695 |
| red at half opacity `#ff0000` | 128, 0, 0, 255     | 2147483903 |

Note the order: blue comes before red, the reverse of `#rrggbb`. Studio shows colours as hex; the file stores only integers.

### Easings[​](#easings "Direct link to Easings")

| `easing_type` | Name             |   | `easing_type` | Name             |
| ------------- | ---------------- | - | ------------- | ---------------- |
| 1             | `linear`         |   | 12            | `easeOutQuart`   |
| 2             | `easeInSine`     |   | 13            | `easeInOutQuart` |
| 3             | `easeOutSine`    |   | 14            | `easeInQuint`    |
| 4             | `easeInOutSine`  |   | 15            | `easeOutQuint`   |
| 5             | `easeInQuad`     |   | 16            | `easeInOutQuint` |
| 6             | `easeOutQuad`    |   | 17            | `easeInExpo`     |
| 7             | `easeInOutQuad`  |   | 18            | `easeOutExpo`    |
| 8             | `easeInCubic`    |   | 19            | `easeInOutExpo`  |
| 9             | `easeOutCubic`   |   | 20            | `easeInCirc`     |
| 10            | `easeInOutCubic` |   | 21            | `easeOutCirc`    |
| 11            | `easeInQuart`    |   | 22            | `easeInOutCirc`  |

### Filters[​](#filters "Direct link to Filters")

```json
"filter": {
  "condition": "all",
  "expression": [
    { "key": "category", "condition": "in", "values": ["culture", "food"] },
    { "key": "name", "condition": "has" }
  ]
}

```

The top `condition` is `all`, `any` or `none`. Each entry's `condition` is one of `has`, `hasnot`, `in`, `notin`, `==`, `!=`, `>`, `<`, `>=`, `<=`; `has` and `hasnot` take no values. On the tutorial's sample file, `bucharest-places.geojson`, this filter keeps four of the eight places: the three culture places and the food market, which all have a name.

Every value of your own data is stored as text, and text comparisons ignore upper and lower case. `>`, `<`, `>=` and `<=` compare whole numbers and work only on the map data's number fields, `Lanes count` on roads and `Height` on buildings. On text, including every field of your own data, they let every feature through. The fields of the map data are listed in [Map data sources](/docs/guides/map-studio/reference/map-data-sources.md#fields-you-can-filter-on).

### Text[​](#text "Direct link to Text")

Layers that draw map data, such as city labels (`symbol`), road names (`street`), area labels (`areaname`), country labels (`country`) and POIs, draw their text by themselves: leave `label_text` out. None of the official templates sets it on these layers. Use `label_text` on layers that draw your own data sources, to choose what they show.

A symbol layer's text is an expression, stored as a JSON string in `label_text.label_expression`. Its pieces are `{ "text": "..." }`, `{ "number": 20 }`, `{ "get_v": "name" }` for a value of the feature, and `{ "concat": [ ... ] }` or `{ "*": [ ... ] }` over their arguments. For example, the label `concat(|name|, " (", |category|, ")")` in Studio, which reads "Obor Market (food)", is stored as:

```json
"label_text": {
  "label_expression": "{\"concat\":[{\"get_v\":\"name\"},{\"text\":\" (\"},{\"get_v\":\"category\"},{\"text\":\")\"}]}"
}

```

The result of `*` is shown with two decimals: `product(|rating|, 20)` on a rating of 4.6 reads 92.00.

### Images[​](#images "Direct link to Images")

Each image in `icons_section.icons` is `{ "id": "bike.png", "value": "data:image/png;base64,..." }`: a unique name and the image as a PNG, JPEG or SVG data URI. Images can be up to 400 KB each and 4 MB in total.

A layer uses an image through the `icon` property, whose `custom_icon` holds the image's `id`; `""` means no icon. POI layers draw their category's icon from `metaCategoryID` instead.

### Fonts[​](#fonts "Direct link to Fonts")

`fonts_section` holds the style's own font for its labels. It comes after `icons_section` and is left out when the style uses the map's built-in font:

```json
"fonts_section": {
  "regular": "data:font/ttf;base64,AAEAAAAQAQAABAAA...",
  "bold": "data:font/ttf;base64,AAEAAAAQAQAABAAA..."
}

```

| Key       | What it holds                                         |
| --------- | ----------------------------------------------------- |
| `regular` | The face for layers whose `text-style` is normal (0). |
| `bold`    | The face for layers whose `text-style` is bold (1).   |
| `italic`  | The face for layers whose `text-style` is italic (2). |

Each key is optional and works on its own: a face that is missing is drawn in the map's built-in font.

Each value is a whole TTF or OTF file as a base64 data URI, `data:font/ttf;base64,...` or `data:font/otf;base64,...`; there is no size limit, but the file is part of every save and download of the style, and the engine reads it whole when the style is opened. WOFF and WOFF2 web fonts and font collections (`.ttc`) are not read. There is no font per layer: every label uses this font, and a character the font does not have is drawn in the built-in font.

The font is part of the file, so it is in the `.style` file too. Font data cannot be written by hand or generated: a file Studio cannot read as a font is left out when the style is opened. Add fonts in **Settings › Typography** (see [The style's font](/docs/guides/map-studio/editing/fonts.md)).

## A complete small style[​](#a-complete-small-style "Direct link to A complete small style")

A whole style with nine layers: city labels, motorway names, motorways, residential streets, parks, water, sea, land and the background. Its colours and sizes come from the Basic 1 template. Download it as [example-small-style.json](/docs/samples/map-studio/example-small-style.json).

```json
{
  "sources_list": { "sources": [] },
  "map_schemes_section": {
    "COMMENT": "Define all available map schemes.",
    "map_schemes": [{
      "id": 1,
      "name": "Small example",
      "groups_section": { "groups": [
        {"id": 1, "name": "Labels"},
        {"id": 2, "name": "Roads"},
        {"id": 3, "name": "Areas"}
      ] },
      "definition": { "layers": [
        { "COMMENT": "City labels (over 500k)", "id": 9, "type": "symbol", "source": "map", "sourcedata_id": 0, "minzoom": 3, "maxzoom": 13, "group_id": 1, "paint": {
            "text-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4281807665}], "easing_type": 1}},
            "text-size": {"text_size_stops": {"text_size_stop": [{"level_id": 4, "size": 3}, {"level_id": 13, "size": 6}], "easing_type": 1}},
            "text-outline-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294967295}], "easing_type": 1}},
            "text-outline-size": {"text_size_stops": {"text_size_stop": [{"level_id": 0, "size": 1}], "easing_type": 1}}
        } },
        { "COMMENT": "Motorway names", "id": 8, "type": "street", "source": "map", "sourcedata_id": 0, "minzoom": 11, "maxzoom": 17, "group_id": 1, "paint": {
            "text-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4280829573}], "easing_type": 1}},
            "text-size": {"text_size_stops": {"text_size_stop": [{"level_id": 12, "size": 2.5}, {"level_id": 17, "size": 6}], "easing_type": 1}},
            "text-outline-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294967295}], "easing_type": 1}},
            "text-outline-size": {"text_size_stops": {"text_size_stop": [{"level_id": 0, "size": 1}], "easing_type": 1}}
        } },
        { "COMMENT": "Motorway", "id": 7, "type": "line", "source": "map", "sourcedata_id": 0, "minzoom": 4, "maxzoom": 17, "group_id": 2, "paint": {
            "line-inner-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4288801791}], "easing_type": 1}},
            "line-outer-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4284862454}], "easing_type": 1}},
            "line-width": {"line_width_stops": {"line_width_stop": [{"level_id": 4, "width": 7}, {"level_id": 10, "width": 3}, {"level_id": 13, "width": 2.5}, {"level_id": 17, "width": 5}], "easing_type": 1}},
            "line-outline-width": {"line_width_stops": {"line_width_stop": [{"level_id": 4, "width": 1}, {"level_id": 11, "width": 0.5}, {"level_id": 16, "width": 0.1}], "easing_type": 1}}
        } },
        { "COMMENT": "Residential", "id": 6, "type": "line", "source": "map", "sourcedata_id": 6, "minzoom": 11, "maxzoom": 17, "group_id": 2, "paint": {
            "line-inner-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294967295}], "easing_type": 1}},
            "line-outer-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4292662998}], "easing_type": 1}},
            "line-width": {"line_width_stops": {"line_width_stop": [{"level_id": 10, "width": 1}, {"level_id": 13, "width": 1.75}, {"level_id": 15, "width": 1.5}], "easing_type": 1}},
            "line-outline-width": {"line_width_stops": {"line_width_stop": [{"level_id": 0, "width": 0.15}], "easing_type": 1}}
        } },
        { "COMMENT": "Green Park", "id": 5, "type": "polygon", "source": "map", "sourcedata_id": 23, "minzoom": 0, "maxzoom": 17, "group_id": 3, "paint": {
            "fill-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4291160517}], "easing_type": 1}}
        } },
        { "COMMENT": "Water", "id": 4, "type": "polygon", "source": "map", "sourcedata_id": 9, "minzoom": 0, "maxzoom": 17, "group_id": 3, "paint": {
            "fill-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294957738}], "easing_type": 1}}
        } },
        { "COMMENT": "Water Sea", "id": 3, "type": "polygon", "source": "map", "sourcedata_id": 94, "minzoom": 0, "maxzoom": 17, "group_id": 3, "paint": {
            "fill-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294957738}], "easing_type": 1}}
        } },
        { "COMMENT": "Land", "id": 2, "type": "polygon", "source": "map", "sourcedata_id": 0, "minzoom": 0, "maxzoom": 17, "group_id": 3, "paint": {
            "fill-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294638072}], "easing_type": 1}}
        } },
        { "COMMENT": "Background", "id": 1, "type": "background", "sourcedata_id": 0, "paint": {
            "fill-color": {"color_stops": {"color_stop": [{"level_id": 0, "color": 4294957738}], "easing_type": 1}}
        } }
      ] }
    }]
  },
  "icons_section": { "COMMENT": "Define all available icons for schemes.", "icons": [] }
}

```

For a full style to study or start from, download the Basic 1 template, as the portal offers it: [template-basic-1.json](/docs/samples/map-studio/template-basic-1.json) (222 layers and 6 images). One value is corrected so that the file passes the schema: the portal's copy stores the text anchor of the Narrow Water Line Label layer as the text `"2"`, and this file has the number `2`.

## The JSON Schema[​](#the-json-schema "Direct link to The JSON Schema")

The rules above are published as a JSON Schema (draft 2020-12): [`engine-style.schema.json`](/docs/schemas/engine-style.schema.json).

It checks the sections and the single scheme; every layer field and its type; the layer type and source names; every paint property's wrapper, stop array, value key and range (no negative sizes, opacity 0 to 1, zoom 0 to 17, `easing_type` 1 to 22); which properties each layer type takes; colours as integers; filters, text, images and the font's faces. Each property also carries its help text from the Properties column. Fields the engine reads but Studio does not write are accepted and marked `"x-written-by-studio": false`.

A few rules link one part of the file to another, which a schema cannot express. They are listed in the schema under `x-checks-not-in-schema`: layer `id`s go down from each layer to the next and end at 1; every `group_id` and `parent_id` names an existing group; every `custom_icon` names an image; `minzoom` is not above `maxzoom`; each `fonts_section` value is a real TTF or OTF file.

To check a file, save the schema next to it and run, with Python and `jsonschema` 4.18 or later (`pip install "jsonschema>=4.18"`):

```sh
python3 -c "import json, jsonschema; jsonschema.validate(json.load(open('my-style.json')), json.load(open('engine-style.schema.json')))"

```

No output means the file passed; otherwise the first problem is printed with its place in the file.

See also: [Map data sources](/docs/guides/map-studio/reference/map-data-sources.md) · [Layer types reference](/docs/guides/map-studio/reference/layer-types-reference.md) · [Download and use in your app](/docs/guides/map-studio/getting-started/download-and-use.md)
