This document outlines the plan to restructure tileserver-rs for publishing to crates.io, following Rust ecosystem best practices (similar to git2-rs, rusqlite, etc.).
tileserver-rs/
├── Cargo.toml # Workspace root + tileserver-rs binary
├── src/ # Binary source (HTTP server, CLI)
│ ├── main.rs
│ ├── cli.rs
│ ├── logging.rs
│ ├── telemetry.rs
│ ├── openapi.rs
│ ├── wmts.rs
│ ├── cache_control.rs
│ └── render/ # Native rendering (uses mbgl-sys)
│
├── tileserver-core/ # Library crate (publishable)
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ ├── lib.rs
│ ├── config.rs
│ ├── error.rs
│ ├── sources/ # PMTiles, MBTiles
│ └── styles/ # Style management
│
├── crates/
│ └── mbgl-sys/ # FFI crate (publishable)
│ ├── Cargo.toml
│ ├── README.md
│ ├── build.rs # Downloads pre-built OR builds from source
│ ├── src/lib.rs
│ ├── cpp/ # C wrapper code
│ └── vendor/maplibre-native/ # Git submodule (optional, for bundled builds)
│
└── .github/workflows/
├── ci-rust.yml # Lint, test, build
├── build-maplibre-native.yml # NEW: Build & cache native libs
├── release-native-libs.yml # NEW: Publish pre-built libs
└── release-*.yml # Existing release workflows
Core library for tile serving, no native dependencies.
Publishable to crates.io: Yes Dependencies: Pure Rust (pmtiles, rusqlite, serde, etc.)
[package]
name = "tileserver-core"
version = "0.1.0"
[features]
default = []
http = ["reqwest", "pmtiles/http-async"] # Remote PMTiles supportExports:
TileSourcetraitPmTilesSource,MBTilesSourceSourceManagerStyleManagerConfig
Low-level FFI bindings to MapLibre GL Native.
Publishable to crates.io: Yes (with pre-built binaries) Strategy: Download pre-built static libraries OR build from source
[package]
name = "mbgl-sys"
version = "0.3.0"
links = "maplibre-native"
[features]
default = []
# Download pre-built libraries (fast, recommended)
prebuilt = []
# Build from vendored source (slow, requires cmake/ninja)
vendored = []Pre-built Library Distribution:
- Host on GitHub Releases as
maplibre-native-libs-{version}-{target}.tar.gz - Targets:
x86_64-apple-darwin,aarch64-apple-darwin,x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu - Build script downloads appropriate archive based on target
The CLI binary that users install.
Publishable to crates.io: Yes
Install: cargo install tileserver-rs
[package]
name = "tileserver-rs"
version = "0.3.0"
[dependencies]
tileserver-core = "0.1"
mbgl-sys = { version = "0.3", features = ["prebuilt"] }
[features]
default = ["native-render"]
native-render = ["mbgl-sys"]- Create
tileserver-core/directory - Move
src/sources/,src/styles/,src/config.rs,src/error.rs - Create clean public API in
lib.rs - Update imports in main crate to use
tileserver_core:: - Test:
cargo check -p tileserver-core
- Add
prebuiltfeature to Cargo.toml - Update
build.rs:- If
prebuilt: download from GitHub Releases - If
vendored: build from source (current behavior) - If neither: use stub
- If
- Create GitHub Release workflow for pre-built libs
Builds MapLibre Native for all platforms:
- Triggers: manual, or when mbgl-sys changes
- Matrix: macOS (arm64, x86_64), Linux (x86_64, arm64)
- Outputs:
libmbgl-core.a,libmlt-cpp.a, etc. - Caches: Using GitHub Actions cache
Publishes pre-built libraries:
- Triggers: tag
mbgl-sys-v* - Creates GitHub Release with tarballs:
maplibre-native-libs-0.3.0-aarch64-apple-darwin.tar.gzmaplibre-native-libs-0.3.0-x86_64-unknown-linux-gnu.tar.gz- etc.
fn download_prebuilt() -> Result<PathBuf, Error> {
let version = env!("CARGO_PKG_VERSION");
let target = env::var("TARGET")?;
let url = format!(
"https://github.com/vinayakkulkarni/tileserver-rs/releases/download/\
mbgl-sys-v{version}/maplibre-native-libs-{version}-{target}.tar.gz"
);
// Download and extract...
}Order matters due to dependencies:
cargo publish -p tileserver-core- Build and release native libs (tag
mbgl-sys-v0.3.0) cargo publish -p mbgl-syscargo publish -p tileserver-rs
| Workflow | Purpose | Trigger |
|---|---|---|
ci-rust.yml |
Lint, test, build all crates | PR, push to main |
build-maplibre-native.yml |
Build native libs for all platforms | Manual, changes to mbgl-sys |
release-native-libs.yml |
Publish pre-built libs to GitHub Releases | Tag mbgl-sys-v* |
release-crates.yml (NEW) |
Publish crates to crates.io | Tag v* |
release-*.yml |
Build binary releases | Tag tileserver-rs-v* |
tileserver-core: Starts at 0.1.0, follows semvermbgl-sys: Bumps to 0.3.0 (adds prebuilt feature)tileserver-rs: Bumps to 0.3.0 (new architecture)
After publishing:
# Install CLI with native rendering (downloads pre-built libs)
cargo install tileserver-rs
# Use as library (no native deps)
cargo add tileserver-core
# Use with native rendering
cargo add tileserver-core
cargo add mbgl-sys --features prebuilt