@versatiles/versatiles-rs
v3.8.1
Published
Node.js bindings for VersaTiles - convert, serve, and process map tiles
Readme
@versatiles/versatiles-rs
Node.js bindings for VersaTiles - convert, serve, and process map tiles in various formats.
Features
- 🚀 Fast & Native - Powered by Rust with zero-copy operations
- 🔄 Format Conversion - Convert between MBTiles, PMTiles, VersaTiles, TAR, and directories
- 🗺️ Tile Server - Built-in HTTP tile server with dynamic source management
- 📊 Metadata Access - Read TileJSON and inspect container details
- 🌍 Coordinate Utils - Convert between tile and geographic coordinates
- ⚡ Async API - Non-blocking operations with Promise-based interface
- 📦 Dual Format - Supports both ESM and CommonJS
Installation
npm install @versatiles/versatiles-rs
# or
yarn add @versatiles/versatiles-rsPre-built binaries are available for:
- macOS (arm64, x64)
- Linux (x64, arm64, musl)
- Windows (x64, arm64)
Quick Start
Convert Tiles
import { convert } from '@versatiles/versatiles-rs';
await convert('input.mbtiles', 'output.versatiles', {
minZoom: 0,
maxZoom: 14,
bbox: [-180, -85, 180, 85],
compress: 'gzip',
});Serve Tiles
import { TileServer } from '@versatiles/versatiles-rs';
const server = new TileServer({ port: 8080 });
await server.addTileSourceFromPath('osm', 'tiles.mbtiles');
await server.start();
console.log(`Server running at http://localhost:${server.port}`);Read Tiles
import { TileSource } from '@versatiles/versatiles-rs';
const source = await TileSource.open('tiles.mbtiles');
// Get a single tile
const tile = await source.getTile(5, 16, 10);
if (tile) {
console.log('Tile size:', tile.length, 'bytes');
}
// Get metadata
const metadata = source.metadata();
console.log('Format:', metadata.tileFormat);
console.log('Zoom levels:', metadata.minZoom, '-', metadata.maxZoom);
// Get TileJSON
const tileJSON = source.tileJson();
console.log('Bounds:', tileJSON.bounds);Probe Container
import { TileSource } from '@versatiles/versatiles-rs';
const source = await TileSource.open('tiles.mbtiles');
const sourceType = source.sourceType();
const metadata = source.metadata();
console.log('Type:', sourceType.kind);
console.log('Format:', metadata.tileFormat);
console.log('Compression:', metadata.tileCompression);Coordinate Conversion
import { TileCoord } from '@versatiles/versatiles-rs';
// Geographic to tile coordinates
const coord = TileCoord.fromGeo(13.4, 52.5, 10);
console.log(`Tile: z=${coord.z}, x=${coord.x}, y=${coord.y}`);
// Tile to geographic coordinates
const tile = new TileCoord(10, 550, 335);
const [lon, lat] = tile.toGeo();
console.log(`Location: ${lon}, ${lat}`);
// Get bounding box
const bbox = tile.toGeoBbox();
console.log('BBox:', bbox); // [west, south, east, north]CommonJS Support
The package also supports CommonJS:
const { convert, TileSource, TileServer, TileCoord } = require('@versatiles/versatiles-rs');API Reference
convert(input, output, options?, onProgress?, onMessage?)
Convert tiles from one format to another.
Parameters:
input(string): Input file path (.versatiles, .mbtiles, .pmtiles, .tar, directory)output(string): Output file pathoptions(ConvertOptions, optional):minZoom(number): Minimum zoom levelmaxZoom(number): Maximum zoom levelbbox(array): Bounding box[west, south, east, north]bboxBorder(number): Border around bbox in tilescompress(string): Compression"gzip","brotli", or"uncompressed"flipY(boolean): Flip tiles verticallyswapXy(boolean): Swap x and y coordinates
onProgress(function, optional): Progress callback(data: ProgressData) => voidonMessage(function, optional): Message callback(data: MessageData) => void
Returns: Promise<void>
class TileSource
TileSource.open(path)
Open a tile container.
Parameters:
path(string): File path or URL
Returns: Promise<TileSource>
TileSource.fromVpl(vpl, basePath?)
Create a tile source from VPL (VersaTiles Pipeline Language).
Parameters:
vpl(string): VPL query stringbasePath(string, optional): Base path for resolving relative paths
Returns: Promise<TileSource>
source.getTile(z, x, y)
Get a single tile.
Parameters:
z(number): Zoom levelx(number): Tile columny(number): Tile row
Returns: Promise<Buffer | null>
source.tileJson()
Get TileJSON metadata.
Returns: TileJSON
interface TileJSON {
tilejson: string;
tiles?: string[];
vector_layers?: VectorLayer[];
attribution?: string;
bounds?: [number, number, number, number];
center?: [number, number, number];
// ... and more
}source.metadata()
Get source metadata.
Returns: SourceMetadata
interface SourceMetadata {
tileFormat: string;
tileCompression: string;
minZoom: number;
maxZoom: number;
}source.sourceType()
Get source type information.
Returns: SourceType
source.convertTo(output, options?, onProgress?, onMessage?)
Convert this source to another format.
Parameters:
output(string): Output file pathoptions(ConvertOptions, optional): Same asconvert()onProgress(function, optional): Progress callbackonMessage(function, optional): Message callback
Returns: Promise<void>
class TileServer
new TileServer(options?)
Create a new tile server.
Parameters:
options(object, optional):ip(string): IP address to bind (default:"0.0.0.0")port(number): Port number (default:8080)minimalRecompression(boolean): Use minimal recompression
server.addTileSourceFromPath(name, path)
Add a tile source from a file path.
Parameters:
name(string): Source name (URL will be/tiles/{name}/...)path(string): Container file path
Returns: Promise<void>
server.addTileSource(name, source)
Add a tile source from a TileSource instance.
Parameters:
name(string): Source namesource(TileSource): TileSource instance
Returns: Promise<void>
server.removeTileSource(name)
Remove a tile source.
Parameters:
name(string): Source name to remove
Returns: Promise<void>
server.addStaticSource(path, urlPrefix?)
Add static file source.
Parameters:
path(string): Directory or .tar fileurlPrefix(string, optional): URL prefix (default:"/")
Returns: Promise<void>
server.start()
Start the HTTP server.
Returns: Promise<void>
server.stop()
Stop the HTTP server.
Returns: Promise<void>
server.port
Get server port (getter).
Returns: number
class TileCoord
new TileCoord(z, x, y)
Create a tile coordinate.
Parameters:
z(number): Zoom levelx(number): Columny(number): Row
TileCoord.fromGeo(lon, lat, z)
Create from geographic coordinates (static).
Parameters:
lon(number): Longitudelat(number): Latitudez(number): Zoom level
Returns: TileCoord
coord.toGeo()
Convert to geographic coordinates.
Returns: [number, number] - [lon, lat]
coord.toGeoBbox()
Get geographic bounding box.
Returns: [number, number, number, number] - [west, south, east, north]
coord.toJson()
Get JSON representation.
Returns: string
Properties
coord.z(number): Zoom levelcoord.x(number): Columncoord.y(number): Row
Supported Formats
- VersaTiles (
.versatiles) - Native format - MBTiles (
.mbtiles) - SQLite-based format - PMTiles (
.pmtiles) - Cloud-optimized format - TAR (
.tar) - Archive format - Directory - File system based
Examples
See the examples directory for more usage examples:
- convert.ts - Format conversion with various options
- convert-with-progress.ts - Conversion with progress monitoring
- probe.ts - Container inspection
- serve.ts - HTTP tile server
- read-tiles.ts - Reading tiles and coordinate conversion
- vpl-pipeline.ts - Building VPL pipelines programmatically
All examples use TypeScript and can be run with:
npx tsx examples/<filename>.tsDevelopment
Requirements
- Node.js >= 16
- Rust toolchain (for building from source)
Build Process
The package has two outputs: a native N-API module (Rust compiled to a .node binary) and a VPL TypeScript library (generated from Rust operation metadata, then compiled to JS). The VPL generation step calls into the native module, so it must be built first.
flowchart TD
subgraph "1. Native Module"
RS[Rust source] -->|"npm run build:cjs"| CJS["index.cjs"]
RS -->|"npm run build:esm"| ESM["index.js<br/>index.d.ts"]
end
subgraph "2. VPL Library"
ESM -->|"npm run build:vpl"| VJS["vpl.js<br/>vpl.d.ts"]
end| Step | Script | What it does |
| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Build native CJS | build:cjs | Compiles Rust to a native .node binary and generates index.cjs |
| Build native ESM | build:esm | Generates index.js and index.d.ts (ESM wrapper + type declarations) |
| Generate VPL TS | build:vpl | Runs scripts/generate-vpl.ts which calls the native generateVplTypescript() function to produce vpl.ts, then compiles it with tsc to vpl.js + vpl.d.ts |
Building from Source
# Install dependencies
npm install
# Build debug version (native module + VPL)
npm run build:debug
# Build release version (native module + VPL)
npm run build
# Run tests
npm testLicense
MIT License - see LICENSE for details.
Links
Contributing
Contributions are welcome! Please see the main versatiles-rs repository for contribution guidelines.
