Skip to content

conveyal/osmix

Repository files navigation

Osmix

High-performance OpenStreetMap tools for TypeScript and JavaScript environments.

Introduction

Osmix is a collection of composable libraries for reading, querying, merging, and transforming OpenStreetMap PBF data in browsers and Node.js. Built on streaming APIs and Web Workers, Osmix handles large extracts efficiently with spatial indexing, vector tile generation, and in-browser merge workflows.

Key Features:

  • Streaming PBF parsing with minimal memory overhead
  • Spatial queries via R-tree indexes (KDBush, Flatbush)
  • Merge and deduplicate OSM extracts
  • Cross-platform – ESM-native, runs in Node.js, Bun, Deno, and browsers
  • Generate raster and vector tiles
  • Worker-based processing for responsive UIs

Try it: merge.osmix.dev

Quick Start

bun add osmix

Examples

import { fromPbf, toPbfBuffer, transformOsmPbfToJson, merge, isNode } from "osmix"

// Load a PBF file
const osm = await fromPbf(Bun.file('./monaco.pbf').stream())

// Query entities by ID
const node = osm.nodes.getById(123456)
const way = osm.ways.getById(789012)
const relation = osm.relations.getById(345678)

// Spatial queries with bounding box
const bbox: [number, number, number, number] = [7.41, 43.72, 7.43, 43.74]
const nodeResults = osm.nodes.withinBbox(bbox)
const wayResults = osm.ways.withinBbox(bbox)
console.log(`Found ${nodeResults.ids.length} nodes and ${wayResults.ids.length} ways`)

// Stream parse a PBF into JSON entities
const stream = transformOsmPbfToJson(Bun.file("./monaco.pbf").stream())
for await (const entity of stream) {
	if ("id" in entity) {
		console.log(entity.id, entity.tags)
		if (isNode(entity)) {
			console.log(entity.lon, entity.lat)
		}
	}
}

// Write the PBF
await Bun.write('./new-monaco.pbf', await toPbfBuffer(osm))

// Merge two OSM PBF files
const patchOsm = await fromPbf(Bun.file('./monaco-patch.pbf').stream())
const mergedOsm = merge(osm, patchOsm)

Use in a Web Worker

import { createRemote } from "osmix"

// main.ts
const remote = await createRemote()
const osmInfo = await remote.fromPbf(monacoPbf) // Remote returns an info object

// Operations run off the main thread
const tile = await remote.getVectorTile(osmInfo.id, [9372, 12535, 15])

Monorepo Structure

See each package's README for full API and description.

Package Description
osmix Main library packaging all tools into a unified API.
@osmix/core In-memory data structures for storing entities, building indexes, and spatial queries.
@osmix/pbf Low-level PBF protobuf parsing and writing.
@osmix/json Streaming transforms: PBF bytes ↔ typed JSON entities.
@osmix/geojson Convert OSM entities to/from GeoJSON.
@osmix/change Deduplication, merging, and changeset workflows.
@osmix/raster Render OSM entities as raster bitmaps.
@osmix/vt Encode OSM entities as Mapbox Vector Tiles (MVT).
@osmix/shared Utility functions and geometry helpers.
@osmix/router Experimental routing. WIP.

Development

# Install dependencies
bun install

# Run all apps in watch mode
bun run dev

# Build all packages
bun run build

# Run tests
bun run test

# Type check
bun run typecheck

# Format and lint
bun run check

Workspace commands support filtering: bun run --filter @osmix/merge dev

Apps

  • merge – Interactive merge tool for OSM extracts with MapLibre visualization (live demo)
  • bench – Performance benchmarks comparing Osmix with DuckDB-wasm
  • vt-server – Example vector tile server implementation

Resources

About

OpenStreetMap reader, writer, and merge tool. Written in TypeScript.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages