Package Exports
- unimap
- unimap/build/unimap.mini.js
- unimap/unimap.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (unimap) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
UniMap
Unified Mapping Library - One API for All Map Providers
UniMap provides a single, consistent API for working with 10+ map providers. Switch between Google Maps, Mapbox, Bing Maps, OpenStreetMap, and more without changing your application code.
Features
- πΊοΈ 10+ Map Providers - Google, Mapbox, Bing, OSM, Azure, Here, TomTom, Yandex, CARTO, MapmyIndia
- π Provider Agnostic - Switch providers with a single line change
- π¦ Zero Dependencies - Standalone library with minimal footprint
- π― Consistent API - Same methods across all providers
- β‘ Lightweight - Lazy loading of provider-specific code
- π§ TypeScript Ready - Full type definitions included
- π Browser Compatible - Works in all modern browsers
- π Production Ready - Battle-tested in real applications
- π¨ Custom HTML Element - Use maps without writing JavaScript
- π Secure API Key Handling - Multiple secure methods for API keys
Installation
NPM
npm install unimapCDN
JavaScript API Only:
<script type="module" src="https://cdn.jsdelivr.net/npm/unimap@latest/build/unimap.mini.js"></script>Custom Element Only:
<script type="module" src="https://cdn.jsdelivr.net/npm/unimap@latest/build/unimap-element.mini.js"></script>Complete (Recommended - Both Features):
<script type="module" src="https://cdn.jsdelivr.net/npm/unimap@latest/build/unimap-complete.mini.js"></script>Quick Start
JavaScript API
import { UniMap } from 'unimap';
const map = new UniMap({
provider: 'google',
apiKey: 'YOUR_API_KEY',
containerId: 'map',
options: {
center: { lat: 40.7128, lng: -74.0060 },
zoom: 12
}
});
await map.init();
// Add marker
map.addMarker({
lat: 40.7128,
lng: -74.0060,
title: 'New York City'
});Custom HTML Element (No JavaScript Required!)
Production (Secure):
<unimap-map
provider="google"
config-endpoint="/api/map-config"
center="40.7128,-74.0060"
zoom="12"
width="100%"
height="500px">
<unimap-marker lat="40.7128" lng="-74.0060" title="New York City"></unimap-marker>
</unimap-map>
<!-- Use complete bundle for both JS API and Custom Element -->
<script type="module" src="./build/unimap-complete.mini.js"></script>Development (Local):
<unimap-map
provider="google"
api-key="YOUR_API_KEY"
center="40.7128,-74.0060"
zoom="12"
width="100%"
height="500px">
</unimap-map>Note: Custom element names must contain a hyphen per Web Components specification. Use <unimap-map> instead of <unimap>.
Supported Providers
| Provider | API Key | Geocoding | Routing | Status |
|---|---|---|---|---|
| Google Maps | Required | β | β | Stable |
| Mapbox | Required | β | β | Stable |
| Bing Maps | Required | β | β | Stable |
| OpenStreetMap | Free | β | β | Stable |
| Azure Maps | Required | β | β | Stable |
| HERE Maps | Required | β | β | Stable |
| TomTom | Required | β | β | Stable |
| Yandex Maps | Required | β | β | Stable |
| CARTO | Required | β | β | Stable |
| MapmyIndia | Required | β | β | Stable |
API Reference
Core Methods
| Method | Description | Parameters | Returns |
|---|---|---|---|
init() |
Initialize map | - | Promise<void> |
destroy() |
Clean up | - | void |
setCenter(coords) |
Set center | { lat, lng } |
void |
getCenter() |
Get center | - | { lat, lng } |
setZoom(level) |
Set zoom | number |
void |
getZoom() |
Get zoom | - | number |
panTo(coords) |
Pan to location | { lat, lng } |
void |
fitBounds(bounds) |
Fit bounds | { southwest, northeast } |
void |
Marker Methods
| Method | Description | Parameters | Returns |
|---|---|---|---|
addMarker(options) |
Add marker | { lat, lng, title, label, icon, color } |
string |
addCustomMarker(options) |
Add custom HTML marker | { lat, lng, html, iconUrl, iconSize, className, title } |
string |
addCustomMarkers(markersArray) |
Add multiple custom markers | array of marker options |
array<string> |
onMarkerClick(markerId, callback, options) |
Add click handler | string, function, {popupHtml, toastMessage} |
string |
removeMarker(id) |
Remove marker | string |
boolean |
updateMarker(id, options) |
Update marker | string, object |
boolean |
Drawing Methods
| Method | Description | Parameters | Returns |
|---|---|---|---|
drawRoute(coords, options) |
Draw route | array, object |
string |
drawPolygon(coords, options) |
Draw polygon | array, object |
string |
drawCircle(center, radius, options) |
Draw circle | object, number, object |
string |
drawRectangle(bounds, options) |
Draw rectangle | object, object |
string |
drawPolyline(coords, options) |
Draw polyline | array, object |
string |
removeLayer(id) |
Remove layer | string |
boolean |
Geocoding & Routing
| Method | Description | Parameters | Returns |
|---|---|---|---|
geocode(address) |
Geocode address | string |
Promise<object> |
reverseGeocode(lat, lng) |
Reverse geocode | number, number |
Promise<object> |
getDirections(origin, destination, options) |
Get directions | object, object, object |
Promise<object> |
Advanced Features
| Method | Description | Parameters | Returns |
|---|---|---|---|
enableTrafficLayer() |
Enable traffic layer | - | void |
disableTrafficLayer() |
Disable traffic layer | - | void |
addHeatMap(points, options) |
Add heat map | array, object |
string |
trackUserLocation(callback, options) |
Track user location | function, object |
void |
getUserLocation() |
Get user location | - | Promise<object> |
enable3D(enable) |
Enable 3D view | boolean |
void |
indoorMaps(enable) |
Enable indoor maps | boolean |
void |
applyMapStyle(style) |
Apply custom style | array |
void |
on(event, callback) |
Add event listener | string, function |
void |
off(event, callback) |
Remove event listener | string, function |
void |
Custom HTML Element
Basic Usage
<unimap-map
provider="google"
config-endpoint="/api/map-config"
center="40.7128,-74.0060"
zoom="12"
width="100%"
height="500px">
</unimap-map>Note: Custom element names must contain a hyphen per Web Components specification. Use <unimap-map>.
Attributes
Required
provider- Map provider:google,mapbox,bing,osm,azure,here,tomtom,yandex,carto,mapmyindia
API Key (Choose One)
config-endpoint- Recommended for production - URL endpoint that returns API keyapi-key- API key directly (β οΈ Development only)
Map Configuration
center- Center coordinates:"lat,lng"(e.g.,"40.7128,-74.0060")zoom- Zoom level:"12"width- Map width:"100%"or"500px"height- Map height:"500px"map-id- Map ID (required for Google Maps Advanced Markers)map-type- Map type:roadmap,satellite,hybrid,terrain
Controls (Boolean)
disable-default-ui- Disable default UIzoom-control- Show zoom controlmap-type-control- Show map type controlscale-control- Show scale controlstreet-view-control- Show street view controlrotate-control- Show rotate controlfullscreen-control- Show fullscreen control
Features (Boolean)
enable-3d- Enable 3D viewenable-traffic- Enable traffic layerenable-indoor- Enable indoor maps
Child Elements
<unimap-marker>
Add a marker to the map.
<unimap-marker lat="40.7128" lng="-74.0060" title="New York"></unimap-marker>
<!-- Custom HTML marker -->
<unimap-marker lat="40.7128" lng="-74.0060">
<div style="background: red; color: white; padding: 8px; border-radius: 50%;">π</div>
</unimap-marker>Attributes: lat, lng, title, label, icon, color, icon-url, icon-size, class-name
<unimap-route>
Draw a route/path.
<unimap-route
coords="40.7128,-74.0060;40.7589,-73.9851;40.7489,-73.9680"
stroke-color="#FF0000"
stroke-weight="5">
</unimap-route>Attributes: coords (format: "lat1,lng1;lat2,lng2;..."), stroke-color, stroke-weight, stroke-opacity
<unimap-polygon>
Draw a polygon.
<unimap-polygon
coords="40.7128,-74.0060;40.7200,-74.0100;40.7150,-74.0200"
stroke-color="#00FF00"
fill-color="#00FF00"
fill-opacity="0.3">
</unimap-polygon>Attributes: coords, stroke-color, stroke-weight, stroke-opacity, fill-color, fill-opacity
<unimap-circle>
Draw a circle.
<unimap-circle
center="40.7128,-74.0060"
radius="1000"
stroke-color="#0000FF"
fill-color="#0000FF"
fill-opacity="0.2">
</unimap-circle>Attributes: center, radius (meters), stroke-color, stroke-weight, stroke-opacity, fill-color, fill-opacity
<unimap-rectangle>
Draw a rectangle.
<unimap-rectangle
bounds="40.7000,-74.0300;40.7300,-73.9800"
stroke-color="#FF00FF"
fill-color="#FF00FF"
fill-opacity="0.2">
</unimap-rectangle>Attributes: bounds (format: "southwest_lat,southwest_lng;northeast_lat,northeast_lng"), stroke-color, stroke-weight, stroke-opacity, fill-color, fill-opacity
<unimap-polyline>
Draw a polyline (same attributes as <unimap-route>).
Complete Example
<!DOCTYPE html>
<html>
<head>
<title>UniMap Example</title>
</head>
<body>
<h1>My Map</h1>
<unimap-map
id="my-map"
provider="google"
config-endpoint="/api/map-config"
center="40.7128,-74.0060"
zoom="12"
width="100%"
height="600px"
map-type="roadmap"
zoom-control="true"
enable-traffic="true">
<!-- Markers -->
<unimap-marker lat="40.7128" lng="-74.0060" title="New York City"></unimap-marker>
<unimap-marker lat="40.7589" lng="-73.9851" title="Times Square" color="red"></unimap-marker>
<!-- Custom HTML Marker -->
<unimap-marker lat="40.7489" lng="-73.9680">
<div style="background: #ff0000; color: white; padding: 8px; border-radius: 50%;">π―</div>
</unimap-marker>
<!-- Route -->
<unimap-route
coords="40.7128,-74.0060;40.7589,-73.9851;40.7489,-73.9680"
stroke-color="#FF0000"
stroke-weight="5">
</unimap-route>
<!-- Circle -->
<unimap-circle
center="40.7128,-74.0060"
radius="1000"
stroke-color="#0000FF"
fill-color="#0000FF"
fill-opacity="0.2">
</unimap-circle>
</unimap-map>
<script type="module" src="./build/unimap-complete.mini.js"></script>
</body>
</html>Programmatic Access
// Get the custom element
const mapElement = document.querySelector('unimap-map');
// Get the UniMap instance
const unimap = mapElement.getUniMap();
// Use UniMap methods
unimap.setZoom(15);
unimap.addMarker({ lat: 40.7128, lng: -74.0060, title: 'New Marker' });
// Set API key programmatically
mapElement.setApiKey('YOUR_API_KEY');
// Set config endpoint programmatically
mapElement.setConfigEndpoint('/api/map-config');Events
// Map initialized
document.addEventListener('unimap:initialized', (event) => {
console.log('Map initialized:', event.detail.unimap);
});
// Map error
document.addEventListener('unimap:error', (event) => {
console.error('Map error:', event.detail.error);
});Important: Custom element names must contain a hyphen per Web Components specification. Use <unimap-map> instead of <unimap>.
Secure API Key Handling
Method 1: Config Endpoint (Recommended for Production)
<unimap-map config-endpoint="/api/map-config" provider="google"></unimap-map>Backend Endpoint Example (Node.js/Express):
app.get('/api/map-config', (req, res) => {
const provider = req.query.provider || 'google';
const apiKeys = {
google: process.env.GOOGLE_MAPS_API_KEY,
mapbox: process.env.MAPBOX_API_KEY
};
res.json({ apiKey: apiKeys[provider] || apiKeys.google });
});Response Format:
{
"apiKey": "AIzaSyC..."
}Method 2: Global Config Function
window.UniMapConfig = function(provider) {
return { apiKey: 'YOUR_API_KEY' }; // Injected server-side
};Method 3: Development Only (Localhost)
<unimap-map api-key="YOUR_API_KEY" provider="google"></unimap-map>β οΈ Warning: Only use api-key attribute for local development. Console warnings appear in production.
Priority Order
config-endpoint(most secure)- Global config function
api-keyattribute (development fallback)- Provider-specific data attributes
Examples
Basic Map
const map = new UniMap({
provider: 'google',
apiKey: 'YOUR_API_KEY',
containerId: 'map',
options: {
center: { lat: 40.7128, lng: -74.0060 },
zoom: 12
}
});
await map.init();Add Markers
// Regular marker
map.addMarker({
lat: 40.7128,
lng: -74.0060,
title: 'New York City'
});
// Custom HTML marker
map.addCustomMarker({
lat: 40.7128,
lng: -74.0060,
html: '<div style="background: red; color: white; padding: 8px;">π</div>'
});Draw Route
map.drawRoute([
{ lat: 40.7128, lng: -74.0060 },
{ lat: 40.7589, lng: -73.9851 }
], {
strokeColor: '#FF0000',
strokeWeight: 5
});Geocoding
const result = await map.geocode('New York, NY');
console.log(result.formattedAddress);
const reverse = await map.reverseGeocode(40.7128, -74.0060);
console.log(reverse.address);Get Directions
const directions = await map.getDirections(
{ lat: 40.7128, lng: -74.0060 },
{ lat: 40.7589, lng: -73.9851 }
);
console.log(directions);Switch Providers
// Just change the provider!
const map = new UniMap({
provider: 'mapbox', // or 'bing', 'osm', 'azure', etc.
apiKey: 'YOUR_API_KEY',
containerId: 'map',
options: { /* same options */ }
});Browser Support
- Chrome/Edge 67+
- Firefox 63+
- Safari 10.1+
- Opera 54+
Build Options
UniMap provides three build options:
unimap.mini.js(121 KB) - JavaScript API onlyunimap-element.mini.js(134 KB) - Custom HTML Element onlyunimap-complete.mini.js(134 KB) - Recommended - Both features in one file
The complete bundle is recommended as it includes both JavaScript API and Custom Element features with minimal size overhead.
Version History
Version 2.3.0 (Current)
β¨ New Features
- Unified Build - New
unimap-complete.mini.jsbundle combining both JS API and Custom Element features - Custom HTML Element - Use maps without writing JavaScript using
<unimap-map>element - Secure API Key Handling - Multiple secure methods for API key management:
- Config endpoint (production recommended)
- Global config function (SSR support)
- Attribute-based (development only)
- Child Elements Support - Declarative markers, routes, shapes via HTML:
<unimap-marker>- Add markers<unimap-route>- Draw routes<unimap-polygon>- Draw polygons<unimap-circle>- Draw circles<unimap-rectangle>- Draw rectangles<unimap-polyline>- Draw polylines
π Bug Fixes
- Critical Fix - Added initialization checks to prevent errors when calling methods before
init() - Fixed OSM adapter destroy method null reference errors
- Fixed race conditions in custom element initialization
- Improved error handling and cleanup on destroy
- Fixed linter errors and code quality issues
π§ Improvements
- Added initialization lock to prevent concurrent initializations
- Improved error messages and user feedback
- Better input validation for all public methods
- Consistent timing for async operations
- Production-ready code with proper error handling
- Enhanced destroy method with null checks
- Better handling of uninitialized instances
π Documentation
- Updated README with complete bundle information
- Added version badges and changelog
- Improved examples and usage documentation
- Added security best practices
Previous Versions
- Version 2.2.0 - Enhanced adapter support, improved geocoding
- Version 2.1.0 - Added new providers (CARTO, MapmyIndia)
- Version 2.0.0 - Major refactor, improved API consistency
- Version 1.x - Initial releases
License
This project is under:
GNU General Public License v3.0 - see LICENSE file for details
You may choose to use this software under either license, depending on your project requirements.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
- Issues: GitHub Issues
- Documentation: Full API Docs
- Wiki: GitHub Wiki
- LinkedIn: Rakesh Ranjan Jena
- Author Blog: rrjprince.com
- Website: rakeshranjanjena.com
Security Considerations
XSS Prevention
UniMap uses intentional innerHTML assignments for custom HTML markers and popups. Always validate and sanitize user-provided HTML content before passing it to:
addCustomMarker({ html: ... })onMarkerClick(..., { popupHtml: ... })addMarker({ title: ... })(in some adapters)
Recommendations:
- Use a trusted HTML sanitization library (e.g., DOMPurify) for user-generated content
- Validate
iconUrlvalues come from trusted sources - Implement Content Security Policy (CSP) headers to mitigate XSS risks
- Never use unsanitized user input directly in HTML properties
URL Injection Prevention
All user-provided coordinates and addresses are properly encoded using encodeURIComponent() before being used in API URLs. This prevents URL injection attacks.
API Key Security
- API keys are never logged or exposed in error messages
- Store API keys securely (environment variables, secure config files)
- Never commit API keys to version control
- Use API key restrictions in provider dashboards (domain/IP restrictions)
Input Validation
All adapters validate:
- Coordinates are numeric and within valid ranges (-90 to 90 for latitude, -180 to 180 for longitude)
- Addresses are non-empty strings
- Required parameters are present before API calls
Made with β€οΈ by Rakesh Ranjan Jena
UniMap - One API for All Map Providers πΊοΈ