All projects

ThruHike

Mobile & mapsIn development

Offline itinerary planning with maps, camps, and resupply.

In development

In development. The trip wizard, resupply presentation, geographic calculations, and itinerary modules have implemented foundations. Production trail data, complete generation orchestration, maps, offline installation/sync, and public distribution are still being integrated.

Overview.

ThruHike is an offline-first mobile planning application for long-distance hikes. I’m building it to turn a hiker’s pace, dates, camp preferences, and resupply needs into an editable day-by-day plan, starting with the John Muir Trail and the Cottonwood approaches.

The engineering challenge is making the plan reproducible and traceable. Geographic calculations, itinerary rules, and source provenance live in deterministic modules. AI is intended to help interpret preferences and explain tradeoffs; it does not supply trail coordinates, mileage, legal rules, or safety claims.

Screens & workflows.

Application screens and development prototypes. Select a capture for a closer look.

Prototype: describe a trip

  1. Choose a trail and route variant from the supplied catalog.
  2. Set direction, endpoints, dates, and daily mileage preferences.
  3. Adjust terrain, camps, rest days, resupply, and waste-guidance preferences.
  4. Review the eleven-step draft and explicitly confirm it before generation.

Prototype: inspect resupply

  1. Open a supplied resupply summary.
  2. Compare planned stops, mailed boxes or local purchases, and the longest food carry.
  3. Review the recorded arrival targets and quantity information.
  4. Read freshness, provenance, and unknown-status warnings alongside the plan.

Planned: generate and refine an itinerary

  1. Submit confirmed preferences with a versioned, verified trail package.
  2. Calculate route-relative mileage, elevation, feature candidates, and daily constraints.
  3. Review the itinerary and lock stops that should remain fixed.
  4. Edit a stop, resupply, or rest day and recalculate the affected window while preserving locked choices.

Planned: take the trip offline

  1. Install a versioned trail package and map region before leaving service.
  2. Save the trip and its source evidence on the device.
  3. Read daily plans, resupply information, and field notes without a connection.
  4. Sync small user-owned records when service returns, separately from the large geographic package.

Inside the build.

Explore the components, their boundaries, and the decisions behind them.

The repository separates a React Native client, shared TypeScript contracts, a deterministic C# domain and itinerary engine, a trusted ingestion boundary, and data infrastructure. Many leaf modules are implemented and tested independently; production adapters and end-to-end composition remain explicit integration work.

Mobile planning experience

Collect, validate, and review trip preferences without treating UI guesses as trail facts.

  • The registry composes eleven wizard steps in the same canonical order used by validation and navigation guards.
  • Zustand owns draft state; React Hook Form and Zod support form and contract validation.
  • Trail and endpoint catalogs are injected ports. Unconfigured production routes show unavailable data; synthetic fixtures are confined to development and tests.

Design decisions & tradeoffs.

Keep AI outside geographic authority

Preferences may come from a natural-language interpretation, but verified source records and deterministic code own distances, locations, constraints, and results. The user confirms the structured input before generation.

The tradeoffCurated data, explicit validation, and more domain code take longer to build, but a fluent model response cannot silently become a trail fact.

Separate downloaded geography from synchronized edits

Large static trail data is designed to ship as versioned packages. The intended sync layer carries small user-owned records such as trips, notes, and edits.

The tradeoffPackage lifecycle and record synchronization need separate implementation, but bandwidth, versioning, and offline behavior can be reasoned about independently.

Make provenance part of the computation

Source identity, dataset version, confidence, and review history travel with the inputs and calculated output. Engine stages pin package and calculation identities instead of accepting loose coordinates or unbound scalars.

The tradeoffContracts are more demanding, but calculations remain traceable and stale or incomplete evidence stays visible.

Recalculate only the affected plan window

An edit is bound to a base revision and accepted stop snapshot. The affected-day module computes the bounded set of days that can change and stops propagation at locked choices.

The tradeoffLock and revision rules add complexity, but local changes do not need to discard the user’s entire itinerary.

Technical stack.

Mobile application

  • React Native
  • Expo SDK 57
  • Expo Router
  • TypeScript
  • React Native Web

Implemented client foundation and feature screens. Browser captures show the same React Native components in a development harness.

State & input

  • Zustand
  • React Hook Form
  • Zod

Draft state, validated wizard steps, confirmation, and guarded navigation.

Backend & geographic engine

  • C#
  • .NET 10
  • ASP.NET Core
  • GeographicLib.NET

Implemented API/domain boundaries and independent deterministic geography, scoring, resupply, and recalculation modules.

Database foundation

  • Supabase
  • PostgreSQL
  • PostGIS
  • SQL migrations
  • Row-level security

Local database schema and ownership policies exist; complete production data integration remains in development.

Planned offline & mapping integrations

  • Mapbox
  • SQLite
  • Drizzle ORM
  • PowerSync
  • Cloudflare R2
  • TanStack Query

Selected in the starting architecture; these are not yet installed/connected in the current mobile application.

Verification & operations

  • Jest
  • React Native Testing Library
  • xUnit
  • GitHub Actions
  • Docker

Implemented test and local infrastructure tooling. Sentry and PostHog are planned observability integrations.