@aeryflux/globe
v1.8.0
Published
Portable 3D globe component for React and React Native (Expo)
Maintainers
Readme
@aeryflux/globe
Hex-tiled 3D globe component for React and React Native (Expo), built on Three.js. Country, region and city data visualization with drill-down highlights, imperative camera, ambient waves and music reactivity.
Live showcase — real-time markets on the globe | API reference | npm

Features
- Three levels of geography — countries, regions/states and city cells, with per-level highlight, color and extrusion
- Hierarchy spotlight — one call lifts country → region → city with graduated extrusion and trend-color shading (see it live on aeryflux.com)
- Imperative handle —
flyTo/flyToCellcamera, per-country extrusion and tinting, layer reveals, slide showcase - Data-driven — feed plain
Record<name, { scale, color, extrusion }>maps; the animation loop does the rest (entry easing, breathing pulse, borders) - CDN models included — six GLB tiers from ~1 MB (mobile) to ~36 MB (full detail) with id mappings, served from jsDelivr and pinned to the package version
- Ambient & music modes — gaussian wave sweeps, bass/energy-reactive rotation and extrusion, live background gradients and ocean tint
- Cross-platform — React (web) and React Native (Expo), TypeScript throughout
- Resilient — SVG fallback without WebGL, automatic recovery after GPU context loss, clone-on-write GLB material handling
Installation
React (Web)
npm install @aeryflux/globe threeReact Native (Expo)
npm install @aeryflux/globe three expo-gl expo-threeQuick Start
React (Web)
import { Globe } from '@aeryflux/globe/react';
function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Globe
surface="green"
showCountries
rotationSpeed={0.0005}
/>
</div>
);
}React Native (Expo)
import { Globe } from '@aeryflux/globe/react-native';
export default function App() {
return (
<Globe
surface="dark"
showCountries
showBorders
introAnimation
rotationSpeed={0.0004}
/>
);
}Model loads from CDN automatically — no assets to configure.
Metro config
Add a metro.config.js at the root of your Expo project:
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');
const config = getDefaultConfig(__dirname);
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (moduleName === '@aeryflux/globe/react-native') {
return {
filePath: path.resolve(__dirname, 'node_modules/@aeryflux/globe/dist/react-native/index.js'),
type: 'sourceFile',
};
}
return context.resolveRequest(context, moduleName, platform);
};
module.exports = config;Props
Appearance
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| surface | 'dark' \| 'green' \| 'white' | 'green' | Color theme |
| borderColor | string | - | Override border/accent color |
| countryColor | string | - | Override country fill color |
| globeFillColor | string | - | Override ocean fill color |
| glowIntensity | number | 0.6 | Border glow intensity |
| bloomStrength | number | 0.15 | Post-processing bloom |
| isLightTheme | boolean | false | Reduce bloom for light backgrounds |
| forceTransparent | boolean | false | Force transparent background |
Display
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| showCountries | boolean | true | Show country fills |
| showBorders | boolean | true | Show border lines |
| showGlobeFill | boolean | true | Show ocean/globe |
| showCities | boolean | false | Show city markers (LF models) |
| showRegions | boolean | false | Show region sub-meshes |
Interaction
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| enableControls | boolean | false | Enable orbit controls (drag, zoom, click-to-select) |
| scrollSlides | boolean | true | Advance the slide showcase on mouse wheel (false: wheel only spins) |
| rotationSpeed | number | 0.0003 | Auto-rotation speed |
| onCountryClick | (name) => void | - | Country click (requires enableControls) |
| onRegionClick | (country, region) => void | - | Region click |
| onCityClick | (name) => void | - | City click |
| onCellClick | (cell: CellData) => void | - | Hex cell click |
| onCellHover | (cell: CellData \| null) => void | - | Hex cell hover |
Data Visualization
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| countryData | Record<string, DataPoint> | - | Country highlights, keyed by country name |
| regionData | Record<string, DataPoint> | - | Region highlights, keyed by region key |
| cityData | Record<string, DataPoint> | - | City highlights, keyed by city name |
| dataHighlightColor | string | accent | Default highlight color |
DataPoint: { scale: number; color?: string; extrusion?: number } — scale
drives highlight intensity and pulse, extrusion (0–1) lifts the mesh radially.
Ambient Wave
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| ambientColor | string | accent | Wave accent color |
| ambientIntensity | number | 0.4 | Wave intensity (0-1) |
| ambientExtrusion | number | 0 | Radial displacement on wave peaks (0 = off, 1 = full) |
Music Reactivity
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| bass | number | 0 | Bass level (0-1.5) — boosts rotation and wave |
| mid | number | 0 | Mid frequency level (0-1) |
| treble | number | 0 | Treble level (0-1) |
| energy | number | 0 | Overall energy (0-1) — boosts rotation and wave |
Dynamic Background
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| gradientTop | string | '#06060e' | Background gradient top color |
| gradientBottom | string | '#0e1430' | Background gradient bottom color |
| globeFillTint | string | - | Real-time globe fill tint override |
Intro Animation
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| introAnimation | boolean | false | Enable slide-in + spin entry |
| introDuration | number | 2.5 | Animation duration in seconds |
Assets & Lifecycle
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| modelUrl | string | CDN (7L) | Custom GLB model URL |
| idMappingUrl | string | - | Id mapping JSON — required for regions, cities and the hierarchy spotlight on L/LF models |
| disablePostProcessing | boolean | false | Skip bloom + MSAA and cap the pixel ratio (memory-constrained GPUs) |
| showFallbackMessage | boolean | false | Show a message in the SVG fallback when WebGL is unavailable |
| onLoad | () => void | - | Called once the model is loaded |
| className / style | string / CSSProperties | - | Container styling |
| debug | boolean | false | Debug mode |
Imperative API
Attach a ref to drive the globe beyond declarative props:
import { useRef } from 'react';
import { Globe, type GlobeHandle } from '@aeryflux/globe/react';
const globeRef = useRef<GlobeHandle>(null);
<Globe ref={globeRef} enableControls />| Group | Methods |
|-------|---------|
| Camera | flyTo(country), flyToCity(name), flyToCell(cellId), flyToLatLon(lat, lon) |
| Hierarchy | highlightHierarchy(target, levels?), clearHierarchy() |
| Countries & regions | extrudeCountry, extrudeRegion, colorCountry, colorRegion, dimAllExcept, resetAll, triggerAura |
| Cells & cities | highlightCells, highlightCitiesByCoords, getCells |
| Scene | revealLayers, setSlide, setModelOffset, getTier, getCanvas |
Full signatures and behavior notes: aeryflux.com/docs/globe.
Data Visualization
import { Globe } from '@aeryflux/globe/react';
const countryData = {
France: { scale: 0.8, color: '#ef4444' },
Japan: { scale: 0.6, color: '#3b82f6', extrusion: 0.5 },
Brazil: { scale: 1.0, color: '#22c55e' },
};
<Globe
surface="dark"
showCountries
countryData={countryData}
dataHighlightColor="#00ff88"
/>Hierarchy Spotlight
Drill-down highlight for LF models (requires idMappingUrl): the country
lifts mildly, the target region more, the city the most, with the trend
color's lightness graduating per level.
const res = globeRef.current?.highlightHierarchy({
country: 'united states',
city: 'Austin',
lat: 30.27, lon: -97.74, // nearest-cell fallback if the city isn't mapped
scale: 0.82, // 0 = down/red · 0.5 = neutral · 1 = up/green
color: '#22c55e',
extrusion: 0.9,
});
if (res?.cellId != null) globeRef.current?.flyToCell(res.cellId);
globeRef.current?.clearHierarchy(); // restore the data-driven viewCity resolution cascades from cellId to name to nearest-cell lat/lon lookup —
pass coordinates as a fallback for towns missing from the mapping. The optional
levels argument overrides the per-level extrusion weights (HIERARCHY_LEVELS).
Music-Reactive Globe
<Globe
surface="dark"
showCountries
ambientIntensity={0.6}
ambientExtrusion={0.3}
bass={bassLevel}
energy={energyLevel}
rotationSpeed={0.0005}
gradientBottom="#1a0a00"
/>Bass and energy values drive rotation speed, wave sweep velocity, and extrusion displacement in real-time.
Dev Tools
import { Globe, GlobeDevTools } from '@aeryflux/globe/react';
const [config, setConfig] = useState<GlobeConfig>({ surface: 'green' });
<Globe {...config} />
<GlobeDevTools
config={config}
onChange={(partial) => setConfig(prev => ({ ...prev, ...partial }))}
side="right"
/>Interactive panel with toggles for all visual options: ocean, countries, borders, cities, controls, glow, speed, bloom, bass, energy, and ambient settings.
Models
Models are served from jsDelivr CDN by default. Every model ships with a
matching *_id_mapping.json — pass it via idMappingUrl to enable region /
city name resolution and the hierarchy spotlight.
| Model | Size | Content | Use Case |
|-------|------|---------|----------|
| atlas_hex_subdiv_5L.glb | ~1 MB | countries | Mobile |
| atlas_hex_subdiv_6L.glb | ~3.5 MB | countries | Tablet |
| atlas_hex_subdiv_7L.glb | ~12 MB | countries | Desktop (default) |
| atlas_hex_subdiv_5LF.glb | ~4 MB | + regions + cities | Mobile, full detail |
| atlas_hex_subdiv_6LF.glb | ~12 MB | + regions + cities | Tablet, full detail |
| atlas_hex_subdiv_7LF.glb | ~36 MB | + regions + cities | Desktop, full detail |
import { GLOBE_CDN_MODEL_7LF_URL, GLOBE_CDN_ID_MAPPING_7LF_URL } from '@aeryflux/globe';
// URL constants are pinned to the installed package version
<Globe modelUrl={GLOBE_CDN_MODEL_7LF_URL} idMappingUrl={GLOBE_CDN_ID_MAPPING_7LF_URL} showCities />
// Self-host models
<Globe modelUrl="/models/atlas_hex_subdiv_7LF.glb" idMappingUrl="/models/atlas_hex_subdiv_7LF_id_mapping.json" />Performance
- Pick the right tier per device — phones: 5L/5LF, tablets: 6L/6LF,
desktop: 7L/7LF. Beware tablets in landscape reporting desktop-class widths;
detect touch-first devices (
pointer: coarse) rather than viewport width. disablePostProcessingtrades the bloom veil for a lighter GPU footprint (skips the composer render targets and MSAA, caps pixel ratio at 1.5).- Context-loss recovery — if a mobile GPU resets, the component restarts
its render loop on
webglcontextrestoredinstead of staying black.
Surfaces
| Surface | Accent | Background | Countries |
|---------|--------|------------|-----------|
| dark | #00ff88 | #050508 | Light gray |
| green | #00ff88 | #050508 | Light gray |
| white | #1a1a1a | #ffffff | Light gray |
Exports
@aeryflux/globe/react
Globe, GlobeFallback, GlobeDevTools, useWebGLSupport
SURFACES, GLOBE_MODELS
HIERARCHY_LEVELS, type HierarchyTarget, type HierarchyLevelWeights
loadIdMapping, rebuildRegionIndexFromIdMapping
GLOBE_VERSION, GLOBE_CDN_BASE, GLOBE_CDN_MODEL_URL /* 7L */
animateDataHighlights, animateCityHighlights
// + all types@aeryflux/globe (root)
// Everything from core, including all CDN URL constants:
GLOBE_CDN_MODEL_{5L,6L,7L,5LF,6LF,7LF}_URL
GLOBE_CDN_ID_MAPPING_{5L,6L,7L,5LF,6LF,7LF}_URL
scaleExtrusion, TIER_EXTRUSION_MAX, resolveHierarchy, buildGlobeIndex, …@aeryflux/globe/react-native
Globe, GlobeNativeProps
// Core renderer utilities (for custom integrations)
buildGlobeIndex, getSurfaceColors, applyGlobeMaterials
createGlobeScene, createGlobeCamera
animateGlobeRotation, animateBorderPulse, animateAmbientWave
animateDataHighlights, animateCityHighlights
resetAllCountries, resetAllCities
updateGradient, updateGlobeFillTint, updateAccentLight
createIntroState, applyIntroAnimation
// + all typesContributing
See CONTRIBUTING.md for development setup, build/test workflow, and pull request guidelines.
Changelog
See CHANGELOG.md for a detailed history of changes per version.
License
MIT - AeryFlux
Credits
- Three.js - 3D rendering
- geojsonto3D - Globe model generation
- Natural Earth - Geographic data
