How the SDK works
The SDK is one npm package, @tomtom-org/maps-sdk, with three entry points: Map draws the map, Services calls TomTom's location APIs, and Core holds what both share. Use any of them on its own or together.
The playground below is the Map bundle alone: a TomTomMap configured once through Core, with no service call.
The three bundles
| Bundle | Import path | Runs in | Holds | Start with |
|---|---|---|---|---|
| Map | @tomtom-org/maps-sdk/map |
Browser | TomTomMap and its modules |
Map introduction |
| Services | @tomtom-org/maps-sdk/services |
Browser, Node.js, React Native | One async function per TomTom API | Services quickstart |
| Core | @tomtom-org/maps-sdk/core |
Anywhere | TomTomConfig, shared types, utilities |
Core quickstart |
- Map and Services never depend on each other. Both depend on Core, so Services runs on a server with no map, and Map draws your own data with no service.
- They meet through Core's GeoJSON types. What a service returns is what a map module shows, unchanged: no adapter in between.
- Everything is tree-shakable. Your bundle carries only the modules and services you import.
Data flow
import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
import { discoverPlaces } from '@tomtom-org/maps-sdk/services';
import { PlacesModule, TomTomMap } from '@tomtom-org/maps-sdk/map';
TomTomConfig.instance.put({ apiKey: 'YOUR_API_KEY', language: 'en-GB' });
const map = new TomTomMap({ mapLibre: { container: 'map', center: [4.9, 52.37], zoom: 13 } });
const places = await PlacesModule.create(map);
await places.show(await discoverPlaces({ query: 'coffee', geoBias: { position: [4.9, 52.37] } }));
TomTomConfigholds the API key and language once, for the map and every service call.discoverPlacesmerges that configuration under its own parameters, calls the API, and resolves to a GeoJSONFeatureCollectionofPlacefeatures.PlacesModule.showtakes that collection as it is, and draws it on its own sources and layers.
Map
TomTomMapwraps a MapLibreMap: it loads a TomTom style, applies the global configuration, and keeps the MapLibre instance reachable asmap.mapLibreMap(when to use the SDK or MapLibre).- Modules add everything else, each one area of the map, and come in two kinds:
- Style-owned, from
get(map): the parts the style already draws, such as the base map, POIs, traffic and terrain. One instance per map. - Data-owned, from
create(map): the data you show, such as places, routes, geometries and your own GeoJSON. As many instances as you need.
- Style-owned, from
- Modules survive style switches.
await map.setStyle(…)restores every module's data and settings on the new style (Map styles). - Every setting is data. Each module's configuration has stable knob ids, set the same way on every module (Every setting as data), and map styling restyles the map at runtime.
- Events are typed per module: a click on a place pin hands you the
Placeyou showed (User events).
Services
- One async function per API: search and geocoding in Places, route calculation and reachable ranges in Routing, incident details and area analytics in Traffic.
- The global configuration is the baseline: a call's own parameters win for that call only (Global configuration).
- Results are typed GeoJSON for places, routes, reachable ranges, geometries and traffic. The POI category, EV availability and search-suggestion services return plain objects.
- Every call takes the same request options: validation, lifecycle hooks, an
AbortSignal, and typed errors (Request options and errors).
Core
- Global configuration:
TomTomConfig.instance.put({ apiKey, language, … })once, read by the map and every service. - Shared types:
Place,Routeand the traffic types, the shape both bundles agree on. - Utilities that need no map: bounding boxes, coordinates, formatting and route progress.
Next steps
- Map only, with your own data: the Map quickstart.
- Services only, in Node.js, a browser or React Native: the Services quickstart.
- Both: the examples gallery, where most apps combine them.