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

@geoql/maplibre-gl-starfield

v0.1.1

Published

A MapLibre GL JS custom layer for rendering a Three.js starfield skybox with galaxy panorama

Readme

@geoql/maplibre-gl-starfield

Three.js starfield skybox custom layer for MapLibre GL JS globe projections.

npm version JSR npm bundle size License: MIT

oxlint tsdown typescript

Live Demo

Renders an optional equirectangular galaxy/milky-way panorama texture with configurable brightness, plus thousands of individual point stars with additive blending. Perfect for globe-projection maps that need a space-like background — earthquake visualizations, satellite trackers, flight paths, and more.

Installation

# npm
npm install @geoql/maplibre-gl-starfield maplibre-gl three

# pnpm
pnpm add @geoql/maplibre-gl-starfield maplibre-gl three

# yarn
yarn add @geoql/maplibre-gl-starfield maplibre-gl three

# bun
bun add @geoql/maplibre-gl-starfield maplibre-gl three

# JSR
bunx jsr add @geoql/maplibre-gl-starfield

Usage

import maplibregl from 'maplibre-gl';
import { MaplibreStarfieldLayer } from '@geoql/maplibre-gl-starfield';
import 'maplibre-gl/dist/maplibre-gl.css';

const map = new maplibregl.Map({
  container: 'map',
  style: {
    version: 8,
    projection: { type: 'globe' },
    sources: {
      satellite: {
        type: 'raster',
        tiles: [
          'https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg',
        ],
        tileSize: 256,
        attribution: '© EOX IT Services GmbH - S2 Cloudless',
      },
    },
    layers: [{ id: 'satellite', type: 'raster', source: 'satellite' }],
  },
  center: [0, 20],
  zoom: 1.5,
});

map.on('load', () => {
  const starfield = new MaplibreStarfieldLayer({
    galaxyTextureUrl: '/milkyway.jpg', // your panorama image
    galaxyBrightness: 0.35,
    starCount: 4000,
    starSize: 2.0,
  });

  // Add below all other layers so stars render behind the globe
  map.addLayer(starfield, map.getStyle().layers[0]?.id);
});

Options

interface MaplibreStarfieldLayerOptions {
  id?: string;
  starCount?: number;
  starSize?: number;
  starColor?: number;
  galaxyTextureUrl?: string;
  galaxyBrightness?: number;
}

| Option | Type | Default | Description | | ------------------ | -------- | ------------- | ------------------------------------------------------------------------------ | | id | string | 'starfield' | Unique layer ID | | starCount | number | 4000 | Number of individual point stars | | starSize | number | 2.0 | Base point size for stars (randomized ±60%) | | starColor | number | 0xffffff | Hex color for point stars | | galaxyTextureUrl | string | undefined | URL to an equirectangular panorama image. If omitted, only point stars render. | | galaxyBrightness | number | 0.35 | Brightness multiplier for the galaxy texture (0–1) |

Galaxy Texture

This library does not bundle a galaxy image. You need to provide your own equirectangular panorama via galaxyTextureUrl.

A great free option is the ESO/S. Brunier Milky Way panorama (source), licensed under CC BY 4.0. Download and resize to ~4096×2048 for a good balance of quality and file size:

# Download the 6000×3000 original (8 MB)
curl -o milkyway_full.jpg "https://cdn.eso.org/images/large/eso0932a.jpg"

# Resize to 4096×2048 (~3 MB)
sips --resampleWidth 4096 milkyway_full.jpg --out public/milkyway.jpg

Attribution: ESO/S. Brunier — CC BY 4.0

How It Works

The layer implements MapLibre's CustomLayerInterface and shares the WebGL context with MapLibre:

  1. Galaxy sphere — A Three.js SphereGeometry with BackSide rendering, textured with the panorama image. Rendered at near-infinite depth via a vertex shader trick.
  2. Point stars — Thousands of Points with per-vertex random size and opacity, rendered with additive blending for a natural glow.
  3. Camera sync — The projection matrix is decomposed from MapLibre's model-view-projection matrix, with translation stripped so the skybox stays at infinity regardless of zoom/pan.

Exports

// Main class
export { MaplibreStarfieldLayer } from '@geoql/maplibre-gl-starfield';

// Default export (same class)
export { default } from '@geoql/maplibre-gl-starfield';

// Types
export type { MaplibreStarfieldLayerOptions } from '@geoql/maplibre-gl-starfield';

Requirements

  • MapLibre GL JS >= 3.0.0
  • Three.js >= 0.135.0
  • Node.js >= 24.0.0

Contributing

  1. Fork and create a feature branch from main
  2. Make changes following conventional commits
  3. Ensure commits are signed (why?)
  4. Submit a PR
bun install
bun run build
bun run lint
bun run typecheck

License

MIT