Stand in a spot, and find native plants that will actually thrive right there — ranked by what they do for the local ecosystem, with honest mature-size-over-time drawings.
An indigene is a native of a place. This app measures the sun where you're standing, pulls the soil and climate for your exact coordinates, and returns the plants that belong there — with plain language the whole way, because it's for people who've never heard "part shade" or "keystone species."
A mobile-first, offline-first Progressive Web App. No account, no App Store. Built on the DOM and real web APIs — no framework.
See PROJECT_BRIEF.md for the vision and decisions, and
DATA_SOURCES.md for the data-licensing audit — starting
with How a source gets in, the tests a
dataset has to pass before anything here depends on it.
Layout
| Path | What it is |
|---|---|
app/ |
The PWA — vanilla TypeScript on the DOM, no framework, zero runtime deps, ~713 KB gzipped plus the one region you garden in (19–58 KB). This is the product. Offline-first, installable. |
server/ |
A thin Hanami 2 JSON API. Its job: fetch site data (soil/elevation/climate) server-side to dodge browser CORS and keep future API keys off the client. The PWA works without it. |
Quick start
# The app
cd app && npm install && npm run dev # http://localhost:5173
# The API (optional)
cd server && bundle install && bundle exec puma -p 2300 config.ru
Camera + compass features need HTTPS and a real phone; everything else — the
whole flow via the manual sun picker — works on desktop over plain localhost.
Deployment
The PWA deploys to GitHub Pages — free, HTTPS, no server to run — via
.github/workflows/deploy.yml on every push to
main. The app talks to its data sources (SoilGrids, USGS, Open-Meteo)
directly from the browser, so Pages hosts the entire product; the optional
server/ API is not required and not deployed.
One-time setup: in the repo's Settings → Pages, set the source to GitHub Actions.
When that path is unavailable — a deploy job that never gets a runner, an
Actions outage, a Pages incident — the site can be published from a laptop
instead, with npm run publish:cloudflare or npm run publish:gh-pages.
docs/publishing.md explains which failure each one
survives, the one thing any host has to do (serve 404.html for unknown
paths, or every deep link breaks), and how to fail the domain over.
The deploy also publishes a plain-words What's new page at
/release-notes/, compiled from CHANGELOG.md and the entries
still loose in changelog.d/ — so release notes update
themselves whenever a merged PR carried one. The changelog's header explains the
format; CLAUDE.md explains the workflow.
What it does
- Location — high-accuracy geolocation with a draggable pin.
- Sun — a plain three-way picker (leads), with an optional camera sky-scan
(
getUserMedia+DeviceOrientation, never WebXR) that measures the skyline and computes real sun-hours locally. - Confirm — soil/climate/zone in plain words, framed as "the map says…", with a 60-second ribbon test to correct it.
- Results — plants ranked by a transparent eco-score × site-fit, each with a to-scale size drawing beside a human silhouette, a broken-out score, honesty flags, and confidence. Re-weightable sliders + guerrilla-mode filters. Saved to IndexedDB, local-first.
Plant recommendations are tuned region by region, and the app picks the right list from where you're standing — refined, when online, by the spot's real ecoregion (US EPA Omernik in the States, EEA biogeographical regions in Europe). Eight regions ship today, across two continents — including the whole of metropolitan France:
- Mid-Atlantic / Northeast Piedmont (40 species, Pennsylvania reference)
- Pacific Northwest, west of the Cascades (44 species, Portland–Seattle reference)
- Florida, north & central (23 species, central-Florida reference)
- Florida, south & the Keys (21 species, greater-Miami reference)
- Atlantic France (23 species, Paris–Nantes–Bordeaux reference)
- Continental France (22 species, Dijon–Strasbourg–Lyon reference)
- Mediterranean France (21 species, Provence, Languedoc & Corsica)
- The French Alps (21 species, montane & subalpine, Grenoble–Briançon)
The four French regions are the app's European foothold; their wording is still English for now. Their Lepidoptera host counts are computed from the openly licensed Gaytán 2026 European interaction matrix rather than estimated.
Outside a covered region the sun/soil/climate readings still work; the app says
plainly when it has no plant list for your spot yet. Adding a region is a data
file plus one line in app/src/data/regions.ts — see DATA_SOURCES.md for the
taxonomy and distribution backbones we'll build the national and global catalog
on, and docs/ecoregion-plan.md for how region selection uses EPA ecoregions.
License
MIT. All the data underneath is public; this is too.
Indigene began as a pivot from the Planter repository and is now its own project.
