Skip to content
hello-nexusPublic

About

Nexus React dashboard and panel SPA

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4,773 Commits

Folders and files

Repository files navigation

nexus-web

React + TypeScript + Vite dashboard for Nexus. The same bundle is shipped two ways:

  • Standalone web app - served via the bundled Node server (npm start) or any static host. Serves hellonexus.com (marketing site) and my.hellonexus.com (the app surface) from one deployment; server.js routes / by host (see Surfaces below).
  • Service-embedded UI - built into nexus-service and served by the local service (Windows, macOS, Linux) on http://127.0.0.1:9400 / https://127.0.0.1:9443. Builds with npm run build:service.

The marketing site is a second Vite entry (site/index.html -> src/site/) that imports the app's real components (palette ring, shader renderer, curve editor, gauges) as live demos on mock data. It is emitted only by the standalone build - npm run build:service excludes the entry, so marketing content never ships inside the desktop app.

Setup

Prerequisites: Node.js 22.12 or newer (Vite supports ^20.19.0 || >=22.12.0).

npm install
npm run dev        # http://localhost:5173

The dev server expects a running nexus-service at http://127.0.0.1:9400 for live data; start one with dotnet run in the sibling nexus-service repo. Debug builds of the service accept Vite dev-server origins via CORS, so no extra configuration is needed.

Standalone production build:

npm run build      # outputs dist/ (SPA + dist/site/ marketing page)
npm start          # serves dist/ at http://localhost:3000 (override with PORT)

With npm start, http://localhost:3000/ is the marketing page and http://my.localhost:3000/ is the app surface (browsers resolve *.localhost to loopback). In npm run dev there is no host routing: the SPA is at / and the marketing page at /site/ (trailing slash).

Service-embedded build (normally triggered automatically by the nexus-service build, which copies dist/ into its wwwroot/):

npm run build:service

Surfaces

The app routes a small set of top-level surfaces from the URL path:

Path Purpose
/ Host-dependent in the standalone deployment: my.* hosts (my.hellonexus.com, my.localhost) get the dashboard; every other host gets the marketing page (dist/site/index.html). Embedded/dev builds always serve the dashboard. On a remote origin without a reachable local service the dashboard shows the launch/download gate (app/ServiceGatePage.tsx).
/panel/:deviceId Kiosk panel surface for embedded touchscreens.
/panel/phone Mobile remote surface (paired via QR).
/r/pair iOS Universal Link landing page (App Store / browser fallback).
/auth/verify Email verification landing page. Browser-only.
/auth/recover Lost-password magic-link landing page. Browser-only.
/auth/confirm-password Confirms a password change made without the current password (emailed link). Browser-only.
/login, /register, /recover, /account, /u/:username server.js 302-redirects these to the same path on https://build.hellonexus.com, which hosts sign-in, the account page and public profiles.
/telemetry-reference Dev reference view listing the analytics events the app emits.

/touch and /panel/q60 are legacy aliases that land in the panel allocation flow.

Only / is host-routed - every deeper path serves identically on all hosts, so /r/pair QR links, /panel/phone relay-paired phones (whose session tokens live under the hellonexus.com origin), and emailed /auth/* links keep working unchanged.

/download serves the marketing downloads page (all platforms + latest version). The canonical per-OS URLs /download/windows|macos|linux (and the win/mac short forms) 302 to the newest downloadable release's asset, resolved server-side via the GitHub releases API (latest stable, or the newest prerelease while no stable exists - GitHub's static latest/download alias 404s until then).

/auth/verify, /auth/recover and /auth/confirm-password are dead-code-eliminated from npm run build:service (same __SERVICE_BUILD__ build-define technique as the __DEV_TOOLS__ gate) - they only ever ship in the standalone build served at hellonexus.com.

The Build portal (build.hellonexus.com) renders its sign-in, account and profile pages from the same components as the in-app Settings > Account view (components/views/SettingsView/Account/, app/public/DeviceSpecsCard.tsx, app/public/PublicProfileBenchmarks.tsx, app/public/usePublicAccount.ts), swapped onto an AuthBackend adapter that talks to api.hellonexus.com directly (api/directApiBackend.ts) instead of the in-app adapter that proxies through the local service (api/localServiceBackend.ts). In-app profile links go through lib/publicProfile.ts.

Cloud profiles are not part of the account surface: their backup status and the cross-machine import live under Settings > Profiles (CloudProfilesSection), next to the profiles they act on, and show a sign-in prompt when signed out. Profiles are backed up per machine, so copying config between machines is an explicit import (ImportFromMachinePanel) that overwrites only the categories the user ticks.

Project layout

Everything ships from src/. Top-level folders:

Folder Contents
api/ Typed REST/WS clients for nexus-service + the cloud API - one file per domain (cooling, lighting, displays, keeb, gallery, panel, internetPairing…). Host resolution lives in api/service.ts.
app/ Desktop dashboard shell: Dashboard.tsx, sidebar, pairing modals, panel entrypoint + routing, window caption buttons. app/public/ holds the emailed account landings and the account pieces the Build portal reuses (see Surfaces above).
assets/ Static image assets bundled into the app (e.g. flags/ for locale flags).
components/ Shared React components - common/ (design-system primitives), views/ (full dashboard sections), icons/.
diag/ Renderer diagnostics - the memory/health probe that reports JS-heap, DOM-node, and reconnect samples to the service log (/diagnostics/client-mem) on significant change.
hooks/ Reusable hooks, mostly data/state (useDevices, useCooling, useMultiplexSocket…).
lib/ Non-React utilities + stores (appStore, monitoringStore, i18n, settings, codecs, sensor resolvers).
locales/ The i18n JSON bundles (en + 16 others).
overlay/ The /overlay surface - per-monitor overlay shell + bridge to nexus-overlay.exe.
panel/ The kiosk/phone panel surface and its own rendering engine (engine/, editor/, chrome/, theme/, dnd/, background/, overlays/, embed/ simulator). panel/widgets/ holds the built-in widget implementations.
sandbox/ Host runtime for sandboxed SDK widgets ("Nexus apps"): boots a hardened Web Worker per widget, installs the nexus.* API, and renders the worker's remote-dom tree. This is what executes third-party app bundles.
search/ Global command palette / top search (providers, fuzzy match, frecency).
site/ The marketing site (site/index.html entry at the repo root -> src/site/): long-scroll landing page whose feature demos mount the app's real components on mock data. Standalone build only. Bundled shader copies live in src/site/shaders/ (see its README).
storybook/ In-app component gallery - not the npm Storybook tool; a dev surface that previews design-system components.
styles/ Global SCSS (variables, text, scrollbar, interactions, reset).
telemetry/ Analytics events + a reference view listing them.
types/ Shared TS types + ambient declarations (scss.d.ts, global.d.ts).
widgets/ Client glue for the marketplace/SDK app layer - wire types, installed-apps API, marketplace registry, settings bridge. Feeds installed apps into the panel picker.
__tests__/ Cross-cutting test suites + vitest setup.

Three "widget/app" layers are easy to confuse: panel/widgets/ is the built-in widgets; widgets/ is the marketplace feed that injects installed SDK apps into the panel picker; sandbox/ is the runtime that hosts those SDK apps. The app bundle sources live outside this repo.

Scripts

npm run dev              # vite dev server
npm run build            # standalone build (dist/)
npm run build:service    # build that nexus-service embeds
npm run preview          # preview the production build
npm start                # serve dist/ with the bundled Express server
npm run lint             # eslint
npm test                 # vitest unit tests (single run)
npm run test:watch       # vitest watch mode
npm run test:e2e         # playwright (run `npx playwright install` once first)
npm run test:e2e:ui      # playwright UI mode
npm run test:e2e:sandbox # playwright, SDK sandbox only (needs `cd sdk && npm ci && npm run build` once)
npm run audit:locales    # locale key sync check
npm run audit:styles     # style audits (also: audit:text-styles)
npm run export:deck-icons # renders DECK_ICONS to PNGs for nexus-service's deck key renderer

Tests default to the jsdom environment, and building one is the largest cost in a run, paid per test file. A file that touches no DOM opts out with a // @vitest-environment node docblock; __tests__/setup.ts guards its DOM stubs so it still loads there. Vitest matches that comment anywhere in the file, so avoid writing it in a fixture or a doc comment.

Environment

  • VITE_SERVICE_HOST / VITE_SERVICE_PORT / VITE_SERVICE_PROTOCOL - override how the app reaches the local service. Defaults to 127.0.0.1:9400; the embedded build is same-origin.
  • VITE_API_URL - cloud API origin override. The compiled-in default is https://api.hellonexus.com, so every production build works without it; the committed .env.development points npm run dev at http://localhost:3000. Set it explicitly to target a local/staging API from a build.
  • NEXUS_CLIENT_TOKEN - build credential minted by release CI. Its presence sets the __OFFICIAL_BUILD__ define, which is what compiles in the account, profile-sync, remote-access, leaderboard, and updater surfaces. Absent (the default, and every public clone) those surfaces are absent and the client is local-only; the token itself is never put in the bundle. Falls back to ~/.nexus-build/client-token so a lab machine does not have to export it.
  • WEB_SOURCEMAPS - set to 1 (release CI does) to write hidden sourcemaps for symbolicating error reports. They hold paths and mappings but no source text, land in sourcemaps/ rather than dist/, and leave the shipped bundle byte-identical. The build fails if a map references a file outside this repo.
  • VITE_RELAY_URL - relay origin override for local relay testing.
  • VITE_LAN_SEALED - set to 1 to force the LAN-sealed transport (also toggleable at runtime via localStorage['nexus.lanSealed']). Debug flag.

Host resolution logic lives in src/api/service.ts.

Architecture

The authoritative transport, polling cadence, and WebSocket topic inventory live in the nexus-service repo: docs/network-transport.md, with the REST surface in docs/api-spec.md. Widget host architecture is documented under src/widgets/.

License

nexus-web is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0); see LICENSE for the full text. The app SDK package in sdk/publish (@hello-nexus/sdk) is MIT-licensed; see sdk/publish/LICENSE.

Copyright (C) 2026 Hello Nexus

About

Nexus React dashboard and panel SPA

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages