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

ascii-globe

v0.4.2

Published

Isomorphic ASCII globe renderer

Readme

ASCII-Globe

npm github repo NPM Downloads jsDelivr hits (npm) LICENSE MIT

Zero dependencies isomorphic ASCII-Art globe renderer in JavaScript.

See Live Demo

Installation

npm

npm install ascii-globe

CDN

<!-- IIFE (global variable) -->
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>

<!-- ES Module -->
<script type="module">
import Globe from 'https://esm.run/ascii-globe';
</script>

Usage

ES Module (Node.js / Vite / bundlers)

import Globe from 'ascii-globe';

const globe = new Globe({ size: 1.4 });
console.log(globe.render(90));

CommonJS (Node.js)

const Globe = require('ascii-globe');

const globe = new Globe({ size: 1.4 });
console.log(globe.render(90));

Browser (script tag)

<pre id="output"></pre>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script>
var globe = new Globe({ size: 1 });
document.getElementById('output').textContent = globe.render(0);
</script>

Browser (ES Module)

<pre id="output"></pre>
<script type="module">
import Globe from 'https://esm.run/ascii-globe';

const globe = new Globe({ size: 1 });
document.getElementById('output').textContent = globe.render(0);
</script>

API

new Globe(options?)

Creates a new globe instance.

| Option | Type | Default | Description | |----------------|----------|---------|-----------------------------------------------------| | size | number | 1.4 | Scale factor. 1 produces a 120x60 character grid. | | map | string | — | Base64-encoded map data. Defaults to the built-in Earth map. | | land | string | '#' | Character used to render land masses. | | water | string | '-' | Character used to render water/ocean. | | background | string | ' ' | Character used for the area outside the globe disk. | | margin | number | 0 | Number of characters around the globe disk. | | marginBlock | number | 0 | Vertical margin (overrides margin). | | marginInline | number | 0 | Horizontal margin (overrides margin). | | pin | string | '@' | Default character for location pins. Can include ANSI escape codes. | | pinSize | number | 1 | Default size multiplier for pin markers. | | pins | Pin[] | [] | Array of pin locations. | | tilt | number | 0 | Axial tilt in degrees (Earth's tilt is 23.5°). | | speed | number | 0.7 | Rotation speed in degrees per frame. | | format | function | — | Callback (type, length) => string for custom output (see below). |

Pin object

| Property | Type | Required | Description | |----------|----------|----------|--------------------------------------------------------------------| | lat | number | yes | Latitude in degrees (-90 to 90). | | long | number | yes | Longitude in degrees (-180 to 180). | | char | string | no | Override character for this pin. Can include ANSI escape codes. | | size | number | no | Size multiplier for this pin (overrides pinSize). |

format(type, length)

When provided, render() calls this function for each run of consecutive cells of the same type instead of using the land/water/background/pin characters. This lets you wrap output in HTML tags, ANSI codes, or any other markup.

| Type value | Meaning | |------------|------------| | 0 | Background | | 1 | Water | | 2 | Land | | 3+ | Pin (index type - 3 in the pins array) |

Example — HTML colored output:

const globe = new Globe({
  size: 1,
  pins: [{ lat: 52.23, long: 21.01 }],
  format(type, length) {
    const chars = [' ', ' ', '#', '@'];
    const colors = ['', '', 'green', 'red'];
    const text = chars[type].repeat(length);
    if (!colors[type]) return text;
    return `<span style="color:${colors[type]}">${text}</span>`;
  }
});

pre.innerHTML = globe.render(250);

Custom maps

The library ships with an Earth map by default, but you can use a different map by passing the map option. The package includes a built-in Death Star map:

import Globe from 'ascii-globe';
import deathStar from 'ascii-globe/maps/death-star';

const globe = new Globe({ map: deathStar, land: '#', water: ' ' });
console.log(globe.render(0));

With a script tag (no modules), load the map as a separate script. The load order doesn't matter:

<pre id="output"></pre>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe/dist/maps/death-star.global.js"></script>
<script>
var globe = new Globe({ map: Globe.maps['death-star'], land: '#', water: ' ' });
document.getElementById('output').textContent = globe.render(0);
</script>

You can also generate your own map data from any equirectangular projection image (see Generating custom map data below).

globe.render(rotation)

Returns a string with the ASCII globe rendered at the given rotation.

  • rotation — a single number (horizontal angle in degrees) or a [horizontal, vertical] pair. Values wrap around automatically.
globe.render(90);       // horizontal rotation only
globe.render([90, 30]); // horizontal + vertical tilt

CLI

npx ascii-globe --rotation 200
npx ascii-globe --animate

Or install globally:

npm install -g ascii-globe
globe --rotation 200
globe --animate
ASCII Globe v0.4.2 - Isomorphic ASCII globe renderer

Usage: globe <--rotation <degrees> | --animate> [options]

Options:
  --rotation <degrees>  Rotation angle (single number or h,v pair)
  --animate             Animate the globe in the terminal
  --size <number>       Globe size multiplier (default: 1.4)
  --map <file>          Path to a map data file (generated by extract-texture)
  --land <char>         Character for land (default: #)
  --water <char>        Character for water (default: -)
  --background <char>   Character for background (default: " ")
  --margin <number>     Characters around the globe (default: 0)
  --margin-block <n>    Vertical margin (overrides --margin)
  --margin-inline <n>   Horizontal margin (overrides --margin)
  --pin <char>          Character for location pins (default: @)
  --pin-size <number>   Size of pin markers (default: 1)
  --pins <coords>       Pin locations as lat,long pairs separated by ;
  --tilt <degrees>      Axial tilt in degrees (default: 0)
  --speed <number>      Rotation speed in degrees per frame (default: 0.7)
  --help                Show this help message
  -v, --version         Show version number

Either --rotation or --animate is required.

Example with pins (Warsaw and New York):

globe --rotation 250 --pins '52.23,21.01;40.71,-74.01'
globe --rotation 250 --pin '\x1b[31m@\x1b[m' --pins '52.23,21.01'

Example with a custom map:

globe --rotation 40,20 --map ./my-map.js --land '#' --water ' '

Examples

Node.js terminal animation

import Globe from 'ascii-globe';

const globe = new Globe({ size: 1, land: '#', water: ' ', tilt: 23.5 });

let rotation = 0;

process.stdout.write('\x1B[?25l'); // hide cursor

setInterval(() => {
  process.stdout.write('\x1B[2J\x1B[H'); // clear + home
  process.stdout.write(globe.render(rotation));
  rotation = (rotation + globe.speed) % 360;
}, 1000 / 30);

Run the included example:

npm run example:node

Browser animation

<pre id="globe"></pre>
<button id="toggle">Pause</button>
<input id="rotation" type="number" min="0" max="360" step="0.1" value="0" disabled>

<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script>
var globe = new Globe({ size: 1, land: '#', water: ' ' });
var pre = document.getElementById('globe');
var playing = true;
var rotation = 0;

function loop() {
  pre.textContent = globe.render(rotation);
  if (playing) {
    rotation = (rotation + 0.7) % 360;
    requestAnimationFrame(loop);
  }
}

document.getElementById('toggle').addEventListener('click', function() {
  playing = !playing;
  if (playing) loop();
});

loop();
</script>

Open examples/browser/index.html via a local server to run the included browser demo.

Generating custom map data

You can generate map data from any equirectangular projection image (2:1 aspect ratio PNG). The extract script is included in the repository:

npx tsx scripts/extract-texture.ts <image.png> --output <output.ts>

Options:

| Flag | Description | |----------------|----------------------------------------------------------| | --output <path> | Output file path (default: src/maps/<name>.ts) | | --grayscale | Use brightness instead of Earth-specific color detection | | --alpha | Use the alpha channel as the mask (opaque = land) | | --invert | Invert the mask (swap land and water) |

The default mode classifies pixels using Earth-specific color heuristics (blue → water, dark → land). Use --grayscale or --alpha for non-Earth images.

The output file can be imported and passed to the map option:

import Globe from 'ascii-globe';
import myMap from './my-map.ts';

const globe = new Globe({ map: myMap });

Or used with the CLI:

globe --rotation 90 --map ./my-map.ts

Building from source

npm install
npm run extract   # generate src/maps/ from globe.png and death-star.png
npm run build     # compile TypeScript to dist/

Acknowledgments

World map texture by Ebrahim; CC BY-SA 4.0; source Wikimedia Commons.

License

Copyright (c) 2025 Jakub T. Jankiewicz

Released under the MIT License. See LICENSE for details.