TrailScribe 🌿
Offline-first naturalist field assistant designed to get outdoor explorers off their screens and back in touch with nature.
Built for the Hacktoberfest 2026 "Touch Grass" and "Best Use of Gemma" challenge tracks.
Most modern nature and identification apps have a fundamental flaw: they demand constant cellular reception and keep you staring at a screen while walking through ancient forests. Even worse, uploading GPS coordinates of rare flora and fauna to centralized cloud services exposes vulnerable habitats to public disclosure and poaching.
TrailScribe reverses this dynamic through an eyes-up, offline-first philosophy:
- Touch Grass First: Pocket-first interaction model. Tap a tactile shutter or hold-to-talk to capture voice observations. Hardware haptics pulse when passing recorded habitats so you never have to watch a screen.
- Local Ecological Reasoning: Powered by Google Gemma 2 (2B) running locally via Ollama (with an in-browser WebGPU/heuristic fallback). It translates unstructured naturalist voice logs into international biodiversity standards (GBIF Darwin Core JSON-LD and GeoJSON) with zero cloud reliance.
🚀 Repository & Project Links
- GitHub Repository: github.com/OmkarD09/trailscribe
- Walkthrough & Demo Video: Watch Demo Video (Google Drive)
- Primary Tech Stack: Vite + React, Tailwind CSS (Stitch Archival Design System), Dexie.js (IndexedDB), Leaflet Offline Cartography, Google Gemma 2:2B.
🧠 Track 1: Best Use of Gemma
TrailScribe embeds Google Gemma 2:2B as an on-device ecological reasoning and taxonomy extraction engine. Naturalists in the field speak in natural, sensory descriptions rather than structured database rows:
"Found bright orange shelf fungus about two meters up a damp decaying birch nurse log on a north-facing mossy slope."
Gemma Naturalist Extraction Pipeline
TrailScribe routes raw audio transcripts through src/runner/gemma-runner.ts, querying local Ollama (http://localhost:11434/api/generate) with a structured taxonomy prompt:
// Excerpt from src/runner/gemma-runner.ts const systemPrompt = `You are an expert field naturalist. Parse the following field observation into structured JSON conforming to biodiversity standards: - speciesCandidates (Common name & scientific binomial nomenclature) - kingdomOrGroup (Plantae, Fungi, Animalia, Insecta, Aves, Geology) - microhabitat (e.g., damp slope, creek edge) - substrate (e.g., decaying birch nurse log, granite boulder) - lifeStage & abundanceCount Return ONLY valid JSON matching this schema.`; Structured Ecological Record (Darwin Core GBIF Standard)
Gemma 2:2B translates the observational note into:
- Vernacular Name: Orange Shelf Fungus / Turkey Tail
- Scientific Binomial: Trametes versicolor / Pycnoporus cinnabarinus
- Kingdom Classification:
Fungi - Substrate:
decaying birch nurse log - Microhabitat:
damp north-facing mossy slope
If Ollama is stopped or unavailable on remote backcountry ridges, TrailScribe’s ModelRunnerInterface automatically falls back to an offline heuristic parser, ensuring field capture never stalls.
🌱 Track 2: "Touch Grass" Architecture
TrailScribe is built specifically to get users outdoors while keeping devices tucked safely away.
1. Tactile & Screen-Free Logging
- One-Tap Acoustic Intake: High-contrast shutter trigger equipped with Web Audio API chime synthesis and vibration pulses. Explorers can initiate, record, and save observations purely by touch and sound.
- Warm Vellum High-Contrast HUD: Built on the Stitch Design System (
#f8f6f0archival vellum aesthetic,Newsreaderserif, and emerald/amber telemetry) for clear legibility in direct outdoor sunlight.
2. Proximity Geofencing (Haptic Trail Alerts)
Using on-device Haversine distance calculations over Dexie IndexedDB records, TrailScribe monitors your trail position in the background:
- Walking within 50 meters of a recorded specimen triggers hardware vibration patterns (
navigator.vibrate([80, 40, 80])):
"Entering habitat sector of Turkey Tail Fungus."
🛠️ System Architecture
┌─────────────────────────────────────────────────────────────┐ │ TrailScribe PWA │ ├──────────────────────────────┬──────────────────────────────┤ │ UI & Interactions │ Offline Engines │ │ - Stitch Archival Theme │ - Leaflet Topo Tiles (5x) │ │ - Web Audio Waveform │ - Dexie.js (IndexedDB) │ │ - Tactile Haptic Pulses │ - Vector Cosine Engine │ └──────────────┬───────────────┴──────────────┬───────────────┘ │ │ ▼ ▼ Local Voice & Camera Logs In-Memory 384-d Embeddings │ │ └──────────────┬───────────────┘ │ ▼ ┌───────────────────────────────────┐ │ ModelRunnerInterface │ │ ├── Gemma 2:2B (Ollama Local) │ │ └── Heuristic Naturalist Parser │ └─────────────────┬─────────────────┘ │ ▼ GBIF Darwin Core / GeoJSON / GPX Core Technical Highlights
- Offline Storage: Dexie.js manages observations, audio voice notes (WebM blobs), and photo assets locally in IndexedDB.
- In-Browser Semantic Vector Search: Pure TypeScript 384-dimensional
Float32Arraycosine similarity engine yields query responses in under 3 ms without network calls. - Zero-Key Offline Cartography: Leaflet map instance featuring five open topographic and satellite tile options (
World Topo,Ridge Topo,Field Terrain). - Standardized Exports: Immediate offline export to Darwin Core JSON-LD (GBIF global standard), GeoJSON (for QGIS, Gaia GPS, and CalTopo), and CSV.
🧪 Swarm Testing & Validation (MiroFish-Inspired Engine)
To validate system durability prior to submission, we implemented an in-repo TypeScript Swarm Intelligence simulator (tests/swarm/swarm-engine.ts) inspired by multi-agent behavioral frameworks like MiroFish.
We simulated 100 concurrent synthetic field naturalists across four distinct behavioral profiles:
- Alpine Botanists (25 agents): High elevation, rapid GPS variance, brief floral logs.
- Urban Foragers (25 agents): Intermittent network state changes, pocket park microhabitats.
- Fungal Pathfinders (25 agents): Rich decaying log descriptions, dense Darwin Core terms.
- Deep Backcountry Trekkers (25 agents): Multi-kilometer trail breadcrumbs, 100% offline audio captures.
Benchmark Outcomes
- Offline Resilience: 0 unhandled promise rejections across abrupt network transitions.
- Vector Query Latency: Averaged under 4 ms across 500+ generated observations.
- Production Bundle: Clean production build (
tsc && vite build) in 1.48 seconds with code-split vendor chunks.
💻 Quick Start & Local Setup
Prerequisites
- Node.js and npm
- Ollama (for local Gemma inference)
Installation
# 1. Clone the repository git clone https://github.com/OmkarD09/trailscribe.git cd trailscribe # 2. Install dependencies npm install # 3. Pull Gemma 2 through Ollama ollama pull gemma2:2b # 4. Start Ollama with web CORS enabled # Linux/macOS: OLLAMA_ORIGINS="*" ollama serve # Windows PowerShell (in a separate terminal): $env:OLLAMA_ORIGINS="*" ollama serve # 5. Start the development server npm run dev Open http://localhost:5173/ in your browser.
🌲 Conclusion
Building TrailScribe highlights how open-weight models like Google Gemma 2 enable privacy-first edge computing. By keeping ecological reasoning strictly on-device, naturalists can record the wilderness with scientific precision while ensuring sensitive habitat coordinates remain confidential.
Step outside, log your findings, and touch grass! 🌿