The MapConductor React SDK modules have been updated: 19 of the 21 packages on npm moved. Most of it is dependency maintenance, but two fixes around MapLibre are for failures that are hard to diagnose when you hit them.
The versions are deliberately not aligned. react-for-maplibre and react-for-openlayers are at 0.2.2; react-icons and react-kml stay where they were; the rest are at 0.2.1. Unlike 0.2.0, we no longer put every package on the same number: bumping a package whose contents did not change tells the person upgrading only that "something changed".
The map renders as a background colour, and nothing throws
This is what react-for-maplibre 0.2.2 is about.
MapLibre GL JS v6 ships its Web Worker as a separate file and builds the URL for it from its own import.meta.url. Run that through a bundler and the value is folded in at build time — a file:// path under Rspack, the pre-bundle location under Vite — while the worker's real file is emitted nowhere. Resolution fails.
The awkward part is that failure throws nothing. Something like new Worker("") is created silently and the map stops without issuing a single tile request. What you see is a map made of background colour. If the network panel shows zero .pbf requests, this is the symptom.
0.2.2 bundles a self-contained worker with the package and registers it automatically when the first map is created. There is nothing to configure. It behaves the same under Vite and under webpack / Rspack, in dev and in production builds.
There is one exception: serving the worker from your own URL (a shared CDN, or a build that already emits one). Call setMapLibreWorkerUrl(url) before the first map is created and the bundled worker is skipped — and never downloaded.
import { setMapLibreWorkerUrl } from '@mapconductor/react-for-maplibre';
setMapLibreWorkerUrl('https://cdn.example.com/maplibre-worker.mjs');One thing to expect: Vite's dev server runs the bundled worker through its transform pipeline, which injects an import of /@vite/client and inflates the file (roughly 478KB → 2.8MB). It looks alarming and changes nothing about behaviour; production builds emit it as a plain asset.
Handing the worker over as a Blob URL does not work under v6. The worker starts without error and still issues no tile requests. It has to be served as a real file.
onMapLoaded never fired
Also react-for-maplibre 0.2.2.
MapLibreProvider.initialize() awaits map.once('load') before it creates the controller. By the time the controller exists the load has already happened, so the on('load') that setupEventListeners attaches can never fire again.
The already-initialised check in the constructor was meant to cover that case, and did not: both loaded() and isStyleLoaded() return false immediately after load. MapLibre v6's isStyleLoaded() calls Style.loaded(), which waits for every tileManager to finish.
Fixed in 0.2.2. If you were using onMapLoaded, it had never been called.
js-sdk-core 0.2.1 — the Service Worker died when there were too many distinct icons
Marker icons reach the tile Service Worker as bitmaps. They were collected one at a time and posted together at the end, so with more distinct icons than the cache holds, the ones collected first had already been released by the time the payload went out. Structured-cloning a released ImageBitmap throws DataCloneError, and that takes the whole Service Worker registration with it.
With no registration, no tile ever arrives — so what you see is a map that does not appear. And it only reproduces once the number of distinct icons passes the cache size: the shape of bug that works on your machine and stops in production.
The fix is not a bigger cache. It is ownership: the payload now carries copies it owns, and frees them once the post has returned. What the cache owns is left alone.
TomTom no longer carries a second MapLibre
In 0.2.0, react-for-tomtom was the one module held back on maplibre-gl 5.x, because @tomtom-org/maps-sdk depended on maplibre-gl@^5.24.0. Moving to 6.x would have installed two copies of MapLibre and handed the TomTom SDK a map object it did not expect.
TomTom moved to maplibre-gl@^6.4.0 in 0.51.5. react-for-tomtom 0.2.1 follows with ^6.6.0. It now shares one MapLibre with react-for-maplibre and react-for-maptiler, and the caveat from 0.2.0 no longer applies.
A side effect: react-for-tomtom now loads under Node's ESM resolver. It did not in 0.2.0, where the reason was that it "reads maplibre-gl/package.json, which Node will only load with an import attribute". Measured by importing the published packages in an empty project.
import | require() | |
|---|---|---|
react-for-tomtom 0.2.0 | no | no |
react-for-tomtom 0.2.1 | yes | no |
require() still fails because maplibre-gl v6 is ESM-only and declares no CommonJS entry — the same reason as react-for-maplibre and react-for-maptiler. Use those three through ESM.
Four 0.2.1 releases carry no code change
The 0.2.1 releases of js-sdk-react, react-geojson, react-heatmap and react-marker-clustering ship the same JavaScript as 0.2.0. What moved is build metadata carried inside the package, which a web build never reads. There is no urgency in taking them, and no harm either.
Map SDK updates
Brought to the newest version within the declared range. These are the ones that moved.
| Dependency | 0.2.0 | Now |
|---|---|---|
mapbox-gl | ^3.15.0 | ^3.29.0 |
maplibre-gl | ^6.0.0 | ^6.6.0 |
cesium | ^1.131.0 | ^1.144.0 |
ol | ^10.2.1 | ^10.10.0 |
@arcgis/core | ^5.1.16 | ^5.1.20 |
@tomtom-org/maps-sdk | ^0.51.0 | ^0.51.5 |
azure-maps-control | ^3.7.0 | ^3.7.4 |
@turf/turf | ^7.3.5 | ^7.4.0 |
Three stayed put — leaflet ^1.9.4, @googlemaps/js-api-loader ^2.1.1 and mappls-web-maps ^3.8.1 — because upstream has not moved. React's peerDependencies remain ^18.0.0 || ^19.0.0; only the development version changed (19.2.7 → 19.2.8).
The packages and their map SDKs
HERE, Apple MapKit JS and Longdo carry no map SDK as a dependency because those SDKs are not distributed on npm. They load from the vendor's CDN at runtime, so the version that actually runs is whatever the vendor is serving.
Upgrading
npm install @mapconductor/js-sdk-core@latest @mapconductor/js-sdk-react@latest \ @mapconductor/react-for-maplibre@latest
js-sdk-core is at 0.2.1 too. It carries the Service Worker fix above, so if you use many distinct marker icons, take this one.
ESM, CommonJS and SSR behave as they did in 0.2.0, apart from react-for-tomtom above. The full table of what does and does not load outside a bundler is in the React SDK 0.2.0 post. Each package lives in its own repository — see github.com/MapConductor.