This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
TrailKit is an app for hikers who want to explore trails without worrying about losing network coverage. It tracks your trek, identifies plants and animals, and keeps your route and photos on your phone.
Here's what it can do:
- Record your trek. GPS tracks your route, even with the screen off. Distance, duration, elevation gain and pace update as you walk.
- Identify what you find. Take a photo of a plant, insect or snake, and TrailKit identifies it using AI running on your phone. It also provides safety information and short field notes. Dangerous species get additional precautions, first-aid guidance where relevant, and a button to call your emergency number.
- Save interesting views. Take a photo of a valley or viewpoint and mark it on your route.
- Plan your hike. Choose a route, set a date and prepare a checklist. Before starting, the app walks you through a full-screen checklist and countdown. If you stray more than 60 metres from your planned route, your phone vibrates.
- Share your trek. Treks are private by default. If you choose to share one, other hikers can see the route, statistics and identified species. Your photos stay on your phone.
The idea is to spend less time looking at your phone. Start the trek, put it away, and take it out when you need it.
Demo
Code
Hacktoberfest 2026
Projects for the DEV Hacktoberfest 2026 challenges, one folder per week.
The app lives in WEEK 1/. The README explains how to run it, download the models and configure Supabase. I've also kept a REVIEW.md with the decisions, bugs and performance measurements from development.
How I Built It
TrailKit is built with Expo, React Native and TypeScript for Android and iOS. The main challenge was getting AI identification to work locally while making sure it couldn't generate misleading safety advice.
Two models, one rule
TrailKit uses two models, both running on the phone:
- BioCLIP is a model trained on biological data. It compares a photo against a list of known species and ranks the closest matches using ONNX Runtime.
-
Gemma 4 E2B is a 4-bit model of around 2.6 GB. It runs through
llama.rnand generates a short explanation based on BioCLIP's top match.
The important distinction is that Gemma explains the identification; it does not decide how dangerous something is. Danger levels come from the species data, with additional checks before anything appears on screen.
- If the top match has less than 60% confidence, TrailKit says it isn't sure and shows the three leading candidates.
- If a plausible match is dangerous, the result is treated as dangerous.
- The app never tells users that a wild plant is safe to eat. If Gemma generates such a claim, its text is discarded.
- Snake and spider results always include the relevant distance precautions and first-aid information, even if Gemma fails.
My first attempt was to give the photo directly to Gemma, since it's a multimodal model. That took 284 seconds on CPU, and it confidently identified the wrong plant.
I switched to splitting the task between the two models. BioCLIP handles recognition, while Gemma writes the explanation. A warm identification took around 2 seconds on the Android emulator. On the iPhone simulator, the first identification took 24 seconds, including loading Gemma.
That separation made the system considerably more practical, though identification still needs to be treated as a best guess rather than a guarantee.
The trail, offline
The rest of the app is designed to keep working without a network connection.
- GPS tracking: On Android, tracking uses a foreground service; on iOS, it uses background location updates with the system indicator. Location points are appended to a file as they arrive, so a crash doesn't erase the entire trek.
- GPS cleanup: Distance calculations ignore implausible jumps. One stale GPS fix once added 785 metres to a walk I hadn't taken. Elevation gain ignores fluctuations under 3 metres to reduce noise.
- Off-route alerts: The app requires two consecutive fixes more than 60 metres from the planned route before alerting. It only clears the alert once you're within 35 metres, avoiding constant notifications around the boundary.
- Offline maps: TrailKit uses MapLibre with free tiles from OpenFreeMap, based on OpenStreetMap data. You can download the map around a planned route before leaving.
The goal is to prepare everything beforehand so losing reception doesn't interrupt the hike.
Community, without giving up privacy
The optional community features use Supabase for authentication, Postgres storage and profile photos. There's no custom backend server.
A shared trek contains the route, statistics and identified species, but not the photos taken along the way. Row-level security policies restrict accounts to their own data, and a test script checks that unauthenticated writes are rejected and other users cannot delete your posts.
Deleting an account also removes its local data and takes down its posts.
Credits
- BioCLIP by the Imageomics Institute: species recognition.
- Gemma 4 by Google, with QAT GGUF builds from Unsloth: field notes.
- llama.rn and ONNX Runtime: on-device inference.
- MapLibre, OpenFreeMap and OpenStreetMap contributors: maps.
- Supabase: authentication and community features. Expo and React Native: app development.
- First-aid guidance follows the R.I.G.H.T. snakebite protocol. Icons are from Feather, and the app icon is the "route" icon from SVG Repo.
- Test photo: Calotropis gigantea by Peterwchen, CC BY-SA 4.0.
Why Does Open Innovation Matter?
For this project, open models made it possible to run identification and text generation directly on a phone.
- It works without a signal. Trails often have poor coverage. Since both models run locally, identification doesn't depend on reaching a cloud API.
- Photos and location history stay private. The app processes photos on the device and stores GPS tracks locally. Sharing a trek doesn't upload its photos.
- I could choose the right model for each task. BioCLIP is designed for biological identification, while Gemma handles explanations. Having access to both models let me run them on a phone and give each a specific role.
- There are no per-identification costs. Once the models are downloaded, users can identify as many things as they want without paying for API calls.
- The trade-offs are different. A cloud vision model might recognise more species accurately, but it needs connectivity, incurs usage costs and sends photos to an external service. TrailKit prioritises offline availability and privacy, even if that means accepting the limitations of smaller on-device models.
Open models weren't just a cheaper alternative here. They let me build something that can still be useful when the network disappears.
My Agent Session
I used Claude Code to plan TrailKit and break the work into tasks. Antigravity handled most of the implementation using those task files, while Claude Code reviewed the changes against the actual code, emulator behaviour and logs.
That review caught several issues, including incorrect benchmark numbers, a timing budget that was off by a factor of seven, and unsafe generated outputs.
I recorded the development decisions, bugs and performance measurements in REVIEW.md.
Prize Categories
-
Best Use of Gemma: Gemma 4 E2B runs entirely on the device through
llama.rn, generating field notes from BioCLIP's identification. Its role is deliberately limited: it explains the result but never determines danger, and its output passes through safety checks before being displayed.
TrailKit is intended to help hikers learn about their surroundings, not replace professional medical advice or reliable species identification. Never eat a wild plant based on an app's identification. In an emergency, contact your local emergency services.
Top comments (1)
tr.ee/dev-to