@esosdev/astro-globe
v1.0.0
Published
React + Three.js (R3F) 3D Earth, satellites and orbit rendering, with a pure-TS orbital core
Readme
@esosdev/astro-globe
React + Three.js (react-three-fiber) 3D Earth, satellites and orbit rendering, with a pure-TypeScript orbital core. Single package, three entry points:
| Import | Contents | React? |
|--------|----------|--------|
| @esosdev/astro-globe | Scene, building blocks, data hooks | yes (R3F) |
| @esosdev/astro-globe/core | SGP4/Chebyshev/RPO maths, ECI/ECEF, country | no |
| @esosdev/astro-globe/sensors | look angles, visibility, pass prediction | no |
| @esosdev/astro-globe/assetBase | asset path helpers | no |
The package ships source (TS/TSX) — not a pre-built bundle — so the host
bundler can handle the web-worker URLs (new Worker(new URL(...))) and JSX.
Install (Next.js)
npm i @esosdev/astro-globe \
three @react-three/fiber @react-three/drei
# satellite.js is a direct dependency and installs automatically1. next.config.js
const nextConfig = {
// Required: transpile the source-shipped package + handle worker URLs.
transpilePackages: ['@esosdev/astro-globe'],
// Optional: enables the SharedArrayBuffer fast-path (degrades gracefully).
async headers() {
return [{
source: '/(.*)',
headers: [
{ key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
{ key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' },
],
}];
},
};
module.exports = nextConfig;2. Serve the 3D assets (bundled in the package — no internet needed)
The Earth textures and satellite meshes ship inside the package. They are
loaded at runtime by URL, so they must live under a path your app serves
(Next.js public/). A CLI copies them there from node_modules — fully offline,
which makes it safe for air-gapped deployments.
Wire it once into your project's lifecycle so it runs on every install/build:
// package.json (your app)
{
"scripts": {
"postinstall": "astro-globe-copy-assets public/astro-globe"
}
}This copies earth_*.jpg/png and meshes/*.obj|.mtl into public/astro-globe/.
Then point the scene there with assetBaseUrl="/astro-globe" (see below).
The meshes are 82 files selected at runtime by satellite type, with relative
.obj→.mtlreferences — they can't be statically bundled/imported, which is why they're served as a static folder rather than imported as modules.
3. Render (client-only)
'use client';
import dynamic from 'next/dynamic';
import { usePositionsWorker } from '@esosdev/astro-globe';
const Scene = dynamic(
() => import('@esosdev/astro-globe').then((m) => m.Scene),
{ ssr: false }
);
export default function GlobePage() {
const satellites = useMySatellites(); // your live data (TLEs / ephemerides)
const [selected, setSelected] = useState<string[]>([]);
const { positionsBuffer, orbitBuffers, requestOrbit } = usePositionsWorker(satellites);
return (
<Scene
satellites={satellites}
selectedSatelliteIds={selected}
onSatelliteSelect={(id) => setSelected([id])}
positionsBuffer={positionsBuffer}
orbitBuffers={orbitBuffers}
requestOrbit={requestOrbit}
assetBaseUrl="/astro-globe" // matches the copy-assets target above
/>
);
}Using just the maths (no React)
import { propagate, eciToEcef } from '@esosdev/astro-globe/core';Because the package ships source, a non-React consumer of
/corestill needs a TS-aware bundler (ortranspilePackages). Ask if you need a pre-built dist target.
Release
Versioning is driven by semantic-release (Conventional Commits):
main publishes the latest dist-tag, develop the beta dist-tag. The publish
job is manual in CI and requires the ESOS_NPM_TOKEN and GITLAB_TOKEN/GL_TOKEN
CI variables.
