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

orbitos

v0.1.2

Published

A rotating sphere of labeled points for React — render any set of skills, links, projects, or facts as an animated 3D-style particle globe on plain HTML5 Canvas.

Readme

OrbitOS

npm version Buy Me a Coffee

A rotating sphere of labeled points for React: render any set of skills, links, projects, radio stations, offices, or facts as an animated, 3D-style particle globe. Two modes: an abstract point-cloud sphere, or an actual world map with continent outlines and points plotted by real lat/lng. Pure HTML5 Canvas 2D, no Three.js/WebGL, no charting library.

| Sphere mode | Globe mode | | --- | --- | | Sphere mode, mono palette, light background | Globe mode, mono palette, light background |

See it in action

OrbitOS grew out of the sphere on my own portfolio site. A few places it (or the code it was extracted from) shows up:

There's also a live, interactive version of the example/ app (toggle mode, colors, and background) hosted on GitHub Pages: live demo.

Why

Most "3D sphere" components pull in a full WebGL stack for something that's really just a rotating point cloud with a few floating labels. OrbitOS does the projection math by hand on a plain <canvas>, small, dependency-free, and easy to read if you want to tweak it.

Dependencies

Runtime: zero. react and react-dom are peer dependencies only, and nothing else ships in the published package, no Three.js, no charting library, no map library. Globe mode's continent outlines are pre-baked at src/worldOutline.ts from the world-atlas land-110m dataset (public domain, via Natural Earth) using a one-off local script (scripts/build-world-outline.mjs); that conversion runs once at dev time, not in your app.

Everything else is dev-only tooling: tsup bundles src/ to dist/ (ESM + CJS + types), and TypeScript type-checks it. The example/ app (the live demo) is a separate Vite + React project with its own package.json, not part of the published package.

Install

npm install orbitos

react and react-dom (>=18) are peer dependencies, so use whatever version your app already has.

git clone https://github.com/btbatson/OrbitOS.git
cd OrbitOS
npm install
npm run build

Then link it into a project with npm link, or npm install ../OrbitOS.

Usage

import { OrbitGlobe } from "orbitos";

const points = [
  { label: "Frontend", name: "React", color: "#2563eb" },
  { label: "Backend", name: "Node.js", color: "#059669" },
  { label: "AI / LLM", name: "Claude", color: "#7c3aed" },
  { label: "Cloud", name: "AWS", color: "#d97706" },
];

export default function Example() {
  return (
    <div style={{ width: 480, height: 480 }}>
      <OrbitGlobe points={points} centerImage="/avatar.png" />
    </div>
  );
}

World map mode

Switch mode="globe" and give points a real location instead of a color-only callout, useful for radio stations, offices, or anywhere with a real address:

const stations = [
  { label: "Kenya", name: "Nairobi FM", color: "#22c55e", location: { lat: -1.29, lng: 36.82 } },
  { label: "UK", name: "London Radio", color: "#22c55e", location: { lat: 51.51, lng: -0.13 } },
];

<OrbitGlobe points={stations} mode="globe" />;

OrbitGlobe must be rendered in a client component (it uses "use client" internally, so this only matters if you're on Next.js App Router, no extra setup needed).

Props

| Prop | Type | Default | Description | | ------------------ | ------------------------ | ------------------------- | ------------------------------------------------------------------ | | points | OrbitPoint[] | (required) | The labeled callouts orbiting the sphere. | | mode | "sphere" \| "globe" | "sphere" | Abstract particle sphere, or an actual world map with continents. | | centerImage | string | undefined | Image URL shown glowing at the center (e.g. an avatar/logo). | | maxSize | number | 700 | Max pixel size; shrinks to fit its parent below this. | | ambientDotCount | number | 1800 | Ambient background particle count (sphere mode only). | | ambientColors | string[] | grayscale set | Palette for the ambient sphere dots (sphere mode only). | | palette | string[] | 9-color default | Fallback dot/card color for points without an explicit color. | | rotationSpeed | number | 0.00011 | Radians of rotation per millisecond. | | globeFillColor | string | "#0a0a0f" | Planet base fill color (globe mode only). | | globeLineColor | string | "rgba(255,255,255,0.35)" | Continent outline / grid line color (globe mode only). | | showGraticule | boolean | true | Whether to draw a faint lat/lng grid (globe mode only). | | className | string | undefined | Extra class on the wrapper element. | | style | CSSProperties | undefined | Extra inline styles on the wrapper element. |

OrbitPoint

type OrbitPoint = {
  label: string;                                    // small eyebrow text
  name: string;                                      // main callout text
  color?: string;                                    // dot/accent color
  position?: { x: number; y: number; z: number };    // fixed spot on the unit sphere (sphere mode)
  location?: { lat: number; lng: number };           // real-world position (globe mode)
};

If neither position nor location is given, points are spread evenly across the sphere using a golden-angle spiral so callouts don't cluster on one side.

How it works

Sphere mode: a few thousand tiny particles are distributed over a unit sphere (golden-angle spiral) and projected to 2D each frame with hand-written rotation/perspective math, no matrix library needed for a single-axis auto-rotate.

Globe mode: continent outlines come from a simplified Natural Earth coastline dataset (public domain, via world-atlas), embedded as plain lat/lng polylines and projected through the same rotation math, no map library, no tiles, no network requests.

In both modes, your points become colored dots at fixed (or real-world) positions on the sphere. When one rotates to the front, it fades in a floating label card with simple rectangle-overlap collision detection so cards never stack. Rendering pauses automatically via IntersectionObserver when the globe scrolls out of view.

Hosting the example

The example/ app auto-deploys to GitHub Pages via .github/workflows/deploy-example.yml on every push to main. One-time setup on GitHub:

  1. Go to the repo's Settings > Pages.
  2. Under "Build and deployment", set Source to GitHub Actions.
  3. Push to main (or run the workflow manually from the Actions tab).

It'll be live at https://<your-username>.github.io/OrbitOS/. To run it locally instead:

cd example
npm install
npm run dev

Support

If OrbitOS is useful to you, consider buying me a coffee.

License

MIT