
EcoRecover AI: Helping People Decide What to Do With Old Electronics, Built on AWS
How I built a web app that identifies old phones, chargers and batteries from a photo, gives safe disposal guidance, and helps collectors prioritise pickups, using Amazon Rekognition, ECS, ECR and S3.
The problem: a drawer full of dead electronics
Almost everyone has one. An old phone, a tangle of chargers, a battery that's started to swell. It stays in the drawer because nobody tells you what to do with it. Should you repair it? Donate it? Who will take a battery safely?
When people give up, these items end up in the household bin or with informal handlers, and the hazardous parts (especially lithium batteries) are the real risk.
For the AWS Builder hackathon's Waste & Energy track, I chose one small problem and tried to solve it well:
A person holding an old gadget should know the safest next step in under a minute.
What I built
EcoRecover AI is a web app with three parts.
1. Identify. You upload a photo and a model suggests the item type: phone, laptop, charger, cable, circuit board or battery. You always confirm the category yourself. If the model isn't confident, the app says so and asks you to choose.
2. Advise. Simple, tested rules put reuse and repair first. Batteries are always treated as hazardous: no dismantling, no household bin, specialist collection only.
3. Collect. You request a pickup or drop-off by city and locality, get a request ID, and track the status from Submitted to Completed. Collection partners see a queue ranked by a transparent score, with the reasons shown. Hazardous items go into a separate specialist queue instead of being mixed with routine pickups.
How AWS fits
Need | AWS service |
|---|---|
Identify the item from a photo | Amazon Rekognition ( DetectLabels ) |
Store uploaded photos | Amazon S3 (private bucket) |
Package the app | Docker image in Amazon ECR |
Run the app | Amazon ECS Express Mode on AWS Fargate |
Permissions | IAM task role limited to two actions |
Identifying items with Rekognition
I didn't train a model. Rekognition returns generic labels such as "Mobile Phone" or "Electronics", and my backend maps them to my categories. The part I care about most is what happens when the model isn't sure:
JavaScript
export const MIN_CONFIDENCE = 70;// If no label maps to a category with >= 70% confidence,// return "other" and mark the result as uncertain.if (!best || best.confidence < MIN_CONFIDENCE)return { category: 'other', uncertain: true, ... };
If Rekognition is unavailable, the app falls back to manual category selection instead of showing a made-up answer. A human confirmation step before any request is created matters more to me than a few points of accuracy. [Add what you saw: which labels Rekognition returned for your own photos, and where it was right or wrong.]
Least-privilege IAM
The running container gets a task role with only two permissions:
rekognition:DetectLabels , and s3:PutObject on a single uploads/ prefix of one bucket. It can't read other buckets or touch anything else.A deployment detour
I first planned to host on AWS App Runner. I then found that App Runner has been closed to new customers since April 30, 2026, and AWS recommends Amazon ECS Express Mode for new projects. Because my app was already containerised, switching meant pushing the image to ECR and creating an Express Mode service. It needed an image and a couple of IAM roles. [Describe your actual experience: how long it took, what confused you, any errors such as the health check path.]
Making the priority score honest
Partners need to know which request to handle first. I used a deterministic formula instead of calling it "AI":
Plain text
score = min(days waiting x 2, 60)+ min(quantity x 1.5, 10)+ 20 if hazardous
Every ranked request shows the reasons behind its score, and the weights are configurable. It is not a validated prediction model, and I say so in the app. I skipped proximity scoring because the app only collects free-text localities, not reliable coordinates.
Being honest about limits
- The seed data and collection partners are demo entries, labelled as sample data. None are certified recyclers.
- Environmental figures are estimates from stated assumptions (average weight per item type), not verified recycling.
- The database is SQLite inside the container, so data resets on redeploy. A managed database would be the production choice.
- [Add anything you didn't finish.]
Testing
The backend has automated tests for registration and login, role-based access, upload validation, the request lifecycle and status transitions, cross-user access blocking, analytics, and the priority rules. In my build environment all 10 tests passed.
What I learned
- Design for uncertainty. Pretrained models return generic labels, so the interface must admit when it isn't sure.
- Keep a human in the loop wherever safety is involved, like batteries.
- Check service availability early. Cloud services change, and a quick look at current documentation saved me from deploying on a closed service.
- [Add one lesson that is truly yours.]
What's next
Verified collection partners, location-based routing with real coordinates, a managed database, and testing with real households in my city.
Code: [your GitHub link]
Demo video: [your video link]
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article