When my recent project build came out at 2 megabytes for something that should have been dead simple, I realised bundling Maplibre, the webgl-based map library, was adding a lot of bulk.
Since we use maps in various projects and we don’t need to duplicate the library for each project/release I wanted to split it out onto our CDN and import it as required.
This guide is specific to MapLibre GL JS, but could apply to any large library, really.
Import the library
Maplibre isn’t an ES module, and I’m using a webpack config that won’t allow import()
, so I wrote a small function to load a module as a global:
const promises = {};
function importModule(url) {
if (promises[url]) {
return promises[url];
}
promises[url] = new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = url;
s.type = 'module';
s.addEventListener('load', resolve);
s.addEventListener('error', reject);
document.head.appendChild(s);
});
return promises[url];
}
From here we can load MapLibre from wherever we like. The docs suggest unpkg:
importModule('https://unpkg.com/maplibre-gl@^5.3.0/dist/maplibre-gl.js')
.then(() => {
console.log(window.maplibregl);
});
Adding Typescript types to the CDN library
This works fine, but now Typescript has no idea what’s going on. We need to import the types.
Turns out you can plop a .d.ts file in the same directory as your code and Typescript will pick it up and provide types for the global variable.
Maplibre distributes .d.ts files in their releases, so I downloaded the release corresponding to my CDN version, unzipped the file, and placed it in the directory where I’m using maplibre. As if by magic, Typescript and JSDoc are now available:

Importing additional types
When you need specific types from the .d.ts file, you can import them as types. This seems obvious, but I got caught up with this.
import type { MapOptions } from './maplibre-gl';
const mapOptions = {
container: mapRootEl,
interactive: false
} as MapOptions;
map = new Map(mapOptions);
There’s two gotchas, don’t include .d.ts in the import name. Typescript will find it without, and complain with. Also make sure to import as type
otherwise your build may fail.
And that’s about it. Everything TIL.