Tech Stack

Current State (Existing Free App)

  • Frontend: FlutterFlow (generates Dart/Flutter code)
  • Backend: Supabase (Postgres + auth + realtime)
  • Architecture: No backend logic layer — app talks directly to Supabase

The existing app will eventually be replaced. The new stack is greenfield.

Planned Direction

Shared Rust Core (Public)

A Rust crate containing client-safe business logic — validation, scoring, data models, sync protocol, offline queue management, protobuf serialization. This crate ships to every consumer:

  • Server: imported directly as a Rust dependency
  • Web app: imported directly (compiles to WASM)
  • iOS: compiled to a native library, Swift bindings generated by UniFFI
  • Android: compiled to a native library, Kotlin bindings generated by UniFFI

No server-only logic lives here. Anything in this crate can be decompiled from WASM or native binaries.

Server (Private)

Rust (Axum). Imports the shared core crate and adds all server-only business logic — authentication, authorization, subscription/billing, admin operations, database queries. This code never leaves the server. Postgres database.

Marketing Site

Static HTML + Tailwind CSS. The public-facing landing page at the root domain. Explains the product and routes users to the right destination:

  • Admins/Instructors → dashboard login
  • Shooters → app download (iOS App Store, Google Play, or install PWA)

Built with Tailwind CLI — full utility classes in source, minified to only used rules in production. No framework, no JS runtime.

Admin Dashboard

Dioxus (Rust → WASM). The admin web app for event management, drill building, roster management, org settings, and score review. Imports the shared core crate (not the server crate). Fullstack integration with Axum for SSR, server functions, and WebSocket support.

PWA

Dioxus (Rust → WASM). A separate, shooter-facing web app for users who can’t or won’t install the native app. Read-heavy, light interaction at MVP. Imports the shared core crate. Deployed independently from the dashboard.

Native Mobile Apps

  • iOS: Swift + SwiftUI — calls the Rust core via UniFFI-generated Swift bindings
  • Android: Kotlin + Jetpack Compose — calls the Rust core via UniFFI-generated Kotlin bindings

Both apps run business logic locally via the embedded Rust library. They are not thin clients.

See Cross-Platform Strategy for the decision rationale.

Wire Format

Protocol Buffers (protobuf) for compact binary serialization of sync payloads and API communication.

See Protobuf Schema Strategy for details.

Database

  • Server: Postgres
  • iOS: SwiftData (with Rust core handling data logic)
  • Android: Room (with Rust core handling data logic)
  • PWA: IndexedDB

Monorepo Structure

monorepo/
  proto/                 # .proto definitions (wire format)
  libs/
    core/                # shared (public): models, validation, scoring, sync, protobuf
    uniffi-bindings/     # UniFFI binding generation for Swift + Kotlin
  apps/
    marketing/           # static HTML + Tailwind CSS — landing page, links to dashboard and app downloads
    server/              # Rust/Axum — private: auth, billing, admin ops, DB queries
    dashboard/           # Rust/Dioxus — admin web app (event mgmt, drill builder, org settings)
    pwa/                 # Rust/Dioxus — shooter-facing PWA (read-heavy, light interaction)
    ios/                 # Swift + SwiftUI (consumes UniFFI-generated bindings)
    android/             # Kotlin + Jetpack Compose (consumes UniFFI-generated bindings)
  cli/                   # rangeday CLI — dev tooling for all monorepo operations
  docs/                  # documentation (this vault)

Key Principles

  • Rust is the shared language — client-safe business logic written once in the core crate, runs natively everywhere. Server-only logic stays in the server crate.
  • Native UI where it matters — SwiftUI and Jetpack Compose for mobile, Dioxus for web.
  • UniFFI for cross-language bindings — generates typed Swift and Kotlin interfaces from Rust code. Changes to the Rust core surface as compile errors in all consumers.
  • Protobuf for wire format — compact binary serialization for sync and API communication.
  • AI-assisted multi-platform development — features described once, implemented across Rust, Swift, and Kotlin in parallel.