Cross-platform headless astronomy controller for Raspberry Pi, ARM64 SBCs, and Windows mini PCs.
⚠️ N.I.N.A. Polaris is a community-driven fork of N.I.N.A. It is not affiliated with or supported by the official N.I.N.A. development team. Please don't ask them for support with this fork, open issues here instead.
N.I.N.A. Polaris is a lightweight, browser-controlled astrophotography system built on ASP.NET Core. It brings the power of N.I.N.A. (Nighttime Imaging 'N' Astronomy) to single-board computers and small-form-factor PCs, with a responsive Web UI accessible from any device on the network.
The Raspberry Pi (or Windows mini PC) acts as a data broker, controlling hardware, saving FITS files, and streaming images, while your laptop, tablet, or phone handles all the heavy rendering in the browser.
Browser (laptop / tablet / phone) Raspberry Pi / Mini PC
┌──────────────────────────────┐ ┌──────────────────────────┐
│ Web UI (Alpine.js) │◄──HTTP─►│ ASP.NET Core + Kestrel │
│ Live preview (Canvas/WebGL) │◄──WS───►│ INDI client (TCP 7624) │
│ Image processing (client) │ │ Plate solving (ASTAP) │
│ Sky explorer │ │ Sequence engine │
└──────────────────────────────┘ │ Live stacking │
└──────────────────────────┘
- Features · full list in docs/FEATURES.md
- Documentation
- Architecture · Technology Stack
- Getting Started
- Deployment
- API & Configuration
- Performance Targets
- Support the project
- Contributing · License
Looking for the full tooling matrix? See REQUIREMENTS.md for the complete required + optional dependency list per platform (Windows / Linux ARM-RPi / Linux x64), with firewall rules and hardware sizing guidance.
A single self-hosted backend that drives the whole night from any browser — acquisition, guiding, focusing, planning, live stacking, and a full post-processing suite with in-browser AI. Highlights:
- Equipment — INDI (400+ Linux drivers), ASCOM/Alpaca over the network, direct ASCOM COM on Windows, and native ZWO / SVBony / Player One / ToupTek camera SDKs. DSLR/mirrorless (Canon, Nikon, Sony). Multi-rig profiles, an INDI property browser, and a one-click equipment simulator for hardware-free testing.
- Acquisition — real-time image streaming (LZ4 raw or JPEG, adaptive), plate-solve & center, PHD2 + a built-in native autoguider, manual focus assist + V-curve auto-focus, meridian-flip automation, dithering.
- Planning & automation — tree-based Advanced Sequencer, ASIAIR-style multi-target night planner (PLAN), mosaic planner, simple sequences, a plugin system, and a sky catalog / atlas / map with weather and Tonight's-Best.
- EAA & video — live stacking with calibration, SNR/HFR, and client-side (WASM) compute offload for weak hosts; planetary / lucky-imaging video capture and stacking.
- Post-processing (STUDIO + EDITOR) — calibrate, integrate, channel combine (RGB/LRGB/PixelMath), color calibration (BG-neutralize / manual / photometric PCC), crop, and a non-destructive editor. In-browser AI via ONNX/WebGPU: GraXpert 🌃 BGE / ☄ Denoise / 🌌 Deconvolution, plus 🌠 star removal (nox / starrem2k13 / StarNet++) and 🎚️ Image Blend. Optional NPU acceleration on RK35xx boards.
- Access & ops — responsive Web UI, in-app help/tutorials, authentication,
relay server for remote access without port-forwarding, WiFi hotspot↔station
switch, mDNS (
nina.local), remote terminal (SSH in the browser), debug logging, polar alignment (TPPA + rudimentary), and SBC self-update.
The full documentation lives in docs/ — that index
organizes every page by area. The essentials:
- User Guide — start here. Install → first night → end-to-end workflow, plus a reference page per sidebar tab.
- Feature overview — what every tab does, at a glance.
- API & Configuration reference — REST endpoints,
WebSocket streams,
appsettings.json, environment variables. - Requirements matrix — dependencies per platform.
- Architecture · Contributing
- Setup guides: Raspberry Pi, GraXpert, Siril, DSLR (Canon / Nikon / Sony / Linux), mounts & WiFi.
nina-polaris/
├── src/
│ ├── NINA.Polaris/ ← ASP.NET Core app (Kestrel, Minimal API)
│ │ ├── Program.cs ← Host builder, service registration
│ │ ├── Endpoints/ ← REST API (13 endpoint groups)
│ │ ├── WebSocket/ ← Image stream + status broadcast
│ │ ├── Services/ ← Business logic layer
│ │ └── wwwroot/ ← Web UI (HTML, JS, CSS)
│ │
│ ├── NINA.Core.Portable/ ← Shared enums, models, utilities (net10.0)
│ ├── NINA.Image.Portable/ ← Image processing, FITS I/O, statistics (net10.0)
│ └── NINA.INDI/ ← INDI protocol client (net10.0)
│ ├── Protocol/ ← XML parser/writer
│ ├── Client/ ← TCP client, blob receiver, connection manager
│ └── Devices/ ← 9 device type implementations
│
│ ├── NINA.Relay.Protocol/ ← Shared multiplexed frame format (net10.0)
│ └── NINA.Relay.Server/ ← Standalone reverse-tunnel relay (ASP.NET Core)
│
├── tests/
│ └── NINA.Polaris.Test/ ← 294 unit tests (NUnit)
│
├── deploy/ ← Deployment scripts
│ ├── nina-polaris.service ← systemd unit file
│ ├── install.sh ← Linux installer
│ ├── publish-linux-arm64.sh ← RPi build script
│ ├── publish-win-x64.ps1 ← Windows build script
│ └── docker-build.sh ← Multi-arch Docker buildx
│
├── Dockerfile ← Multi-stage, linux/amd64 + arm64
└── docker-compose.yml ← NINA + optional indiserver sidecar
| Layer | Technology | Purpose |
|---|---|---|
| Web server | Kestrel (standalone) | Native .NET, no nginx/IIS needed |
| API | ASP.NET Core Minimal API | Low overhead, AOT-friendly |
| Real-time (images) | WebSocket (binary) | JPEG or LZ4-compressed raw frames, adaptive |
| Real-time (status) | WebSocket (JSON) | Equipment + sequence + guider + AF + meridian flip at 1Hz |
| Frontend framework | Alpine.js v3 | Reactive UI (~15KB, no build step) |
| UI typeface | Inter (SIL OFL 1.1, self-hosted) | Variable woff2 for every weight + italic, ~740 KB total. No external CDN call, the UI looks the same online and offline |
| Charts | Chart.js v4 | Guiding, focus, HFR, temperature, histogram, altitude |
| Sky map | stellarium-web-engine (AGPLv3, sandboxed in /sky/ iframe) |
WebGL2 sky viewer with Gaia stars, DSO surveys, constellation art, atmosphere, HiPS Milky Way tiles |
| Image viewer | OpenSeadragon | Full-resolution zoom/pan over last frame |
| Image rendering | WebGL2 shaders | GPU debayer + MTF stretch (CPU fallback) |
| Image encoding | SkiaSharp | Cross-platform JPEG / PNG encoding (incl. STUDIO previews + thumbnails) |
| FITS I/O | Custom FITSWriter | Extended headers per N.I.N.A. manual spec |
| XISF I/O | Custom XISFWriter | PixInsight native, LZ4-compressed, FITSKeyword mirrored |
| TIFF export | Custom TiffWriter | Baseline uncompressed 8-bit / 16-bit grayscale (SkiaSharp doesn't ship TIFF) |
| STUDIO frame index | Microsoft.Data.Sqlite | On-disk metadata cache so 2000-frame sessions list in < 50 ms |
| Astronomy ephemeris | CosineKitty.AstronomyEngine | Planet positions for the Tonight's Best panel (MIT, ~150 KB, no native deps) |
| Sun / moon math | SunCalc (BSD-2, vendored) | Sunset / sunrise / twilight / moon phase for the Weather panel |
| Weather forecast | 7Timer ASTRO (HTTP, no key) | Cloud / seeing / transparency, 3-day window in 3 h slots |
| Compression | K4os.Compression.LZ4 | Fast image compression (~2GB/s) |
| Equipment drivers | INDI protocol (TCP/XML) + Alpaca (HTTP) | 400+ Linux drivers + ASCOM over network |
| Plate solving | ASTAP / PlateSolve3 / Astrometry.net (online + local) | Strategy dispatcher with primary + blind fallback |
| Guiding | PHD2 (TCP/JSON-RPC, port 4400), fully managed | Profile switch, equipment connect, process launch/shutdown |
| Remote access | NINA.Relay.Server reverse tunnel | Public access without inbound port-forwarding |
| Discovery | Makaretu.Dns.Multicast | mDNS announcer for nina.local |
| Geocoding | Nominatim (OpenStreetMap, proxied) | Address → coordinates for location setup |
| Stellarium sync | HTTP (Remote Control plugin, port 8090) | Pull selected object as target |
| Logging | Serilog | Structured logging to console + file |
| Target framework | .NET 10.0 | Latest LTS, cross-platform |
Minimum to build + run from source:
- .NET 10 SDK
- Git (with submodules: stellarium-web-engine is pulled at build time)
- On Linux for hardware control:
sudo apt install indi-full - Optional plate-solving: ASTAP + H17/H18 database
For the complete tooling matrix, Windows + Linux ARM (Raspberry Pi) + Linux x64, required vs optional per feature, firewall rules, hardware sizing, see REQUIREMENTS.md.
git clone https://github.com/DanWBR/nina-polaris.git
cd nina-polaris
dotnet build
dotnet run --project src/NINA.PolarisOpen http://localhost:5000 in your browser.
dotnet testThe .deb package (built automatically by GitHub Actions on every
tag push) handles user creation, systemd unit, indi-web venv, apt
dependencies, and self-signed HTTPS cert generation. End-user install:
wget https://github.com/DanWBR/NINA.Polaris/releases/latest/download/polaris_arm64.deb
sudo apt install ./polaris_arm64.deb
# 30 seconds later: Polaris running at https://<hostname>.local:5000The postinst prints the URL, sets up the service, and starts it. Full breakdown in packaging/README.md. Pi- specific end-to-end recipe (hardware checklist, OS flashing, optional SSD mount) in docs/user-guide/raspberry-pi-setup.md.
Manage the service:
sudo systemctl status polaris # Check status
sudo journalctl -u polaris -f # Follow logs
sudo systemctl restart polaris # RestartFor non-Debian distros (Fedora, Arch, etc) or when you prefer no systemd integration:
wget https://github.com/DanWBR/NINA.Polaris/releases/latest/download/polaris-linux-arm64.tar.gz
tar -xzf polaris-linux-arm64.tar.gz
cd polaris-linux-arm64
./NINA.Polaris # foreground; wire your own service unit if neededReplace linux-arm64 with linux-x64 for Intel/AMD 64-bit Linux.
Download the portable zip from GitHub Releases:
# x64 (most desktops/laptops):
Invoke-WebRequest -Uri "https://github.com/DanWBR/NINA.Polaris/releases/latest/download/polaris-win-x64.zip" -OutFile polaris.zip
Expand-Archive polaris.zip
cd polaris-win-x64
.\NINA.Polaris.exe
# ARM64 (Surface Pro X, some Copilot+ PCs):
Invoke-WebRequest -Uri "https://github.com/DanWBR/NINA.Polaris/releases/latest/download/polaris-win-arm64.zip" -OutFile polaris.zip
Expand-Archive polaris.zip
cd polaris-win-arm64
.\NINA.Polaris.exeOpen https://localhost:5000 (accept the self-signed cert once).
For unattended Windows installs, wire your own service via sc.exe,
NSSM, or a scheduled task. Build-from-source path:
.\deploy\publish-win-x64.ps1Multi-stage Dockerfile and docker-compose.yml are checked in. Builds for both linux/amd64 and linux/arm64:
# Single host build (uses your platform)
docker compose up -d --build
# Multi-arch build + push to registry
REGISTRY=ghcr.io/yourname ./deploy/docker-build.sh latestThe default compose file runs in network_mode: host so mDNS and INDI LAN
reach work out of the box. Add --profile indi to also start an
indiserver sidecar with the standard simulators (good for testing with no
hardware).
Persistence:
nina-datavolume → profiles + trained-flat exposures./imagesbind-mount → captured FITS output
The Web UI is built entirely on a documented REST + WebSocket surface, so
everything it does is scriptable. The complete endpoint list, WebSocket stream
payloads, appsettings.json keys, and environment variables are in:
| Metric | Target | Notes |
|---|---|---|
| Memory | < 500 MB | RPi 4 with 2GB RAM |
| Startup | < 5 seconds | RPi 4 |
| Image relay | ~3-10 MB/frame | LZ4 compressed, fits WiFi 5GHz |
| JPEG preview | ~200-400 KB | For mobile/weak clients |
| Frontend bundle | ~580 KB total | Alpine.js + libs, cacheable |
| WASM live-stack bundle | ~12 MB on disk, ~3 MB gzipped | One-time download per browser |
| Status broadcast | 1 Hz | Equipment + sequence state |
Polaris ships with a one-click button to spawn a fake telescope +
camera + focuser + filter wheel. Open Settings → Equipment simulator
→ Launch. The simulated camera renders real stars from the GSC
catalog at whatever RA/Dec the simulated mount is pointing at,
plate solve, auto-focus, live stacking all work end-to-end against
it. Linux/macOS uses INDI simulators (apt install indi-bin);
Windows uses Alpaca Omni Simulator. See
docs/user-guide/simulator-mode.md.
Live stacking can run in your browser via a WebAssembly module
that reuses the same NINA.Image.Portable algorithms the server
runs. On Pi 2 / Pi 3 hosts this is the only way to keep up, the
Pi just orchestrates equipment + relays raw frames, the browser
does StarDetector + alignment + accumulator. Auto-detected on WS
handshake; per-rig override in the LIVE tab toolbar. See
docs/user-guide/client-side-compute.md.
If N.I.N.A. Polaris saves you an evening of fiddling with rigs and you want to chip in for hosting / a coffee / dark-sky travel:
Donations are entirely optional, the project stays free and open-source either way. Bug reports and PRs are just as welcome (see below).
Contributions are welcome! This project follows the same coding standards as the main N.I.N.A. repository.
- Endpoints are in
src/NINA.Polaris/Endpoints/, each is an extension method onWebApplication - Services are in
src/NINA.Polaris/Services/, registered as singletons inProgram.cs - INDI devices follow a consistent pattern in
src/NINA.INDI/Devices/ - Frontend is plain HTML/JS/CSS in
src/NINA.Polaris/wwwroot/, no build step required - Tests go in
tests/NINA.Polaris.Test/using NUnit
When the Photometric Color Calibration (PCC) workflow is enabled,
Polaris uses the AAVSO APASS DR10 star catalog under a CC-BY
4.0 license. The catalog is downloaded by scripts/download-apass.py
to wwwroot/catalogs/apass/apass.db (gitignored). If you publish
images calibrated with PCC, please credit:
Henden, A. A., Levine, S., Terrell, D., Welch, D. L., Munari, U., & Kloppenborg, B. K. (2018). "The APASS Data Release 10." VizieR On-line Data Catalog: II/336. https://www.aavso.org/apass
N.I.N.A. Polaris stands on the shoulders of a large community of astronomy and
open-source projects. Some we derive code from, some we studied as a reference,
and many ship inside the capture and processing stack. The same list is shown
in-app under HELP -> Credits & acknowledgements. Thank you to every author
below. Per-component license details are in ### Third-party licenses,
the licenses/ folder, and the bundled 3rd-party-licenses notice.
Built on
- N.I.N.A. - Nighttime Imaging 'N' Astronomy - Stefan Berg and the N.I.N.A. contributors. Polaris is derived from N.I.N.A. (MPL-2.0).
Guiding & gear simulation
- PHD2 - Open PHD Guiding - Andy Galasso, Bret McKee, Craig Stark and the PHD2 contributors. Managed external guider, and the reference for the native autoguider + gear simulator (BSD-3-Clause).
Image processing & AI
- GraXpert - the GraXpert development team. Background extraction, denoise and deconvolution ONNX models, and the default auto-stretch algorithm.
- nox - charvey2718. StarNet-like star-removal model (native colour + gray), the default behind FILES → Remove stars. Code and weights MIT.
- starrem2k13 - code2k13. pix2pix-style U-Net star-removal model, an alternative in FILES → Remove stars. Code and weights MIT.
- StarNet++ - Nikita Misiura (nekitmm). The original star-removal neural network. Code MIT; pre-trained weights © Nikita Misiura, CC BY-NC-SA 4.0 (NonCommercial).
- Siril - the Free-Astro / Siril team. Optional external pre-processing and stacking.
Plate solving
- ASTAP - Han Kleijn. Default fast offline solver and star database.
- Astrometry.net - Dustin Lang, David W. Hogg and collaborators. Local and online blind solving.
- PlateSolve3 - PlaneWave Instruments. Alternative solver.
Equipment, protocols & camera SDKs
- INDI Library - Jasem Mutlaq and the INDI community. Primary equipment-control protocol.
- ASCOM Initiative & Alpaca - the ASCOM Initiative. Windows COM drivers and the cross-platform Alpaca protocol.
- ZWO ASI SDK - Suzhou ZWO Co., Ltd.
- SVBony SDK - SVBONY.
- Player One SDK - Player One Astronomy.
- ToupTek SDK - ToupTek Astro.
- Nikon SDK - Nikon Corporation. Nikon DSLR / mirrorless support.
- Canon EDSDK - Canon Inc. Canon EOS DSLR / mirrorless support on Windows.
- Sony Camera Remote SDK - Sony Corporation. Sony Alpha camera support on Windows.
- libgphoto2 / gPhoto2 - the gPhoto team. DSLR / mirrorless support on Linux (via the INDI gphoto driver).
Sky data, catalogs & astrometry
- OpenNGC - Mattia Verga. Bundled NGC/IC/Messier/Caldwell catalog (CC BY-SA 4.0).
- APASS - AAVSO Photometric All-Sky Survey - the AAVSO. Reference photometry for color calibration.
- Aladin Lite - CDS, Universite de Strasbourg / CNRS. Interactive sky atlas.
- Stellarium Web Engine - Stellarium Labs / Guillaume Chereau and contributors. WebGL planetarium sky view (AGPL-3.0).
- Astronomy Engine - Don Cross. High-precision ephemeris and coordinate math.
In-browser UI
- Alpine.js - Caleb Porzio and contributors.
- Chart.js - the Chart.js contributors.
- OpenSeadragon - the OpenSeadragon contributors.
- noVNC - the noVNC authors (MPL-2.0).
- xterm.js - the xterm.js authors.
- SunCalc - Vladimir Agafonkin.
- SortableJS - the SortableJS contributors.
Server & .NET
- Silk.NET - the .NET Foundation. OpenCL bindings for the SBC GPU compute backend.
- SkiaSharp - Microsoft, wrapping Google's Skia.
- ONNX Runtime - Microsoft. Runs the GraXpert AI models in the browser.
- YARP - Microsoft. Reverse proxy for embedded device web UIs.
- .NET Community Toolkit (MVVM) - the .NET Foundation.
- K4os.Compression.LZ4 - Milosz Krajewski.
- LettuceEncrypt - Nate McMaster.
- Serilog - the Serilog contributors.
- Json.NET - James Newton-King.
- SSH.NET - the SSH.NET contributors.
- SMBLibrary - Tal Aloni. Pure-managed SMB1/SMB2 client for the "auto-push images to network storage" backend.
- net-mdns (Makaretu.Dns) - Richard Schneider.
nina.localdiscovery. - SQLite - D. Richard Hipp and the SQLite team.
- Rockchip RKNN runtime - Rockchip. Optional NPU acceleration on RK35xx boards.
Plus the wider amateur astronomy and free-software communities. If your work is used here and not listed, it is an oversight, not an intent, please let us know.
N.I.N.A. Polaris as a whole is licensed under the GNU Affero General Public
License v3.0 (AGPL-3.0). See LICENSE.txt and
NOTICE.
Portions are derived from N.I.N.A. - Nighttime Imaging 'N' Astronomy,
Copyright (C) Stefan Berg and the N.I.N.A. contributors, under the Mozilla
Public License 2.0 (licenses/MPL-2.0.txt). Those
files keep their MPL header; per MPL-2.0 section 3.3 they are combined into
this AGPL-3.0 Larger Work and a recipient may use those specific files under
either the MPL-2.0 or the AGPL-3.0.
A limited additional permission (linking exception) covers proprietary camera
vendor SDKs and dynamically-loaded plugins - see
licenses/LINKING-EXCEPTION.txt.
Because Polaris is a network-served application, AGPL-3.0 section 13 applies: if you run a modified version as a service, you must offer its source to users. Releases published before the relicensing remain available under the MPL-2.0.
- PHD2 (OpenPHDGuiding) -- BSD-3-Clause. The native autoguider
(
NINA.Guider.Portable) ports PHD2's core guiding math (single-star centroid, calibration, Hysteresis + Resist-Switch algorithms, camera/mount transforms) to C#. Each ported file carries the PHD2 BSD-3 header; the full license text is inlicenses/PHD2-LICENSE.txt. PHD2 is Copyright (c) the Open PHD Guiding development team and the Max Planck Society. See https://openphdguiding.org. - Silk.NET -- MIT. Managed OpenCL bindings used by the optional SBC GPU
compute backend (
NINA.Polaris.Services.OpenCl). Copyright (c) .NET Foundation and Contributors. See https://github.com/dotnet/Silk.NET.