The same bottle needs a different bin a few miles away. Sortline tells you exactly which bin — for your city, your municipality's rules — powered by on-device AI.
Sortline is a hyper-local, privacy-first waste & recycling advisor that runs as a single index.html file. Snap a photo of any item (or scan its barcode) and Sortline identifies it with on-device machine learning, then routes it to the correct bin, container, or drop-off point for your exact city — with the real local rulebook behind every answer.
The problem: Recycling rules are set by municipalities, not physics. In Dublin, bottle caps stay on. In Berlin, plastic film goes in the yellow bin. In NYC, film goes in the trash. The same object can be handled four different ways in four different cities — and most people just… guess.
The Sortline answer:
| Conventional apps | Sortline |
|---|---|
| Give generic, "national" recycling advice | Tells you the exact local container name (e.g. Gelbe Tonne, Bolsa verde, Sampah anorganik) |
| Send your photos to a cloud server | Runs 100% on-device AI — your photo never leaves your phone |
| Cover one country | Ships with 79 hand-curated city rulesets in 44 countries |
| Guessing game | Combines AI vision + barcode lookups + local rulebooks + community reports |
| Just an answer | Also gamifies good habits: points, streaks, badges & real environmental impact |
- Photograph an item with the camera or upload an image from your gallery.
- TensorFlow.js + MobileNet classify the item entirely on your device — no server, no upload, no account needed.
- Top-5 predictions are aggregated and mapped onto 9 waste categories, then routed to the correct local bin.
- Wrong guess? Tap an alternative prediction or pick the correct category manually — corrections are cached and improve future results for everyone.
- Batch mode: scan several items in a row and get a grouped summary at the end.
- Scan the barcode of any packaged product with the camera, or type the number in manually.
- Fetches real packaging/material data from the Open Food Facts database to determine the most accurate category.
- Every city ships with a full, municipality-grade ruleset: the exact bin name, plus a practical note ("leave the cap on", "flatten and keep dry", "never in any household bin").
- Rules are searchable and fully readable as a "local ruleset" reference.
- Special rules are surfaced too — e.g. Berlin's Pfand deposit bottles go back to the retailer, not in any bin.
- One tap and Sortline reverse-geocodes your coordinates (BigDataCloud + OpenStreetMap Nominatim) and auto-selects your municipality.
- No GPS access? Pick from the dropdown or type a city name with live suggestions.
- Curated pointers to the right place for anything that should not go in a household bin — e-waste, batteries, glass, textiles, hazardous waste — with a direct Google Maps link.
- Earn points for every scan (10 pts) and for confirming/correcting the AI (5 pts).
- Keep a daily streak, unlock badges (First Scan, Century Club, 7-Day Streak, Barcode Pro, Serial Sorter).
- Watch your environmental impact grow in real time: kg of waste correctly sorted and kg of CO₂ avoided.
- Set collection-day reminders per bin type; Sortline notifies you the night before your bin goes out.
- Flag an overflowing bin, a broken drop-off, or a tip for neighbours.
- Reports appear in a live community feed, scoped per the app's storage backend (shared when hosted, device-local when run as a file).
- A bold, neo-utilitarian UI with Space Grotesk, IBM Plex Sans and IBM Plex Mono.
- Light & dark themes, color-coded waste categories, toast notifications, offline banner and a fully responsive, mobile-first layout.
| Layer | Technology | Why |
|---|---|---|
| Language | Vanilla HTML / CSS / JavaScript (ES5-compatible, no framework, no build step) | Zero dependencies, instantly runnable, trivially portable |
| Vision AI | TensorFlow.js 4.x + MobileNet 2.1.1 | Real object classification 100% on-device — photos never leave the device |
| Barcode scanning | html5-qrcode 2.3.8 | Camera-based scanning of EAN/UPC codes straight from the browser |
| Product data | Open Food Facts public API | Real ingredient/packaging data behind every barcode |
| Geo-detection | BigDataCloud reverse-geocode + OpenStreetMap Nominatim | Coordinates → city/municipality, with an accuracy readout |
| Mapping | Google Maps deep-link search | One tap from any drop-off point to turn-by-turn directions |
| Icons & fonts | Font Awesome 6.4 · Space Grotesk · IBM Plex Sans/Mono | Bold, utilitarian visual identity with first-class readability |
| Persistence | StorageBackend abstraction (native window.storage → localStorage → in-memory) |
Works everywhere, upgrades to a shared backend if one is provided later |
Sortline is a single static file with no dependencies to install and no build step.
Double-click index.html. Done.
(The camera and geolocation features work best over HTTP(S)/localhost because browsers require a "secure context" to access them.)
Python:
cd waste
python -m http.server 8080
# → http://localhost:8080Node.js:
cd waste
npx serve .VS Code: install the Live Server extension → right-click index.html → Open with Live Server
Upload index.html to any static host — GitHub Pages, Netlify, Vercel, Cloudflare Pages — and it just works. A hosted deployment also unlocks the option of pointing the app at a real shared backend (see StorageBackend) for cross-device community reports and sync.
- A modern browser (Chrome, Edge, Firefox, Safari). No installs. No account.
- Internet on first use: the AI model, barcode API, geolocation APIs and CDN libraries are loaded on demand and cached afterwards.
- Offline mode: once the model is cached, photo scanning keeps working offline, with a transparent "colour-based guess" fallback if the model can't load.
- Set your city — tap Detect my location (one-tap reverse geocode), pick from the dropdown, or start typing a city name.
- Scan (or barcode) — hit Snap-and-sort, photograph/upload an item or scan its barcode. Sortline shows the item's predicted category, the exact local bin/container, and a practical tip.
- Correct it if needed — not 100% sure? Tap another top-5 guess or pick the category manually; that correction is remembered.
- Check the ruleset — open Local ruleset to read your city's full reference, or Locate for drop-off points that shouldn't go in any bin.
- Build your streak — every action earns points, feeds your history chart, and grows your kg diverted / kg CO₂ avoided impact readout.
- Set reminders & report — get notified the night before bin day, and flag community issues your neighbours can see.
| Mechanic | Details |
|---|---|
| Points | +10 per scan · +5 per confirmation / manual correction |
| Daily streak | Resets if you miss a day; a 7-day streak unlocks a badge |
| Badges | first_scan · century · streak7 · barcode_pro · sorter50 |
| History | Last 30 scans, with timestamps, per-category breakdown chart |
| Impact | Estimated kg of waste correctly routed + kg of CO₂ avoided, computed from per-category weight factors |
Good habits, honestly counted: the app itself notes that rewards are "small nudges" — nothing here changes what actually goes in your bin, but the streak effect is real.
- Your photos never leave your device. Image classification runs entirely on-device with TensorFlow.js — there is no photo upload, no server, no analytics pixel.
- Local-first storage. Everything (points, history, reminders, reports, theme, corrections) is persisted through the
StorageBackendabstraction, which prefers a native shared backend when the app is hosted, and otherwise falls back tolocalStorageon your device. - No account required. The account/profile system is a lightweight local demo (register, avatar, bio, preferences) stored on-device — no email verification, no server.
- Full data portability. Use Rewards → Export data (.json) to back up everything, and Import to restore it on any device. Clearing the browser wipes the app clean via Reset.
The entire application lives in index.html (~2,800 lines, ~200 KB) and is organized into clearly-labeled sections:
index.html
├── <style> Design system: color tokens, dark/light themes, layout, animations
├── <body> Header (brand + score chip) · nav tabs · 6 panels
│ ├── panel-scan (camera / upload / batch mode / result)
│ ├── panel-barcode (scanner + manual lookup)
│ ├── panel-rules (searchable local ruleset)
│ ├── panel-locate (drop-off points + maps links)
│ ├── panel-rewards (points, badges, impact, history, export/import)
│ └── panel-report (community issue feed)
├── Storage backend StorageBackend: native window.storage → localStorage → memory
├── Category data 9 CATEGORY_META entries with color-coded identity
├── City database 79 CITY_RULES entries: per-category bin + note, drop-off points
├── Label rules 2,000+ regex fragments mapping AI labels → categories
├── Geo detection Coordinates → BigDataCloud → Nominatim → city match
├── Vision pipeline MobileNet → top-5 → aggregate → category → correction cache
├── Barcode pipeline html5-qrcode → Open Food Facts → packaging regex → category
├── Reminders bin-type + weekday, browser Notification, day-before trigger
├── Reports shared-scope storage → community feed
└── Game engine points / streak / badges / impact weights / history / chart
Interesting internals worth knowing:
- Correction learning —
saveCorrection()persists mapping overrides keyed by a normalized label, so repeated corrections "teach" the app once per device. - Adaptive storage —
StorageBackenddetects a nativewindow.storageAPI (a hosted backend), else localStorage, else a throwaway in-memory store — withshared:vslocal:namespaces deciding whether data is community-wide (reports) or private (profile, game). - Graceful degradation — if TensorFlow fails to load, Sortline falls back to a colour-dominant heuristic (green → organic, tan → paper/cardboard, light/low-saturation → metal, etc.) with a clear "basic offline mode, not true object recognition" disclaimer. If the QR library fails, manual barcode entry still works.
- Anti-frustration defaults — an 8-second timeout and
AbortControlleron API calls, an online/offline banner, and toasts for every state change.
- More cities — rules are added one by one, municipality-grade (contributions very welcome!)
- Cloud sync & real accounts via a hosted backend (
StorageBackendis already backend-ready) - Multi-language UI for the existing non-English cities (ES, PT, DE, AR, ID…)
- Curbside-schedule API integrations (look up your street's collection day)
- PWA packaging: offline-first install, home-screen launch, service worker for the model cache
- Expand barcode coverage beyond Open Food Facts (more product categories & regions)
Sortline is a single-file project, which makes contributing wonderfully simple:
- Fork the repo.
- Add or refine a city: edit the
CITY_RULESentry — real bin names, a practical note, and trusted drop-off points. - Extend
LABEL_RULESwith new item keywords to improve AI → category mapping. - Open a pull request. Please back up changes with sources (municipal guide links) so rules stay honest.
This project is licenced under Apache-2.0 license — all rights are reserved - If you'd like to use, adapt, or extend Sortline, get in touch first.
Dhurgham Alsaadi
- Project: Sortline https://sortline.vercel.app/
- Built with curiosity, clean design, one
index.html, and a genuine hope that better bins make better neighbours.
"Recycling rules are set by your municipality, not physics." — Sortline, by Dhurgham Alsaadi