Native OpenStreetMap SDK for Expo mobile development with zero configuration πΊοΈ
# For iOS & Android (works out-of-the-box)
npm install expo-osm-sdk
# For Web support, ALSO install:
npm install maplibre-glπ± Mobile-First Package: iOS and Android work immediately. Web requires
maplibre-gl(setup guide).
β
Native Mobile Polylines: Real route visualization on iOS & Android
β
Cross-Platform Routing: Works on mobile and web (with maplibre-gl)
β
Multi-Point Navigation: Route through multiple waypoints
β
Turn-by-Turn Instructions: Real navigation with step-by-step directions
β
OSRM Integration: Complete routing powered by OpenStreetMap
β
Transport Modes: Car π, Bike π΄, Walking πΆ
β
Route Styling: Custom colors, widths, and styling per transport mode
Add to your app.json:
{
"expo": {
"plugins": [["expo-osm-sdk/plugin"]]
}
}Use in your app:
import { OSMView, SearchBox } from 'expo-osm-sdk';
// Basic Map
<OSMView
style={{ flex: 1 }}
initialCenter={{ latitude: 40.7128, longitude: -74.0060 }}
initialZoom={13}
/>
// Map with Search
<View style={{ flex: 1 }}>
<SearchBox
placeholder="Search for places..."
onLocationSelected={(location) => {
// Animate map to selected location
mapRef.current?.animateToLocation(
location.coordinate.latitude,
location.coordinate.longitude,
15
);
}}
style={{ margin: 20, marginTop: 60 }}
/>
<OSMView
ref={mapRef}
style={{ flex: 1 }}
initialCenter={{ latitude: 40.7128, longitude: -74.0060 }}
initialZoom={13}
/>
</View>Version 1.0.87 introduces full cross-platform routing with native mobile support:
- ποΈ Native Polylines: Real route visualization using MapLibre native on iOS & Android
- π¨ Custom Route Styling: Colors, widths, and opacity for each transport mode
- πΊοΈ Multi-Point Routes: Navigate through multiple waypoints in sequence
- π§ Turn-by-Turn Instructions: Real navigation with step-by-step directions
- π Distance Matrix: Calculate route distance, duration, and estimated time
- π£οΈ Route Profiles: Support for driving, walking, and cycling routes
- β‘ OSRM Integration: Powered by OpenStreetMap's routing engine
- π Auto-Fit Routes: Automatically zoom to show complete routes
- π Route Switching: Seamless switching between transport modes
- π Cross-Platform: Works on iOS, Android, and Web with appropriate implementations
import {
useOSRMRouting,
calculateRoute,
type Route,
type OSMViewRef
} from 'expo-osm-sdk';
// 1. Complete Mobile Navigation with Native Polylines
const routing = useOSRMRouting();
const mapRef = useRef<OSMViewRef>(null);
const startNavigation = async () => {
const from = { latitude: 40.7128, longitude: -74.0060 }; // NYC
const to = { latitude: 41.8781, longitude: -87.6298 }; // Chicago
// Calculate and display route with native polylines on mobile
const route = await routing.calculateAndDisplayRoute(
from, to, mapRef,
{
profile: 'driving',
routeStyle: {
color: '#007AFF', // Custom blue for driving
width: 5, // Route line width
opacity: 0.8 // Route transparency
}
}
);
if (route) {
console.log(`Route: ${routing.formatRouteDistance(route)} in ${routing.formatRouteDuration(route)}`);
console.log('Turn-by-turn:', route.steps.map(s => s.instruction));
// Auto-fit the route in view (works on both mobile and web)
await routing.fitRouteInView(route, mapRef, 50);
}
};
// 2. Multi-Transport Mode Navigation (like Google Maps)
const TRANSPORT_MODES = [
{ id: 'car', profile: 'driving', color: '#007AFF', icon: 'π' },
{ id: 'bike', profile: 'cycling', color: '#34C759', icon: 'π΄' },
{ id: 'walk', profile: 'walking', color: '#8E8E93', icon: 'πΆ' },
];
const calculateAllRoutes = async () => {
const from = { latitude: 51.5074, longitude: -0.1278 }; // London
const to = { latitude: 48.8566, longitude: 2.3522 }; // Paris
for (const mode of TRANSPORT_MODES) {
const route = await routing.calculateAndDisplayRoute(
from, to, mapRef,
{
profile: mode.profile,
routeStyle: { color: mode.color, width: 5 }
}
);
if (route) {
console.log(`${mode.icon} ${mode.id}: ${routing.formatRouteDistance(route)} in ${routing.formatRouteDuration(route)}`);
}
}
};
// 2. Direct Route Calculation
const calculateCustomRoute = async () => {
const routes = await calculateRoute([
{ latitude: 51.5074, longitude: -0.1278 }, // London
{ latitude: 48.8566, longitude: 2.3522 } // Paris
], {
profile: 'driving',
steps: true, // Include turn-by-turn instructions
alternatives: true // Get alternative routes
});
routes.forEach((route, index) => {
console.log(`Route ${index + 1}: ${route.distance}m, ${route.duration}s`);
route.steps.forEach(step => {
console.log(`${step.instruction} (${step.distance}m)`);
});
});
};
// 3. Navigation State Management
const { state, calculateAndDisplayRoute, nextWaypoint, clearRoute } = useOSRMRouting();
// Display route progress
console.log(`Navigation: ${state.isCalculating ? 'Calculating...' : 'Ready'}`);
if (state.currentRoute) {
console.log(`Distance: ${state.currentRoute.distance}m`);
console.log(`Duration: ${state.currentRoute.duration}s`);
}Version 1.0.79 also includes full OpenStreetMap search and geocoding capabilities:
- π Location Search: Find places, addresses, and points of interest
- π Reverse Geocoding: Get addresses from coordinates
- πͺ POI Discovery: Find nearby restaurants, hotels, hospitals
- π± Professional UI: Beautiful SearchBox component with autocomplete
- β‘ Smart Search: Handles coordinates, addresses, and place names
- π No API Keys: Uses free OpenStreetMap Nominatim service
import {
SearchBox,
useNominatimSearch,
quickSearch,
searchNearby,
getAddressFromCoordinates
} from 'expo-osm-sdk';
// 1. SearchBox Component (Easiest)
<SearchBox
placeholder="Search places..."
onLocationSelected={(location) => console.log(location.displayName)}
maxResults={5}
autoComplete={true}
/>
// 2. Search Hook for Custom UI
const { search, isLoading, lastResults } = useNominatimSearch();
const results = await search("Times Square");
// 3. Quick One-Line Search
const location = await quickSearch("Central Park");
// 4. Find Nearby POIs
const restaurants = await searchNearby(
{ latitude: 40.7128, longitude: -74.0060 },
"restaurant",
2 // km radius
);
// 5. Reverse Geocoding
const address = await getAddressFromCoordinates({
latitude: 40.7589,
longitude: -73.9851
});
// Returns: "Broadway, New York, United States"This repository contains multiple related projects:
π¦ expo-osm-sdk/ - Main SDK Package
The core OpenStreetMap SDK for Expo applications.
- Installation:
npm install expo-osm-sdk - Documentation: Complete API reference and setup guide
- Features: Native performance, TypeScript support, zero config
π§ͺ simple-map-test/ - Navigation Demo App β
Complete navigation demo with mobile routing!
- β Full OSRM routing with native polylines on mobile
- β Multi-transport modes (Car, Bike, Walk)
- β Interactive search with Nominatim integration
- β Custom route styling and auto-fit functionality
- β Cross-platform testing (iOS/Android/Web)
- β EAS Build optimized for real device testing
π§ expo-osm-sdk/example/ - Basic Example
Simple testing example for SDK development.
- Basic functionality testing
- Development-focused (uses relative imports)
- Start here:
simple-map-test/- Complete navigation demo with routing - Read docs:
expo-osm-sdk/README.md- Full documentation - Install:
npm install expo-osm-sdk - Build: Use EAS Build for native mobile routing features
- Main package:
expo-osm-sdk/- SDK source code - Test with:
simple-map-test/- For testing mobile routing changes - Contributing: See Contributing Guidelines
- πΊοΈ Native OpenStreetMap - MapLibre GL powered rendering
- π Native Mobile Routing - Real polyline visualization on iOS & Android
- π Cross-Platform Routing - Seamless routing on mobile and web
- π¨ Custom Route Styling - Colors, widths, and opacity per transport mode
- π§ Multi-Transport Navigation - Car, bike, walking routing
- π Auto-Fit Routes - Intelligent camera positioning for route visibility
- π Complete Search System - Full geocoding with SearchBox UI component
- π Reverse Geocoding - Get addresses from coordinates instantly
- πͺ POI Discovery - Find nearby restaurants, hotels, hospitals
- π Zero Configuration - Works out of the box with Expo
- π± Mobile-First Design - Optimized for iOS and Android performance
- π― TypeScript First - Full type safety and IntelliSense
- π§ Development Friendly - Hot reload, debugging support
- π Graceful Fallbacks - Professional UIs for Expo Go
- π¦ No API Keys - Uses OpenStreetMap directly
- β‘ GPU Accelerated - Hardware-accelerated map rendering
- π§ͺ Fully Tested - 142+ tests ensuring reliability
| Platform | Support | Experience |
|---|---|---|
| iOS Development Build | β Full Native | Complete OpenStreetMap with native polyline routing |
| Android Development Build | β Full Native | Complete OpenStreetMap with native polyline routing |
| Web | β MapLibre GL JS | Interactive maps with web-based routing visualization |
| Expo Go | Professional placeholder with helpful messaging |
| Feature | iOS | Android | Web | Expo Go |
|---|---|---|---|---|
| Route Calculation | β | β | β | β |
| Native Polylines | β | β | β (MapLibre) | β |
| Route Styling | β | β | β | β |
| Auto-Fit Routes | β | β | β | β |
| Turn-by-Turn | β | β | β | β |
| Transport Modes | β | β | β | β |
- π Complete Guide: expo-osm-sdk/README.md
- π§ͺ Test App: simple-map-test/README.md
- π¦ npm Package: expo-osm-sdk
- π Issues: Report problems
import { OSMView } from 'expo-osm-sdk';
<OSMView
style={{ flex: 1 }}
initialCenter={{ latitude: 51.5074, longitude: -0.1278 }}
initialZoom={10}
/>import { OSMView, SearchBox } from 'expo-osm-sdk';
<View style={{ flex: 1 }}>
<SearchBox
placeholder="Search London..."
onLocationSelected={(location) => {
mapRef.current?.animateToLocation(
location.coordinate.latitude,
location.coordinate.longitude,
15
);
}}
style={{ margin: 20, marginTop: 60 }}
/>
<OSMView
ref={mapRef}
style={{ flex: 1 }}
initialCenter={{ latitude: 51.5074, longitude: -0.1278 }}
initialZoom={10}
/>
</View>import { quickSearch } from 'expo-osm-sdk';
// One-line search
const location = await quickSearch("Big Ben London");
console.log(location.displayName); // "Big Ben, Westminster, London, England"import { useOSRMRouting } from 'expo-osm-sdk';
const routing = useOSRMRouting();
const mapRef = useRef();
// Calculate and display route with native polylines
const showRoute = async () => {
const route = await routing.calculateAndDisplayRoute(
{ latitude: 51.5074, longitude: -0.1278 }, // London
{ latitude: 48.8566, longitude: 2.3522 }, // Paris
mapRef,
{
profile: 'driving',
routeStyle: { color: '#007AFF', width: 5 }
}
);
if (route) {
console.log(`${routing.formatRouteDistance(route)} in ${routing.formatRouteDuration(route)}`);
}
};
<OSMView
ref={mapRef}
style={{ flex: 1 }}
initialCenter={{ latitude: 51.5074, longitude: -0.1278 }}
initialZoom={10}
/>const markers = [
{
id: 'london',
coordinate: { latitude: 51.5074, longitude: -0.1278 },
title: 'London',
description: 'Capital of England'
}
];
<OSMView
style={{ flex: 1 }}
initialCenter={{ latitude: 51.5074, longitude: -0.1278 }}
initialZoom={10}
markers={markers}
onMarkerPress={(id) => console.log('Marker pressed:', id)}
/>We welcome contributions! Here's how:
- Fork this repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Test your changes thoroughly
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details.
- MapLibre GL Native - Powerful map rendering engine
- OpenStreetMap - Community-driven map data
- Expo Team - Amazing development platform
- Contributors - Thank you for making this better!
Made with β€οΈ by Saikat Maiti
Experience native OpenStreetMap in your Expo app without complexity!