A modern foraging webapp built with React 19, TanStack Router, and Vite that helps users discover wild mushrooms, edible plants, and berries in their area. Features an interactive Mapbox map with real-time foraging data, comprehensive species database, and curated wild food recipes.
- Real-time Mapbox integration with custom GeoJSON overlays
- Dynamic species filtering by category (mushrooms, plants, berries, nuts, flowers)
- Geolocation support with user location detection and navigation
- Responsive design optimized for both desktop and mobile devices
- Dark/light theme support with system preference detection
- Comprehensive catalog of 30+ wild edibles including:
- Mushrooms (Chanterelles, Morels, Porcini, etc.)
- Edible plants (Nettles, Dandelions, Wild Garlic, etc.)
- Berries (Blackberries, Elderberries, Wild Strawberries, etc.)
- Nuts (Hazelnuts, Walnuts, Chestnuts)
- Scientific names and detailed descriptions
- Seasonal information and habitat details
- Safety notes and identification tips
- Multi-language support (English, German, Spanish, French, Italian, Portuguese)
- Curated recipe collection featuring wild ingredients
- Difficulty levels (Easy, Medium, Hard) with prep/cook times
- Safety warnings and preparation tips
- Filterable by ingredient type and dietary preferences
- Step-by-step instructions with cooking tips
- Beautiful recipe images and nutritional information
- Full offline support with service worker caching
- Installable on mobile and desktop devices
- Splash screens for native app-like experience
- Offline map functionality with cached data
- Push notifications support (configurable)
- 6 language support with automatic detection
- Localized content for species, recipes, and UI
- RTL language support ready
- Cultural adaptations for regional foraging practices
- Frontend: React 19 with TypeScript
- Routing: TanStack Router with file-based routing
- State Management: Zustand stores
- Styling: Tailwind CSS 4 + SCSS
- Maps: Mapbox GL JS
- Build Tool: Vite 6
- Testing: Vitest + Testing Library
- PWA: Vite PWA plugin
src/
βββ assets/ # Static assets
βββ components/ # Reusable UI components
β βββ ui/ # shadcn/ui components
β βββ Mobile/ # Mobile-specific components
β βββ Sidebar/ # Navigation components
βββ contexts/ # React context providers
βββ data/ # Static data (species, recipes)
βββ hooks/ # Custom React hooks
βββ i18n/ # Internationalization
βββ lib/ # Utilities and API layer
βββ pages/ # Page components
βββ routes/ # TanStack Router file-based routes
βββ store/ # Zustand state stores
βββ stories/ # Storybook stories
βββ styles/ # Global styles and design tokens
βββ test/ # Test files
βββ types/ # TypeScript type definitions- AdvancedMap: Interactive Mapbox map with foraging data
- SpeciesSelector: Filter and browse wild edibles
- RecipeModal: Detailed recipe viewer with instructions
- RouteToDishPanel: Route-to-dish feature panel
- AppSidebar: Navigation and species filtering
- Node.js 18+
- npm, yarn, or bun
- Clone the repository
git clone https://github.com/lodist/funges.git
cd funges- Install dependencies
npm install- Environment setup
cp .env.secret.example .env.secretFill in your credentials in .env.secret. Public config (R2 data URLs) is already committed in .env.
- Start development server
npm run devThe app will be available at http://localhost:3000
npm run dev- Start Vite dev servernpm run dev:mobile- Start with mobile-optimized settingsnpm run build- Build production bundlenpm run preview- Preview production buildnpm run lint- Run ESLintnpm run lint:fix- Fix ESLint issuesnpm run format- Run Prettiernpm run type-check- TypeScript type checkingnpm run test- Run Vitest testsnpm run test:ui- Interactive test UInpm run test:coverage- Test coverage reportnpm run storybook- Start Storybook
- ESLint with TypeScript and React rules
- Prettier for code formatting
- TypeScript strict mode enabled
- Add to home screen on mobile devices
- Desktop app installation on supported browsers
- Automatic updates with background sync
- Native app-like user experience
- English (en) - Default
- German (de) - Deutsch
- Spanish (es) - EspaΓ±ol
- French (fr) - FranΓ§ais
- Italian (it) - Italiano
- Portuguese (pt) - PortuguΓͺs
- Automatic language detection based on browser settings
- Persistent language preference stored locally
Python scripts that generate foraging scores and map tiles, running on a schedule and writing to Cloudflare R2.
backend/
βββ EU/
β βββ North_Europe/ NE_Scoring.py, NE_MapLayer.py
β βββ South_Europe/ SE_Scoring.py, SE_MapLayer.py
βββ US/
β βββ USE/ USE_Scoring.py, USE_MapLayer.py
β βββ USW/ USW_Scoring.py, USW_MapLayer.py
βββ tools/
β βββ build_season_curves.py
βββ requirements.txt
- Scoring β fetch weather from R2, compute species scores, write Parquet back to R2
- MapLayer β scores + GeoJSON β Delaunay triangulation β MBTiles via tippecanoe β Mapbox
build_season_curves.pyβ queries GBIF for monthly fungi sightings per region, builds a target-group ratio curve (cancels observer-effort bias), uploads to<REGION>_SEASON_CURVESin R2. Run once before the first scoring run, then monthly.
pip install -r backend/requirements.txt
cp .env.secret.example .env.secret # fill in R2, Mapbox, WeatherAPI credentials
python backend/tools/build_season_curves.py # publish season curves to R2
python backend/EU/North_Europe/NE_Scoring.py # then run scoring
python backend/EU/North_Europe/NE_MapLayer.py| Variable | Where | Description |
|---|---|---|
VITE_MAPBOX_ACCESS_TOKEN |
.env.secret |
Mapbox API access token (required) |
VITE_MAPBOX_STYLE |
.env.secret |
Mapbox style URL |
VITE_VISITOR_LIMIT |
.env.secret |
Mapbox usage limit |
MAPBOX_USERNAME |
.env.secret |
Mapbox account username |
R2_ACCESS_KEY_ID |
.env.secret |
Cloudflare R2 credentials |
R2_SECRET_ACCESS_KEY |
.env.secret |
Cloudflare R2 credentials |
R2_BUCKET_NAME |
.env.secret |
Cloudflare R2 bucket name |
R2_ENDPOINT_URL |
.env.secret |
Cloudflare R2 endpoint |
WEATHERAPI_KEY |
.env.secret |
WeatherAPI.com key |
| R2 data URLs (NE/SE/USE/USW) | .env |
Public CDN URLs β already set |
npm run build- HTTPS required for service worker functionality
- Manifest generation automatic
- Icon generation for all device sizes
- Splash screen creation for native feel
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
- TypeScript for type safety
- ESLint for code quality
- Prettier for formatting
- Conventional commits for commit messages
MIT License - see LICENSE file for details.
Always consult with local experts before consuming wild edibles. This app provides educational information but should not be the sole source for identification. Many wild mushrooms and plants have poisonous look-alikes. When in doubt, leave it out.
Happy foraging! ππΏπ«