Inspiration

Indonesia ranks at the top of the World Giving Index almost every year. We are, by the numbers, one of the most generous nations on earth.

Then 2022 happened. The ACT scandal broke, a major Indonesian charity caught diverting donated funds, and something cracked. Not generosity. Trust.

That distinction became our whole project. People didn't stop wanting to give. They stopped believing their money arrives. And when we looked closer, we found the gap wasn't a people problem at all, it was a structural one. Conventional foundations accept unrestricted money and decide the allocation themselves. That freedom is the whole point of a foundation. It's also the exact hole ACT fell through.

So we asked a different question. Not "how do we make donors trust charities again?" but: what if there were no money to misuse in the first place?

Orphanages don't need "funds." They need rice this week and milk next month. If we ship the rice instead of wiring the money, the entire category of abuse we're afraid of simply has nowhere to live.

ACT had a cash box. Nyalur has a shelf of goods.

What it does

Nyalur is inverted e-commerce: one person checks out, someone else receives.

For orphanages. Register, upload legal documents (foundation deed, NIB, Ministry of Social Affairs decree), get verified. Then request needs from a curated catalogue, not "Rp 50 million," but 10 kg of rice, 5 L of cooking oil, 20 boxes of milk. Track what arrives, itemized, with every donor named.

For donors. Browse a registry of verified orphanages and their live needs. Pick a portion you can actually cover, even 1 kg. Buy it from Nyalur's own warehouse. No money ever touches an orphanage's bank account. Track your physical goods: Packing → Shipped → Received. Then receive handover proof: a unique code (NYL-7F3A-2210), the recipient's name and role, GPS coordinates, a timestamp.

Not a PDF report next month. Proof, the day it lands.

Three guardrails hold the system honest:

Guardrail What it does
Tiered verification Tier 1 registered → Tier 2 verified (NIB + Ministry decree) → Tier 3 site visit
Monthly ceiling $\text{ceiling} = \text{children} \times \text{Rp }500{,}000$. Request beyond it and the system refuses, visibly.
Rigid catalogue Orphanages can only request approved SKUs. Can't request cash. Can't request outside basic needs.

And the answer to the shipping question everyone asks first, "1 kg of rice costs Rp 15,000, how is shipping not Rp 20,000?", is batching. Goods leave in one wave every Friday. Ten donors on the same wave split one delivery: $\text{Rp }20{,}000 \div 10 = \text{Rp }2{,}000$ each. The more of us, the cheaper it gets.

How we built it

Three people. Thirty hours. One phone for the demo.

Stack: Expo 54 / React Native 0.81 / expo-router 6 / Supabase (Postgres). Plus Jakarta Sans for type, an Indonesian typeface, which felt right for an Indonesian product.

Architecture, and the rules we held ourselves to. With three people moving fast in one codebase, we decided the only thing that would save us was a small set of rules nobody was allowed to break:

  • Every Supabase call lives in lib/queries.ts. Screens never touch the database directly. One file to audit when something's wrong with the data.
  • No hardcoded hex anywhere in a component. Everything comes from constants/theme.ts.
  • No raw sentences in JSX. Every string goes through t(), which is what let us ship fully bilingual (Indonesian/English) without bolting on an i18n library at hour 25.
  • Green means delivered. Only delivered. Red means the guardrail rejecting something. Only that. Every other state is blue or grey.

That last one sounds like a design nit. It isn't. It means that when green appears on screen, it means something, and the moment the proof screen loads, the color itself is doing pitch work.

The seed data is generated, not written. scripts/gen-seed.mjs builds reset-seed.sql and asserts its own integrity before writing: every request's jumlah_terpenuhi must equal SUM(donasi), every received donation must have proof, every undelivered donation must not have proof. If any assertion fails, the generator exits non-zero and refuses to write. We called the failure mode "angka hantu", ghost numbers, progress bars with no donor behind them. A demo that lies quietly is worse than one that crashes loudly.

Two batches in the seed, deliberately. Batch 1 (July 10) has arrived. Batch 2 (July 17) is still moving. Without that second batch, every donation in the app would read "Received," the status filters would be three empty buckets, and the blue "in transit" timeline state would never render once in the entire demo.

Challenges we ran into

Two personas, one phone. No Supabase Auth, no RLS, a deliberate call we documented rather than hid. Real auth would have eaten hours and bought the demo nothing. Instead: two hardcoded accounts and an account switcher. The moment you switch from orphanage to donor and watch the request you just filed appear on the donor's home screen, that's the moment the closed loop lands. We built the whole session model around making that one switch feel instant.

Knowing what not to build. Real payment gateway, admin verification dashboard, live courier app, anomaly detection, all cut, all on the deck instead.

We audited our own work before submitting. Full sweep for dead code, ghost numbers, color-rule violations, POV leaks.

Accomplishments that we're proud of

The architecture answers the killer question, not the pitch deck. When a judge asks "how are you different from ACT?", we don't have a rebuttal slide. We have a schema. There is no collective fund in this system to divert, because there is no collective fund. There are only small transactions, each bound to a specific SKU for a specific recipient from the second it's created. The answer isn't rhetoric. It's the data model.

A seed generator that refuses to lie. It won't emit a SQL file whose numbers don't reconcile. Small thing. It's the reason we can point at any progress bar in the demo and name the donors behind it.

Fully bilingual, and it cost us no dependency. ~270 dictionary keys, correct English pluralization, locale-aware currency and dates (Rp 13.000 vs Rp 13,000, the separators invert, and getting that wrong is exactly the tell that says "we didn't really localize this").

It doesn't look like a charity box. It looks like a bank. White-dominant, blue used sparingly, generous empty space. Because that's the claim: this is trust infrastructure, not a donation drive.

What we learned

Structure beats promises. We could have built the same app with a "we pledge transparency" banner. Instead we removed the thing that needed pledging. Every hour we spent on the architecture bought more credibility than any hour we could have spent on copy.

Constraints are a design tool, not an obstacle. "Green only means delivered" felt arbitrary on day one. By the end it was doing real work, the proof screen lands harder because nothing else on the journey earned that color.

Write down why, next to the code. With 3 people and no time, the comment explaining why something is deliberately weird is what stops teammate #2 from "fixing" it at hour 22. Our mock courier and fake auth are both flagged in-code, in plain language, with deletion instructions. Nobody had to ask.

Honest placeholders beat convincing fakes. A placeholder doesn't lie, so it can't be caught lying. On the screen judges stare at longest, that's not a compromise, it's the safer bet.

What's next for NYALUR

Immediately after the hackathon, closing what we mocked:

  • Real auth + Row Level Security. Every table is currently public with a fake session. That's a demo decision with a documented expiry date, and it's the first thing to go.
  • The courier app. Right now handover is simulated so the donate → track → proof flow is walkable on stage. Phase 1 real: the courier photographs the actual handover, GPS and timestamp captured at the source.
  • Server-side guardrail enforcement. The monthly ceiling should be a database constraint, not client logic. A safety rule that only exists in the app isn't a safety rule.

The product roadmap:

  • Phase 2, Langganan Kebaikan (Subscription of Kindness). Donors subscribe to send 5 kg of rice to the same orphanage every month. Solves donor retention and gives orphanages predictable supply, which is the real fix for the feast-or- famine problem (50 sacks one month, empty for three).
  • Phase 3, Merchant marketplace. Local suppliers and small businesses fill the catalogue; we become the platform. Escrow becomes relevant here, because only here does a third party exist. This is also where Nyalur touches agriculture, bridging rural producers to urban donors.
  • Phase 4, Disaster mode. The same rails for emergency logistics. Evacuation shelters post needs in real time; the public fulfills them item by item. Same registry, same proof, different urgency.
  • Phase 5, Beyond orphanages. Elderly homes, low-income families, remote schools, patient shelters.

The catalogue itself is curated around nutrition, protein packs, children's milk, fresh vegetables, which means every phase of this touches Health too.

One set of rails. Goods, not cash. Proof, every time.

Built With

Share this project:

Updates