https://github.com/navidnabavi/styl
A fast, opinionated linter, validator, and formatter for Mapbox GL and MapLibre GL style JSON files.
https://github.com/navidnabavi/styl
cli formatter geojson geospatial gis linter map-style mapbox maplibre rust validator
Last synced: 16 days ago
JSON representation
A fast, opinionated linter, validator, and formatter for Mapbox GL and MapLibre GL style JSON files.
- Host: GitHub
- URL: https://github.com/navidnabavi/styl
- Owner: navidnabavi
- License: mit
- Created: 2026-05-10T21:05:37.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-22T01:22:35.000Z (24 days ago)
- Last Synced: 2026-05-22T09:44:01.567Z (24 days ago)
- Topics: cli, formatter, geojson, geospatial, gis, linter, map-style, mapbox, maplibre, rust, validator
- Language: Rust
- Homepage:
- Size: 191 KB
- Stars: 22
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-maplibre - Styl - A fast, opinionated linter, validator, and formatter for Mapbox GL and MapLibre GL style JSON files, written in Rust (Utility Libraries / JavaScript)
- awesome-vector-tiles - Styl - A fast, opinionated linter, validator, and formatter for Mapbox GL and MapLibre GL style JSON files, written in Rust (Applications / Command line tools)
README
# styl
**Linter, validator, and formatter for MapLibre GL / Mapbox GL style JSON.**
Catch spec violations, enforce best practices, and keep style files consistent — in CI or locally.

[](https://github.com/navidnabavi/styl/actions/workflows/rust.yml)
[](https://www.rust-lang.org)
[](LICENSE)
[](https://maplibre.org/maplibre-style-spec/)
---
## Why styl?
GL style JSON files grow fast. A single typo in a source reference silently breaks tiles. An invisible layer left in production wastes render time. Legacy filter syntax slips through code review unnoticed.
`styl` is the `cargo clippy` for your map styles — runs in milliseconds, integrates with CI, and tells you exactly what is wrong and why.
```
$ styl check style.json
warning[W002] layers[9].layout.visibility: layer "Building" is permanently invisible
--> style.json
hint: remove the layer or set visibility to "visible" if it should be shown
warning[W011] layers[3].filter: layer "Landuse" uses deprecated legacy filter syntax
--> style.json
hint: migrate to expression-based filters: https://maplibre.org/maplibre-style-spec/expressions/
error[E003] sources.roads: vector source missing required field "url" or "tiles"
--> style.json
```
---
## Features
| Feature | Description |
|---|---|
| **Validator** | Spec violations: missing fields, invalid values, broken source refs (E-codes) |
| **Linter** | Best-practice warnings: duplicate IDs, invisible layers, legacy filters, perf anti-patterns (W-codes) |
| **Formatter** | Canonical key ordering with `--check` mode for CI enforcement |
| **Multiple output formats** | Human-readable, JSON (for tooling), GitHub Actions annotations |
| **Config file** | Per-project `.stylrc` — per-rule severity overrides, indent settings |
| **Stdin support** | `cat style.json \| styl check --stdin` — pipe-friendly |
---
## Installation
### Homebrew (macOS / Linux)
```bash
brew tap navidnabavi/tap
brew install styl
```
### One-line installer
```bash
curl -fsSL https://raw.githubusercontent.com/navidnabavi/styl/main/install.sh | bash
```
Detects your OS and architecture, downloads the correct binary, installs to `/usr/local/bin`.
### Cargo (requires Rust)
```bash
cargo install --git https://github.com/navidnabavi/styl
```
### Build from source
```bash
git clone https://github.com/navidnabavi/styl
cd styl
cargo build --release
# binary at: target/release/styl
```
---
## Usage
```bash
styl check style.json # validate + lint (most common)
styl validate style.json # spec violations only (E-codes)
styl lint style.json # best-practice warnings only (W-codes)
styl fmt style.json # format in-place
styl fmt --check style.json # CI: exit 1 if formatting would change
styl check --format json style.json # machine-readable output
styl check --format github style.json # GitHub Actions annotations
cat style.json | styl check --stdin # read from stdin
```
### Exit Codes
| Code | Meaning |
|------|---------|
| `0` | Clean — no diagnostics |
| `1` | Diagnostics found (errors or warnings) |
| `2` | Tool error (bad JSON, I/O failure) |
### CI Integration
**GitHub Action (Recommended):**
```yaml
- uses: navidnabavi/styl@v0.0.4
with:
style_file: style.json
```
**Advanced usage:**
```yaml
- uses: navidnabavi/styl@latest
with:
style_file: style.json
command: check # check (default), validate, lint, fmt
format: github # github (default), human, json, html
version: v0.0.4 # pin styl version (optional)
```
**Pre-commit hook:**
```bash
styl fmt --check style.json && styl check style.json
```
---
## Configuration
Drop a `.stylrc` at your project root:
```toml
[rules]
W002 = "error" # invisible layers → hard error
W003 = "off" # unused layers → silence
W011 = "warn" # legacy filters → warn (default)
[format]
indent = 4
```
`styl` walks up the directory tree to find it automatically.
---
## Documentation
| Document | Description |
|----------|-------------|
| [CLI Reference](docs/cli.md) | All subcommands and flags |
| [Validators](docs/validators.md) | E-code spec violations |
| [Linter Rules](docs/linter.md) | W-code best-practice warnings |
| [Expressions](docs/expressions.md) | Supported expression operators |
| [Formatter](docs/formatter.md) | Key ordering and `--check` mode |
| [Configuration](docs/config.md) | `.stylrc` reference |
| [Layer Properties](docs/layer-properties.md) | Valid paint/layout props per layer type |
---
## Supported Specs
- **MapLibre GL Style Spec v8** (default) — [maplibre.org/maplibre-style-spec](https://maplibre.org/maplibre-style-spec/)
- **Mapbox GL Style Spec v8** — pass `--spec mapbox`
---
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md). New validators and linter rules are welcome — the architecture makes adding them straightforward.
```bash
cargo build && cargo test && cargo clippy -- -D warnings && cargo fmt --check
```
All four must pass before opening a PR.
---
## License
MIT