Case study
SkyEye: a live 3D globe of aircraft, ships and satellites, with an AI assistant
By Adil Soukaini
, 6 min read

SkyEye is ShipFastDev's own live-data product: a 3D globe in the browser that streams aircraft, ships and satellites as they move, with JARVIS, an AI assistant that answers questions about that data and flies the camera to whatever it is talking about. It is not public; a demo is available on a call.
What a user can do
- Fly anywhere on the globe with terrain and 3D buildings, and switch layers on and off: aircraft, satellites (about 16,000), ships, trains, buses and trams, earthquakes, volcanoes, rocket launches, airports, traffic cameras, World Heritage Sites, disaster alerts, bike share and active fires.
- Click anything for a card: an aircraft's route and altitude, a ship's flag, size and destination, a satellite's catalogue data, an airport's decoded METAR and TAF weather, or a country or city with its live counts, weather and photos.
- Follow or ride along: a chase camera follows a flight, and cockpit and window-seat views ride the live aircraft's track and climb.
- Look back in time: a 12-hour replay timeline, air and shipping heatmaps, "Above me" (aircraft and satellites overhead) and "What passed here" for any point.
- Get alerts for rapid descents, circling aircraft, ships that go silent and emergency squawk codes.
JARVIS, the assistant
JARVIS is a chat and voice assistant built into the globe. You ask "how busy is Charles de Gaulle right now?" or "follow the highest plane over Paris", and it answers in a sentence or two while selecting and flying to what it names.
- Tools generated from the data. Each layer declares a field schema, and JARVIS's tools are generated from it, so a new dataset becomes searchable by the assistant without new tool code. The model asks for a tool, the server runs the query on live data and sends the result back: the standard tool-use loop Anthropic documents.
- Pluggable models. Claude or DeepSeek, sharing the same tools and camera actions.
- More than answers. Narrated tours ("walk me through the top five…"), a short daily briefing, news briefings pinned on the globe, and watches such as "tell me when BA117 lands" or "warn me about any quake over 6 near Tokyo", checked against the live data every 20 seconds.
- Memory. Chat history and an editable long-term memory are stored locally, with full-text search over past chats.
- Voice. Browser speech by default, or an optional neural voice (Kokoro-82M) that runs on the machine, so nothing is sent to a speech service. A hands-free mode uses local speech recognition.
What was built
SkyEye is a TypeScript monorepo with three packages: a Node.js server (Hono, WebSockets, the Anthropic SDK), a web client (React 19, CesiumJS, Vite, Zustand) and shared code.
- Plugins. Each dataset is one folder on the server (ingest and field schema) and one entry in the client (style). The schema drives the detail panel, the search API and JARVIS's tools.
- Transport. One WebSocket per viewer. The server keeps a grid spatial index per layer and sends binary deltas for the viewer's part of the globe, about 33 bytes per object, thinned to a budget (60,000 objects per layer by default).
- Rendering. One draw call per layer. Between updates, objects are moved on the GPU along great circles, so the per-frame CPU cost stays flat whatever the object count; a CPU copy of the same maths handles clicks, labels and the selected object. Highlights and shadows are plain Cesium Primitives, built synchronously.
- Satellites in the browser. The server sends the catalogue's orbital elements once and a Web Worker propagates them with SGP4 using satellite.js. CelesTrak's GP data are produced for exactly that propagator.
- Aircraft and ships. Aircraft come from OpenSky and adsb.lol. The OpenSky REST API uses OAuth2 client credentials and daily credit quotas (400 credits for anonymous users, 4,000 for a standard account), so SkyEye polls according to its credits: a global refresh every 90 seconds with credentials, every 15 minutes without. Ships come from aisstream.io, which does not allow direct browser connections, so the key stays on the server.
How it is kept reliable
- Tests. 45 Vitest test files, a separate performance suite for the server, the client and the data flow, and type checking of both server and client. A
?synthetic=50000flag spawns 50,000 moving objects as a load test. - Measured fixes. Simplifying airspace shapes cut their cache from 260 MB to 15 MB and server memory from 2 GB to 0.4 GB; a pre-aggregated hourly table took the 72-hour heatmap query from 12 s to 0.24 s. Event-loop delay and garbage-collection pauses are reported in the server stats.
- Frame budget. Quality presets (Battery saver, Balanced, Max), 60 fps only while you interact, paused streaming in hidden tabs, and a service worker that caches Cesium's files.
- Review rounds. The history shows a numbered review round after each feature, one of which closed a server-side request forgery hole with a media-host allowlist.
Recent releases
The repository has 210 commits between 23 September and 3 October 2026. The latest, on 2 and 3 October 2026:
- Landing gear that retracts on 11 aircraft families, and textured cockpits (an A350 flight deck for jets, a Cessna 172 panel for light aircraft).
- A trains layer: every Finnish train from Digitraffic, and Amtrak, VIA Rail and Brightline in North America.
- World Heritage Sites (1,154 sites, grouped by their official ID via Wikidata), active fires from NASA FIRMS and air quality from OpenAQ on city cards.
- JARVIS watches and alerts, news search, news briefings on the globe, and photos of the people and places it mentions.
- A clock fix: the server measures its clock offset against several sites so moving objects no longer stall and jump between updates.
If you are planning something similar
The technical side of streaming live positions onto a globe is covered in Live data on a 3D globe with CesiumJS, and the assistant side in Adding AI features to your product. For a product already in production, see the Driveway Morocco case study, and the other projects in the portfolio.
Frequently asked questions
Can I try SkyEye online?
No. SkyEye is not public. A live demo is available on a call.
Where does the data come from?
From public feeds: OpenSky and adsb.lol for aircraft, CelesTrak for satellites, aisstream.io for ships, plus national transport, weather, earthquake and disaster sources. Some need a free key (ships, active fires, air quality), and OpenSky gives more frequent updates with an account.
Can the same approach work with my own data, such as a fleet or sensors?
That is what the plugin structure is for: a dataset is an ingest step and a field schema on the server plus a style on the client, and the schema also gives the assistant its search tools. A private feed would follow the same pattern.
Which AI model does JARVIS use?
Claude or DeepSeek, chosen in configuration; both use the same tools. Chat history and memory stay in a local database, and the optional neural voice runs on the machine.
Sources
- CesiumJS API reference, Cesium, accessed October 2026
- Primitive (CesiumJS reference), Cesium, accessed October 2026
- OpenSky REST API, The OpenSky Network, accessed October 2026
- A New Way to Obtain GP Data, CelesTrak, updated June 2026
- satellite.js, satellite.js contributors (GitHub), accessed October 2026
- AIS Stream documentation, aisstream.io, accessed October 2026
- Tool use with Claude, Anthropic, accessed October 2026

