Skip to content

Development Guidance

Russ Leikis edited this page Sep 25, 2026 · 10 revisions

Ultra-Tracker Developer Guide

🛠️ First-Time Setup

Run these commands sequentially from your terminal to configure your local environment.

# 1. Install package managers & core tools (Windows PowerShell)
winget install --id Microsoft.PowerShell --source winget
iwr https://pnpm.io -useb | iex
Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe

# 2. Install Node.js, Git, and clone the repository
winget install OpenJS.NodeJS
winget install --id Git.Git -e --source winget # Linux: sudo apt install git
git clone https://github.com
cd ultra-tracker

# 3. Install dependencies and run development server
pnpm install
pnpm rebuild
pnpm dev

💡 Tip: To pull the latest updates later without losing your config or database, run git pull and repeat steps 6 and 7. The folder can be opened directly in VSCode for debugging support.


💧 Annual Environment Hydration (2026)

If you are returning to the project after a long break, use this condensed sequence to securely bypass package supply-chain risks and align native modules.

  • A project-level script isolation has been added to the baseline configuration in the root level .npmrc file
  • An overrides block has been added to package.json for packages with specific compatibility issues
    • vite ^7.3.6
    • @babel/core ^7.26.2
# 1. Apply Reconciled Package Configuration and Security Overrides
pnpm install

# 2. Remediate the Outdated Browser Database
npx update-browserslist-db@latest

# 3. Manually Extract the Local Platform Binary
node .\node_modules\electron\install.js

# 4. Recompile the Native SQLite Driver
pnpm dlx @electron/rebuild --only better-sqlite3

# 5. Validate and Launch the Application Frame
pnpm start

🧪 Local Development Workflow

Ultra-Tracker requires Node 22 or newer. Running pnpm install downloads and uses a matching version of Node automatically, so no manual version switching is needed.

Use the platform scripts to reset or prepare a development environment:

  • Windows safe clean: powershell -ExecutionPolicy Bypass -File ./clean-dev.ps1
  • Windows deep clean: powershell -ExecutionPolicy Bypass -File ./clean-dev.ps1 -Deep
  • Linux/macOS safe clean: sh ./clean-dev.sh
  • Linux/macOS deep clean: sh ./clean-dev.sh --deep
  • Windows hydration: powershell -ExecutionPolicy Bypass -File ./hydrate-dev.ps1
  • Linux/macOS hydration: sh ./hydrate-dev.sh

Safe cleanup removes disposable development artifacts. Deep cleanup also deletes local databases, environment files, and generated API/test data. Review those files before using the deep option. Hydration installs dependencies, downloads the Electron binary, and rebuilds native modules; it does not start the application. Run pnpm dev or pnpm start separately afterward.

Common commands:

  • pnpm dev — Runs the application in development mode.
  • pnpm test — Runs the test suite once and reports the result.
  • pnpm test:watch — Runs the test suite and re-runs it as files change.
  • pnpm test:coverage — Runs the test suite and produces a coverage report.
  • pnpm lint and pnpm typecheck — Check formatting, lint rules, and TypeScript types.

Tests are written with Vitest and live in a tests/ folder beside the code they cover, such as src/main/database/tests/. Every pull request runs the test suite, lint, and typecheck.


🗂️ Project Architecture

Implementation logic is divided into specialized environments within the src/ directory. Avoid using the frontend client for backend tasks to prevent synchronization bugs.

├───main // Backend (Database access, IPC channels, internal libraries)
│ ├───api // Server API (RFID reader push)
│ ├───database // Only database access
│ ├───ipc // IPC to frontend
│ ├───lib
│ └───services // External integrations (e.g. OpenSplitTime client)
├───preload // Middleware bridge
├───renderer // Frontend Client (Assets, UI components, hooks, router)
└───shared // Global types and common data (Do not use as an IPC bypass)

The frontend client is divided into Assets, UI components, hooks, and routers.

├───renderer // Frontend Client: Run inside the Chromium window browser process
│ └───src
│ ├───assets // Static media: Global images, icons, fonts, and stylesheets
│ ├───components // Shared UI elements: Reusable, dumb components (buttons, inputs)
│ ├───features // Domain modules: Self-contained business logic and layout sections
│ │ ├───Backdrop // App loading/blocking overlay
│ │ ├───DataGrid // Shared data grid primitives
│ │ ├───ExportPage // CSV/export workflows
│ │ ├───Footer // Bottom navigation bar, connectivity/push status indicators
│ │ ├───Header // Top navigation, window control buttons, and profile menus
│ │ ├───HelpPage // In-app help/documentation
│ │ ├───LogsPage // Normal/verbose log viewers
│ │ ├───RosterPage // Athlete roster management
│ │ ├───RunnerEntry // BIB# entry and fast-key timing input
│ │ ├───SettingsPage // App, database, and OpenSplitTime settings
│ │ ├───Sidebar // Primary navigation sidebar
│ │ ├───StationsPage // Station configuration view
│ │ └───Toasts // Non-blocking notification popups and system status alerts
│ ├───hooks // Custom React hooks: State managers and isolated component logic
│ ├───lib // Client utilities: Network clients, formatters, and third-party setups
│ └───routes // Application routing: Page definitions and view-switching paths


🚀 Production, Releases & Maintenance

App Bundling & Local Installation

# Compile standalone installers
pnpm build:win    # Windows
pnpm build:mac    # macOS
pnpm build:linux  # Linux

To install, simply double-click the newly created executable file.

Automated GitHub Releasing

  1. Update the version string inside package.json.
  2. Commit the bump: git commit -m "chore(release): bump version to 1.0.0".
  3. Tag and push to trigger the automated drafting workflow:
    git tag v1.0.0
    git push origin v1.0.0

Code Quality & Linting

pnpm lint      # View formatting and code syntax errors
pnpm lint:fix  # Automatically resolve common style issues

🔍 Troubleshooting

better-sqlite3 Errors after restructuring

Folder movements break pre-compiled native bindings. Clear any syntax errors in your code, then trigger a native module rebuild:

pnpm rebuild

Network Resolution (RequestError: getaddrinfo ENOENT ://npmmirror.com)

Ensure your firewall, proxy, or ISP allows traffic to ://npmmirror.com.

Missing Python Environment (gyp ERR! find Python)

Ensure Python is installed and globally exposed via your system's environment variables (PATH).

Missing C++ Build Tools (gyp ERR! find VS)

node-gyp requires native C++ compilation workloads. Install Visual Studio Community along with the required desktop workloads using either option below:

# Option A: Native Winget Installer
winget install Microsoft.VisualStudio.2022.Community --silent --override "--wait --quiet --add ProductLang En-us --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"

# Option B: Chocolatey Package Manager
choco install visualstudio2022community visualstudio2022-workload-manageddesktop visualstudio2022-workload-manageddesktopbuildtools visualstudio2022-workload-nativedesktop visualstudio2022-workload-vctools -y