Inspiration
Uruguay has more cattle than people: roughly 11.7 million head, over three for every Uruguayan. Every one of them wears a SNIG ear tag, and every rancher has to file a sworn DICOSE declaration each year. Yet most ranchers still keep their herd in a notebook, a WhatsApp thread with the capataz, and a spreadsheet nobody trusts. We did too, on our own 200+ head operation near Punta del Este. I work cattle on my family's regenerative ranch, and GanadoUY is the tool we wanted and couldn't find: built around Uruguay's own systems (SNIG, INAC, DICOSE) and around how the work actually happens, which is standing at a chute with one free hand and no cell signal.
What it does
- Mi Hacienda: every animal is registered by SNIG ear tag. The whole herd imports from the official SNIG Excel/CSV export in seconds.
- Lotes & pesadas: group animals into lots, weigh them, and see average weight, daily weight gain (GDP) per session, and progress toward a target sale weight.
- Modo Campo: a one-handed weigh-in screen with a big numpad and voice entry. It works fully offline and syncs when you get signal back.
- Sanitario: treatment records with recurring reminders sent as push notifications.
- Mercado: official INAC weekly cattle prices refreshed automatically, a sale calculator, a feedlot margin calculator, and price alerts.
- Sorteos, Gastos, Nacimientos, Mortandad, Lluvias (manual or Tempest weather station), Potreros with a map.
- DICOSE / Declaración Jurada helper and an annual summary built from data you already entered.
- Shared campo: invite the capataz, vet or accountant with role-based permissions.
- Fully bilingual, Spanish (rioplatense) and English.
Monetization (RevenueCat)
The free plan includes every feature for up to 50 active animals, which is enough for a small producer to run their whole operation. GanadoUY Pro (USD 499/year) removes the herd limit. We deliberately don't paywall features: the rancher who outgrows 50 head is exactly the rancher for whom the app is worth the most.
- Android (v1.2) sells Pro through Google Play Billing via the RevenueCat Capacitor SDK (
@revenuecat/purchases-capacitor), with a 7-day free trial, restore purchases, and Play subscription management. - Web customers at ganadouy.com pay through Stripe (plus bank transfer for Uruguayan ranchers who prefer it).
- All channels write to one server-side entitlement ledger. The RevenueCat app user ID is the user's account ID, not the device, so Pro follows the rancher from phone to web to the accountant's laptop.
- The server never trusts the client or a raw webhook body. After a purchase, restore, or any RevenueCat webhook (renewal, cancellation, billing issue, refund, transfer), the server re-reads the subscriber from the RevenueCat REST API with a secret key and applies the result idempotently. A missing Play purchase can never downgrade a rancher who pays via Stripe or transfer.
How we built it
React + TypeScript + Vite, wrapped with Capacitor 8 for Android. tRPC + Express on the server, Drizzle ORM on MySQL, IndexedDB offline outbox for field work, web-push for reminders, scheduled jobs for INAC price ingestion and reminders. ~30 tables, 700+ automated tests. RevenueCat for native billing and entitlement lifecycle.
Challenges
- Shipping billing in the last 72 hours. Adding RevenueCat meant a new Play build, and every step fought back: Play rejected the first upload because its version code was already taken, Android Studio shipped Java 25 but our Gradle only runs on Java ≤24, and Google service-account credentials take hours to propagate.
- Offline at the chute. Weigh-ins had to survive zero connectivity and replay safely without duplicating animals. We built an idempotent offline outbox and tested it on a real device in the field.
- Anti-steering + one entitlement. A Play-distributed app can't point users to cheaper web checkout, but ranchers also pay by card and bank transfer on the web. Our solution: channel-aware paywalls (the native build physically excludes the web payment module) all resolving to a single server entitlement.
- Uruguay-specific data. Parsing SNIG exports and mapping records into the DICOSE declaration format meant reading a lot of government PDFs.
Accomplishments
Went from first build (Aug 16) to a production app on Google Play (Sept) in about six weeks, part-time, while working electrical construction. It runs our own 200+ head operation, and every milestone and setback was posted publicly each week on Substack. Then added server-verified Google Play subscriptions through RevenueCat in the final days of Shipaton.
What we learned
Build for the chute, not the office. Every screen that works one-handed and offline got used; every screen that needed signal didn't.
What's next
Breeding outcomes (tacto, parición, destete), an iOS release using the same RevenueCat entitlement, RevenueCat Web Billing for the website, and partnerships with consignatarios and rural accountants who manage dozens of DICOSE declarations each.
Built in public
Every week of this build is documented on my Substack:
- Week 159: From the Dirt to the Office, the first full build, already running our own herd
- Week 161: 3 Cycles, All at Once
- Week 162: Building and Creating
- Week 163: Pushing Forward, about 30 revisions and the Play Store submission
- Week 164: Hacker Cycle Completed, live on Google Play
Try it (judges)
Install from Google Play, sign in with Google, and open Perfil → Upgrade to Pro (or add a 51st animal). Pro includes a 7-day free trial through Google Play; cancel anytime in Google Play › Subscriptions. Switch Spanish/English with the ES/EN toggle in the menu.
Built With
- android
- capacitor
- drizzle
- express.js
- google-play
- mysql
- react
- revenuecat
- stripe
- tailwindcss
- trpc
- typescript
- vite
Log in or sign up for Devpost to join the conversation.