DEV Community

Luiz Gonçalves ☕
Luiz Gonçalves ☕

Posted on

Building We Build Forest: A Side Project to Reforest the Planet - with some JS

Let me tell you a story about trees, side-projects, and why I thought it'd be a good idea to build an API that plants stuff.

🌱 Why I Built This (and What It Actually Is)

So... I’m one of those people who loves shipping things. And also, I love trees. Always did. There’s something grounding about forests. They’re quiet, slow, and do their job without drama. I can’t say the same about most of my tickets on Jira.

So I asked myself: how can I contribute to reforestation without quitting my job or becoming an Instagram eco guru? And then came the idea: We Build Forest (WBF) — a platform where companies (or people) can plant or adopt trees via API calls. That’s it. You call an endpoint, and somewhere in the world, a seed gets a chance.

It’s a side-project, built mostly in my free hours with help from some good folks — devs, PMs, environmental partners. Real people. Real impact. Not a greenwashing gimmick.

The win-win is real:

  • Companies get a conversion boost (“we plant a tree for every X” hits hard)
  • Users feel like they’re doing something meaningful, which they are!
  • I take care of the boring infra stuff and make a small margin

⚙️ Tech Stack

The stack is solid, if you ask me. I didn’t want this to be a toy project that dies with the first webhook.

  • NestJS for backend (GraphQL + WebSockets where needed)

  • MySQL with TypeORM — relational and boring (good)

  • Redis + Redlock — because yes, queues need locks

  • SQS + SNS — because things are async, always

  • Vite + Tailwind — WIP - frontend is SPA, fast and clean

  • Prometheus + Grafana

No AI here for now. Just trees and messages.


🏗️ Multi-tenancy

Every client has their own API key, rate limit, webhook setup, and visibility scope. That’s our basic multi-tenancy.

But here's where it gets spicy: the platform has region-aware endpoints:

  • api-us (for North America)

  • api-br (for Brazil)

  • api-jp (for Asia)

This isn’t just for latency — it’s also about compliance. Some countries want local logs, local data, or slower bureaucracy. So yeah, if a US client sends a request to api.web.whatever, it’ll still work... but might be slower, or even trigger warnings depending on the tenant's config.

In a perfect world, everyone hits the right region. In reality, we just try not to break anything.


🌲 Trees Aren’t Instant (and That’s Okay)

One thing I had to embrace early: tree planting takes time.

You’re not buying a t-shirt. You’re claiming that someone, somewhere, will plant a tree. Maybe in a few days, maybe in two weeks.

So here’s what I did:

  • Each tree is an entity in the DB

  • It can be partially claimed (10%, 20%, until it hits 100%)

  • Once full, it’s marked for planting and linked to a partner NGO, which had previously agreed on planting X trees, regardless of the supporters.

  • Webhooks fire to notify the client

  • We generate a nice little and legitimate PDF certificate and store it in S3

The whole system is modeled around asynchronous reality. Nothing blocks. No one waits for a shovel to hit dirt.


💸 PDF Certificates: The Unexpected Boss Fight

Certificates are a must here, as many people will use them for tax exemptions, proof of donation, etc. People love the certificates too; they want to share them on their socials. But man, they are expensive to generate and store.

Right now:

  • We create PDFs per adoption
  • Store them in S3, accessible via link

But long-term, I’ll migrate stale ones to Glacier. I already tag them by access date. It’s just a matter of tuning the lifecycle.

Side-projects teach you that every cost matters. Especially when you're not funded.


📊 Monitoring and Sanity

This thing runs 24/7. People hit the API. Stuff gets queued. Trees are claimed.

So yeah, I need eyes on it:

  • Prometheus tracks per-tenant metrics

  • Grafana shows cert generations, queue depth, webhook retries

I can tell when a partner in Brazil is slow. Or when someone is spamming test calls. Transparency is part of the promise.


🧪 Tests, Because I Like Sleep

Just because it’s a side-project doesn’t mean it can break. I’ve got tests on:

  • Credential validation

  • Queue processors

  • Webhook delivery

  • Redlock handling

Everything has cursor rules to force me to test before merge. Not because it’s trendy — because I don’t like waking up to alerts.


🚀 What’s Next?

Still early days. No public launch yet, just a landing page with some mock data... But some folks are already testing, and it’s working better than I expected.

The roadmap:

  • Public-facing dashboard

  • Partner onboarding flow

  • Shopify/Stripe plug-ins

  • Bulk operations for marketplaces

And maybe — just maybe — turn it into a SaaS with real traction.


🌍 Final Thoughts

I’m not trying to save the world. But if I can plant some trees while helping companies add value to their product? That’s a start.

If you’re a dev, founder, or PM and this sounds like something you’d use — let’s talk.

And if you just wanna see some code — GraphQL schema? Queue handler? PDF gen script? I got you too.

Let’s reforest the internet. One webhook at a time. 🌲

Top comments (0)