npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geoleaf-plugins/cog

v1.0.5

Published

GeoLeaf COG Plugin — Load and render Cloud Optimized GeoTIFF files as MapLibre image layers

Readme

@geoleaf-plugins/cog

GeoLeaf plugin for displaying Cloud Optimized GeoTIFF (COG) raster files on a MapLibre GL map. From a single HTTP/HTTPS URL pointing to a .tif/.tiff, the plugin reads the file's headers via HTTP Range requests, decodes the needed pixels with geotiff.js, and injects the result as a georeferenced MapLibre image source + raster layer.

  • MIT — published on npmjs.org
  • Requires @geoleaf/core loaded before this plugin
  • ESM only — no CommonJS/UMD
  • No runtime configuration: the API is available on GeoLeaf.COG as soon as the plugin loads

Installation

npm install @geoleaf-plugins/cog

Load in your HTML after @geoleaf/core and before GeoLeaf.boot():

<script type="module" src="node_modules/@geoleaf-plugins/cog/dist/geoleaf-cog.plugin.js"></script>

The core must be present and initialised first; no other plugin is required (requires: []).


API — GeoLeaf.COG.*

The public API is intentionally minimal: three functions.

addLayer(url, map, options?)

Loads a COG, decodes it, and adds it to the map. Returns a handle for later updates/removal.

const handle = await GeoLeaf.COG.addLayer(
    "https://example.com/imagery.tif",
    GeoLeaf.Core.getMap().getNativeMap(),
    { opacity: 0.8 }
);

handle.id; // MapLibre source + layer id
await handle.update({ opacity: 0.4 }); // re-render with new options (reuses cached headers)
handle.remove(); // remove source + layer

The full pipeline runs on each addLayer() / handle.update(): validate URL → read headers (getCogInfo) → select overview → fetch rasters → decode to Canvas → PNG data URL → addSource({ type: "image" }) + addLayer({ type: "raster" }). Only the CogInfo metadata is cached (so update() does not re-fetch the file headers).

getInfo(url, options?)

Reads COG metadata without downloading any pixels (TIFF headers only).

const info = await GeoLeaf.COG.getInfo("https://example.com/imagery.tif");
// { url, bounds: [W, S, E, N], width, height, bandCount, nodata, overviewCount, epsg }

removeLayer(map, layerId)

Removes a COG layer and its source. Safe to call even if already removed.

GeoLeaf.COG.removeLayer(map, handle.id);

Options (addLayer)

All optional — only the URL is required.

| Option | Type | Default | Description | | ---------- | ----------------------------------- | --------------------------- | --------------------------------------------------- | | id | string | cog-layer-{timestamp}-{n} | Explicit source/layer id | | opacity | number | 1 | Raster opacity (0–1) | | overview | "auto" \| number | "auto" | Overview index, or auto-select from viewport width | | bands | [n] or [r, g, b] (1-based) | first bands | Band selection (grayscale or RGB / false color) | | colorMap | Array<[r, g, b, a]> (256 entries) | grayscale | LUT applied to single-band rendering | | nodata | number | value from file metadata | Pixels equal to this value are rendered transparent | | maxBytes | number | 52428800 (50 MB) | Memory guard before fetching rasters | | signal | AbortSignal | — | Cancels an in-flight load |

// False-color CIR (NIR/Red/Green) on a multi-spectral COG:
await GeoLeaf.COG.addLayer(url, map, { bands: [8, 4, 3] });

// Single-band DEM with a color palette:
await GeoLeaf.COG.addLayer(url, map, { bands: [1], colorMap: my256ColorLut });

Types

interface CogInfo {
    url: string;
    bounds: [number, number, number, number]; // [west, south, east, north] WGS84
    width: number;
    height: number;
    bandCount: number; // 1 = grayscale, 3 = RGB, 4 = RGBA
    nodata: number | null;
    overviewCount: number;
    epsg: number | null; // e.g. 4326, 3857, 32631
}

interface CogLoadOptions {
    signal?: AbortSignal;
    maxBytes?: number; // default 52 428 800 (50 MB)
}

interface CogLayerOptions extends CogLoadOptions {
    id?: string;
    opacity?: number; // default 1
    overview?: "auto" | number; // default "auto"
    bands?: [number, number, number] | [number]; // 1-based
    colorMap?: Array<[number, number, number, number]>; // 256 RGBA entries
    nodata?: number;
}

interface CogLayerHandle {
    id: string;
    remove(): void;
    update(opts: Partial<CogLayerOptions>): Promise<void>;
}

Constraints

  • HTTP/HTTPS only — file:// and relative URLs are rejected with a TypeError.
  • CORS required — the COG host must send Access-Control-Allow-Origin; the browser blocks cross-origin reads otherwise.
  • Projection — the plugin extracts the bounds and EPSG code but does not reproject pixels. Serve COGs in EPSG:4326 or EPSG:3857 for correct placement on a Web Mercator map.
  • Static image, not dynamic tiling — the layer is a single PNG injected into MapLibre; it is not re-rendered on zoom. For XYZ dynamic tiling use a server (Titiler, GeoServer).
  • Overviews recommended — internal TIFF overviews (COG/GDAL) keep loads small. A non-tiled GeoTIFF still works but reads the full image.
  • Memory guard — maxBytes (50 MB default) caps a single raster fetch; raise it for large overviews or use a higher overview index.

Licence

MIT — © 2026 Mattieu Pottier. See LICENSE.