{"id":51911451,"url":"https://github.com/cpaczek/skylight","last_synced_at":"2026-07-27T05:01:28.036Z","repository":{"id":362204460,"uuid":"1257699593","full_name":"cpaczek/skylight","owner":"cpaczek","description":"Project the aircraft passing overhead onto your ceiling in real time, from an RTL-SDR — with a live sky layer (sun, moon, stars, ISS) and where each plane is headed.","archived":false,"fork":false,"pushed_at":"2026-07-10T16:42:36.000Z","size":6154,"stargazers_count":3054,"open_issues_count":2,"forks_count":371,"subscribers_count":39,"default_branch":"main","last_synced_at":"2026-07-10T18:09:50.641Z","etag":null,"topics":["ads-b","aircraft","art-installation","flight-tracker","projector","raspberry-pi","react","rtl-sdr","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cpaczek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T23:40:28.000Z","updated_at":"2026-07-10T16:44:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cpaczek/skylight","commit_stats":null,"previous_names":["cpaczek/skylight"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cpaczek/skylight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpaczek%2Fskylight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpaczek%2Fskylight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpaczek%2Fskylight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpaczek%2Fskylight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cpaczek","download_url":"https://codeload.github.com/cpaczek/skylight/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpaczek%2Fskylight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35937479,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-27T02:00:06.776Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ads-b","aircraft","art-installation","flight-tracker","projector","raspberry-pi","react","rtl-sdr","typescript"],"created_at":"2026-07-27T05:01:27.489Z","updated_at":"2026-07-27T05:01:28.027Z","avatar_url":"https://github.com/cpaczek.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eSkylight\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eProject the aircraft passing overhead onto your ceiling, in real time - an X-ray through the roof.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://skylightceiling.com\"\u003e\u003cb\u003e🛰️ Get notified when I launch on a crowdfunding platform → skylightceiling.com\u003c/b\u003e\u003c/a\u003e\n  \u003cbr\u003e\u003csub\u003eA ready-made kit is coming. Join the waitlist for early access \u0026amp; launch pricing.\u003c/sub\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/skylight.png\" alt=\"Skylight projected on a ceiling: aircraft, trails, SFO runways and the night sky\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\n\nhttps://github.com/user-attachments/assets/9256b0eb-cc27-4388-9a4f-0a6c05468304\n\n\n\u003c/p\u003e\n\nSkylight decodes ADS-B from a cheap RTL-SDR radio and renders the planes physically\nflying over you onto a ceiling-pointed projector. A jet you'd hear overhead glides\nacross your ceiling at the same moment - labeled with its airline, type, and where it's\nheaded. Pure-black background so the projector's rectangle disappears and only the\naircraft (and stars) are lit.\n\nIt also draws the **real sky** behind the planes - sun, moon, bright stars and\nconstellations, and live **satellites including the ISS** - all at their true positions\nfor your location and time. Tune everything from your phone.\n\n\u003e Reference build is centered on **San Francisco International (SFO)**, but it works\n\u003e anywhere - set your location in the control panel and import your airport's runways\n\u003e by ICAO/IATA code (worldwide, via OurAirports) and you're flying.\n\n## Features\n\n- **Real-time overhead aircraft** from a local RTL-SDR (sub-second), or from a free web\n  API with zero code changes - handy for trying it with no radio.\n- **Type-aware glyphs** in a luminous, swept-wing style: widebodies tower over regional\n  jets, **helicopters spin their rotors**, turboprops and GA aircraft spin their props.\n- **Smooth motion** - interpolates the ~1 Hz fixes to 60 fps by rendering slightly in\n  the past and tweening between real positions (no teleporting).\n- **Comet trails**, altitude-graded color, and range rings + compass for orientation.\n- **The airport** (runways) drawn at its true position, so you watch departures and\n  arrivals line up with the runway.\n- **Window to elsewhere** - each routed flight shows its destination **city, local time\n  there, and miles-to-go**, plus a faint great-circle arc toward where it's headed.\n- **Live sky layer** - sun, moon (with phase), bright stars + constellation lines,\n  **naked-eye planets**, and **satellites / ISS** computed from TLEs. Scrub time\n  forward/back from your phone, or jump straight to the next ISS pass.\n- **Phone control panel** - every setting (rotation, theme, palette, filters, sky\n  toggles, …) is live-tunable over your LAN and persists across reboots.\n- **Optional sky camera** - point a PTZ camera (VISCA-over-IP + RTSP) at the sky and\n  Skylight **automatically films the planes it's projecting**: ADS-B-driven pointing\n  with latency-compensated lead prediction, a hybrid vision system that locks the plane\n  to center, and a confidence-gated zoom ladder that punches in as the lock holds.\n  Includes a **TV dashboard** (`/tv.html`) with the live feed + radar inset, and a full\n  **debug UI** (`/tracker.html`) with jog pad, target table, and a star-capture\n  calibration wizard.\n- **Vision that knows a plane from a cloud** - the camera tracker fuses three signals:\n  a classical blob detector (distant specks) + a large-object detector (big overhead\n  planes), **track-before-detect** that picks the target by how it *moves* through the\n  world like ADS-B predicts (clouds are world-static and lose), and an **optional\n  neural airplane detector** (YOLOX-Nano ONNX, downloaded at setup) for a semantic\n  \"is it an airplane?\" confirmation. It also **continuously self-calibrates** the mount\n  from every locked pass, so the aim re-squares itself over time.\n- **Appliance-ready** - boots straight to a full-screen kiosk on a Raspberry Pi 5\n  (dual-output: projector + TV dashboard).\n\n## Hardware\n\n| Part | Suggested | Notes |\n|---|---|---|\n| Receiver | **RTL-SDR Blog V4 + dipole** | The included dipole is plenty - planes are nearly overhead. The **V3 and V5 work identically** (same RTL2832U); if you're buying now, the V4/V5 are the current models. |\n| Compute | **Raspberry Pi 5 (8 GB)** | Decode + render. Active cooling for 24/7. See [minimum specs](#minimum-specs) for lighter setups. |\n| Projector | A 1080p projector pointed up | Laser (e.g. Optoma GT2100HDR) gives the deepest blacks, but it's overkill - see the budget tip below. |\n| Display link | micro-HDMI → HDMI | The Pi 5 uses **micro**-HDMI (not mini). |\n| Mount | Rotating 1/4-20 stand, pointed up | Lower the stand for a bigger image; tape **+ a safety tether**. |\n| Sky camera *(optional)* | Any **VISCA-over-IP PTZ** with RTSP (e.g. a 4K NDI conference PTZ) | For the auto-filming tracker. **Clamp the base rigidly** - fast slews will walk an unclamped mount and ruin the aim calibration. |\n\n\u003e **💡 Budget tip - you don't need an expensive projector.** The pricey laser short-throw\n\u003e is only worth it if you want the image visible in a **lit** room. If you're happy viewing\n\u003e it in a **dim/dark** room (the intended vibe), a cheap **native-1080p LED** projector like\n\u003e the **[Yaber Buffalo Pro U9](https://www.projectorcentral.com/Yaber-Pro_U9.htm) (~$150)**\n\u003e works great:\n\u003e - **No short-throw needed** - from the floor under an ~8 ft ceiling, even a 1.35:1 throw\n\u003e   gives a ~5.5 ft image.\n\u003e - **Low brightness is fine** (even better) - the content is sparse-on-black, so 200–400\n\u003e   lumens in a dark room actually looks *deeper*.\n\u003e - Just verify it's **native 1920×1080** (not \"1080p supported\"), has a **quiet fan**, and\n\u003e   an **HDMI input that shows on power-on**.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/setup.jpg\" alt=\"The build: short-throw projector pointing up at the ceiling, RTL-SDR dipole antenna on the cabinet\" width=\"320\"\u003e\n  \u003cbr\u003e\u003cem\u003eThe build - short-throw projector pointing up, RTL-SDR dipole on the cabinet.\u003c/em\u003e\n\u003c/p\u003e\n\nYou don't need any of this to try it - see Quick start.\n\n### Minimum specs\n\nThere are two workloads, and they have very different requirements:\n\n- **Display + decode (the core ceiling piece).** This is light. The server is a small\n  Node process; the rendering is a 2D canvas. A **Pi 4 (2 GB)** runs it comfortably, and a\n  **Pi 3B / Pi Zero 2 W** will work for the display if you keep the canvas modest - cap\n  `maxFps` (e.g. 30), trim `trailSeconds`, and lean on `DATA_SOURCE=api` so the Pi isn't\n  also running `dump1090`. 1 GB is workable but tight; 2 GB+ is the comfortable floor.\n- **The optional sky-camera tracker (vision + neural detector).** This is the heavy part\n  and is what the **Pi 5 (8 GB)** recommendation is for - real-time RTSP decode plus ONNX\n  inference. Don't expect the vision tracker to keep up on a Pi 4 or smaller.\n\nRule of thumb: **Pi Zero 2 W / 3B** = display only, **Pi 4** = display + local radio,\n**Pi 5** = everything including the camera tracker.\n\n## Quick start (local, no radio)\n\nRuns entirely on your computer against a free public ADS-B API.\n\n```bash\npnpm install\nDATA_SOURCE=api pnpm dev\n```\n\n- **Display:** http://localhost:5173/\n- **Control panel:** http://localhost:5173/control.html (or from your phone: `http://\u003cyour-ip\u003e:5173/control.html`)\n- **Camera tracker debug UI:** http://localhost:5173/tracker.html - runs against a\n  built-in **camera simulator**, so the whole pointing pipeline (target selection,\n  prediction, zoom, calibration) works with zero hardware.\n- **TV dashboard:** http://localhost:5173/tv.html\n\n**Then set your location** from the control panel's **Location** section - search a\ncity/airport, tap **Current** to use the browser's location, or type `lat,lon`\ndirectly. The default is SFO, so until you change it you'll see San Francisco traffic\n(or nothing, if your radius is small). Your airport's runways can be drawn too:\ntype its ICAO/IATA code into **Location → Runways** and they're imported automatically.\n\n### With a radio (locally)\n\n```bash\nscripts/install-rtlsdr-fedora.sh    # rtl-sdr-blog driver + blacklist DVB-T (Fedora; see script for Debian)\nscripts/run-dump1090-local.sh       # decode + serve aircraft.json on :8080\nDATA_SOURCE=radio pnpm dev\n```\n\n## Raspberry Pi appliance\n\nFull walkthrough in [`pi-setup/README.md`](pi-setup/README.md): flash + headless\nprovision the SD card, install the driver + decoder + app, and set up the boot-to-kiosk\ndisplay. Once it's running, push updates from your dev machine with:\n\n```bash\nPI_HOST=skylight.local ./scripts/deploy-to-pi.sh\n```\n\n### Optional: the neural airplane detector\n\nThe camera tracker works out of the box with its classical + motion-tracking vision.\nFor an extra semantic \"is it an airplane?\" signal (kills cloud locks, nails big\noverhead planes), download the optional ONNX model **on the machine with the camera**:\n\n```bash\n./scripts/fetch-vision-model.sh        # YOLOX-Nano, Apache-2.0, ~3.5 MB (not committed)\nsudo systemctl restart skylight-tracker\n# verify: the tracker state shows vision.net.ready == true\n```\n\nIt's fully optional - if the model (or `onnxruntime-node`) is absent, the tracker runs\nclassical-only with no errors. On a Pi 5 it adds ~0.8 to load average during a pass;\nturn it off with `tracker.vision.net.enabled = false` or run it less often with\n`tracker.vision.net.everyNTicks` if the Pi runs hot.\n\n## Docker (server-driven projector)\n\nIf you'd rather drive a projector from a server (no Pi, no cabling to the projector),\nrun the server + display in a container:\n\n```bash\ndocker compose up -d --build\n# display:  http://\u003chost\u003e:3000/      ·  phone panel: http://\u003chost\u003e:3000/control\n```\n\nOut of the box it uses the free **airplanes.live** API, so it runs with **no radio**.\nTo use your own ADS-B receiver, set `DATA_SOURCE=radio` and point `AIRCRAFT_JSON_URL`\nat an existing dump1090 / readsb / PiAware feed on your network (or just change the URL\nlive from the control panel's **Source** section):\n\n```yaml\n# compose.yaml\nenvironment:\n  DATA_SOURCE: radio\n  AIRCRAFT_JSON_URL: http://192.168.1.50:8080/data/aircraft.json\n```\n\nConfig and the route/TLE caches persist in the `skylight-data` volume. The image is the\n**server + display only** - the optional sky-camera tracker (which wants direct camera +\nGPU access) is not containerized. If you reach the server over a custom hostname or a\ntunnel rather than a LAN IP / `*.local`, add it to `ALLOWED_HOSTS` (see below).\n\n\u003e **Reaching a decoder in another container:** the fetch happens **from inside the\n\u003e Skylight container**, so `localhost` won't work and a sibling container's name only\n\u003e resolves if both containers share a Docker network. Either use the decoder host's\n\u003e LAN IP (e.g. `http://192.168.1.50:8080/data/aircraft.json`), or attach Skylight to\n\u003e the decoder's network (see the commented `networks:` block in `compose.yaml`).\n\u003e The status line in `/control` shows *why* a fetch fails (DNS, refused, timeout).\n\n## Troubleshooting\n\n**No planes, using the public API.** The view is centered on SFO until you set your\nlocation - open `/control` and use the **Location** section (search, **Current**, or\n`lat,lon`). Then check the status line at the top of `/control`: it shows the live\nsource, count, and the exact failure reason if polling is failing. If you're far from\nan airport, also widen the **Radius** slider.\n\n**`source fetch failed: …` in the status line.** The reason in parentheses tells you\nwhat's wrong, measured *from the server*:\n- `DNS lookup failed (host)` - the server can't resolve that hostname. In Docker this\n  usually means the decoder container isn't on the same Docker network (see the Docker\n  section above).\n- `connection refused` / `host unreachable` / `timeout` - the host resolved but nothing\n  answered on that port; check the URL's port and that the decoder's web server is up\n  (`curl http://\u003chost\u003e:8080/data/aircraft.json` from the machine running Skylight).\n- `HTTP 429` - the public API is rate-limiting; Skylight now backs off automatically\n  and recovers on its own. Planes hold position on screen through brief outages.\n\n**Pointing at an existing dump1090 / readsb / PiAware feed.** Set the **Radio URL** in\n`/control` → Source to your feed's `aircraft.json` (dump1090-fa serves it at\n`http://\u003chost\u003e:8080/data/aircraft.json`) and switch the source to *radio*. No rebuild\nneeded - it applies on the next poll.\n\n**Installer fails with `Unsupported architecture: armhf`.** You're on 32-bit\nRaspberry Pi OS; Node.js no longer ships 32-bit ARM builds. Re-flash with\n**Raspberry Pi OS (64-bit)** - every supported Pi (3/4/5, Zero 2 W) can run it.\n\n**Runways for my airport.** `/control` → Location → **Runways**: enter the ICAO or\nIATA code (e.g. `EGLL`, `EDDF`, `SNA`). Geometry comes from the public-domain\nOurAirports dataset; very small airfields sometimes lack surveyed runway endpoints,\nin which case you'll get a clear error.\n\n**Clock on the TV dashboard is wrong.** It shows the Pi's system time - fix the\ntimezone with `sudo timedatectl set-timezone \u003cRegion/City\u003e`.\n\n## Configuration\n\n`Config` ([`shared/src/config.ts`](shared/src/config.ts)) is the single source of truth,\npersisted to `server/data/config.json` and live-editable from the control panel. Key\nfields:\n\n| | |\n|---|---|\n| `centerLat` / `centerLon` | **Your location** - where you're looking up. Editable from the panel's **Location** section (type a city, airport code, or `lat,lon`). |\n| `locationName` | Display name for the current location, shown in the control panel. |\n| `locationProfiles` | Saved places (favorite airports). Switch between them from the panel's **Location** section - tap **Save current** to store the active spot, then a chip to jump back to it. |\n| `radiusMiles` | How far out to show (default 3 - \"what you could realistically see\"). |\n| `rotationDeg` / `mirrorX` | Calibration for the looking-up flip (tune against a real pass). |\n| `theme` | `ambient` · `telemetry` · `focus`. |\n| `showStars` / `showSun` / `showMoon` / `showSatellites` / `showPlanets` | Sky layer toggles. Planets (Venus, Jupiter, Mars, Saturn, Mercury) are drawn at their true positions, sized by brightness and labelled - so the display stays alive even with no traffic. |\n| `skyTimeOffsetMin` | Scrub the sky clock for testing (0 = live). |\n| `showDestArc` / `showRouteDetail` | \"Window to elsewhere\". |\n| `tracker.*` | The whole camera subsystem - driver (`sim`/`visca`), camera IP, mount calibration, target selection criteria, prediction/pursuit tuning, zoom + vision behavior. All live-tunable from the tracker debug UI. |\n\n**Using it somewhere other than SFO:** set your location from the control panel's\n**Location** section (or edit `centerLat`/`centerLon`). Stars, sun, moon, and satellites\nare computed for your coordinates automatically. The runway overlay is still SFO-specific\ngeometry - turn off **Airport runways** if you've moved, or replace it in\n[`web/src/display/airports.ts`](web/src/display/airports.ts) with your local airport\n(coordinates from [OurAirports](https://ourairports.com/data/)).\n\n\u003e Location search uses the free [Nominatim](https://nominatim.openstreetmap.org/)\n\u003e (OpenStreetMap) service. Set `GEOCODE_USER_AGENT` to identify your deployment if you\n\u003e use it heavily.\n\n### Server environment\n\n| Env | Default | Meaning |\n|---|---|---|\n| `DATA_SOURCE` | `radio` | `radio` (dump1090) or `api` (airplanes.live) |\n| `AIRCRAFT_JSON_URL` | `http://localhost:8080/aircraft.json` | dump1090 feed |\n| `SUPPLEMENT_API` | `1` | When on radio, merge the API too (keeps landing aircraft alive) |\n| `PORT` / `HOST` | `3000` / `0.0.0.0` | HTTP + WebSocket |\n| `ALLOWED_HOSTS` | *(empty)* | Extra Host/Origin allowlist entries, comma-separated. Wildcards: `*.example.com`. Loopback, RFC1918 LAN, IPv6 ULA / link-local, and `*.local` are allowed by default. |\n| `ALLOW_PRIVATE_LAN` | `1` | Set `0` to lock the server to loopback + mDNS only (no LAN phone control) |\n| `GEOCODE_USER_AGENT` | *(skylight default)* | User-Agent sent to Nominatim for location search |\n\n### Exposing Skylight on a custom hostname\n\nSkylight binds `0.0.0.0` so the phone control panel works on your home Wi-Fi.\nTo stop browsers on other origins from talking to the server (e.g. a tab on\n`evil.com` opening a WebSocket to your Pi over DNS rebinding), every request\nis rejected unless its `Host` header (and a WebSocket's `Origin` header)\nmatches the allowlist.\n\nThe defaults cover the documented topology - `localhost`, `127.0.0.1`,\n`[::1]`, `*.local`, and private LAN ranges (`10/8`, `192.168/16`,\n`172.16/12`, IPv6 ULA + link-local). If you publish Skylight on a public\nhostname or a tunnel, add it:\n\n```bash\nALLOWED_HOSTS=skylight.mydomain.com,*.trycloudflare.com pnpm dev\n```\n\n## Architecture\n\n```\nRTL-SDR ──USB──\u003e dump1090-fa ──\u003e aircraft.json (:8080)\n                                      │ poll ~1 Hz  (+ API supplement)\n                                      ▼\n                         server/  (Node · Express · ws)  :3000\n                         • normalize + enrich (airline/type tables + adsbdb routes)\n                         • proxy satellite TLEs (Celestrak)\n                         • persist config, broadcast over WebSocket\n                         ├──────────────┬──────────────┬───────────────┐\n                         ▼              ▼              ▼               ▼\n                   Display (/)    Control (/control)  REST /api/*   tracker/  :3001\n                   canvas renderer +  phone settings UI             • target selection + az/el\n                   sky engine → projector (live, two-way)             lead prediction (ECEF)\n                                                                    • velocity pursuit + zoom\n                                                                    • vision: sky-masked blob\n                                                                      detector, lag-compensated\n                                                                    • VISCA-over-IP → PTZ camera\n                                                                    • RTSP → H.264 passthrough\n                                                                      (/video-ws) + MJPEG\n                                                                    • TV dashboard + debug UI\n```\n\n- **`shared/`** - TypeScript types, config schema, and pure geo/projection/pointing math\n  (ECEF az/el, mount model + calibration solver, alpha-beta trackers, FOV/zoom).\n- **`server/`** - polls the radio (primary) and API (supplement), enriches aircraft,\n  proxies TLEs, persists config, and pushes everything over a WebSocket.\n- **`web/`** - Vite + React, four pages: the **display** (`\u003ccanvas\u003e` renderer + celestial\n  engine), the mobile **control panel**, the **TV dashboard**, and the **tracker debug UI**.\n- **`tracker/`** - the camera brain: picks a target, predicts where it will be when the\n  command actually bites (fix age + decode latency + motor latency), drives the PTZ with\n  closed-loop velocity pursuit (sigma-delta speed dithering, soft limit guards,\n  dead-reckoned pose), verifies the plane on-frame with a vision detector, and zooms in\n  only while the lock holds. Runs against a **simulator** with zero hardware; replays\n  recorded sessions deterministically for debugging.\n\n**Stack:** TypeScript · React · Vite · Express · ws · pnpm workspaces ·\n[astronomy-engine](https://github.com/cosinekitty/astronomy) ·\n[satellite.js](https://github.com/shashwatak/satellite-js).\n\n## Credits \u0026 data\n\n- ADS-B decode: [dump1090-fa](https://github.com/flightaware/dump1090) · RTL-SDR Blog\n  [drivers](https://github.com/rtlsdrblog/rtl-sdr-blog)\n- Routes / aircraft enrichment: [adsbdb](https://www.adsbdb.com/) ·\n  fallback feed: [airplanes.live](https://airplanes.live/)\n- Satellite elements: [Celestrak](https://celestrak.org/) · airport data:\n  [OurAirports](https://ourairports.com/)\n\n## License\n\n[MIT](LICENSE) - be excellent, point it at the sky.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpaczek%2Fskylight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcpaczek%2Fskylight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpaczek%2Fskylight/lists"}