Touch Grass
A national park where your feeds used to be

Why it exists
Blockers fail two ways: they're trivial to bypass (typing facebook.com is muscle memory, disabling an extension takes four seconds), or they're so grim they feel like punishment and get uninstalled. And browser-only blocking does nothing about the phone, where the actual doomscrolling happens.
What I built
Made getting blocked the best part. Every closed trail shows a vintage park poster, a rotating trail-cam GIF, and a dry ranger notice instead of a feed. Passes are earned: win a typing gauntlet, a memory match, and a whack-the-duck game consecutively and the app flips that one site's NextDNS denylist entry off for two minutes, then an n8n ranger relocks it on schedule with an on-open fallback if the webhook misses. Phone-wide blocking rides Android Private DNS. Settings sync across devices through a version-stamped relay that stores config only, never keys.
What it does
- Blocks at the DNS layer, so every app and browser on the phone hits the closed trail, verified end-to-end with DNS-over-HTTPS probes returning 0.0.0.0
- The full pass loop runs itself: a game win flips the denylist entry, n8n relocks on schedule, and a self-healing reconcile keeps NextDNS matching the app's closure list
- 118 tests across the pass codec (byte-identical between web and extension), gauntlet state machine, sync relay, and NextDNS proxy
What broke
First real-phone test: blocked sites died correctly, and then every other website on the phone rendered as unstyled 1998 HTML. The blocker had broken the entire internet. Fresh NextDNS profiles ship with a 100,807-entry ads-and-trackers blocklist enabled by default, and it was eating the asset CDNs that serve normal sites' CSS. The blocked-query log pointed straight at minutemediacdn.com. Stripped the profile down to denylist-only and the internet came back.
Want something like this built for your team?
Start a project