Inspiration
Every mod tool out there — is about catching bad behavior. But every long-running community knows that the surest way to reduce bad behavior is to amplify the good so it sets the cultural tone. Today, the "thank the helpers" loop is purely manual: a sticky comment that disappears, an off-the-cuff flair edit, nothing durable. GoodNeighbor automates it.
What it does
GoodNeighbor runs in the background and turns positive participation into visible recognition:
- Auto-scoring via Devvit triggers: every new comment is +1, every new post is +3, every mod approval is +5.
- One-tap mod endorsement from any post
⋮, any comment⋮, or an inline button on the leaderboard — adds +25 points and a ✅ Mod-endorsed badge. - Auto-applied user flair showing the user's earned badges and score (e.g.
🌱🤝✅ • 128) wherever they post or comment in the sub. - Weekly MVP post automatically published every Sunday 17:00 UTC, with a custom-post leaderboard webview.
- Custom-post leaderboard webview with the top 10 contributors, the viewer's own score, mod-only endorse controls, and a refresh button.
How I built it
- Devvit Web 0.12.24 — HTTP server + webview pattern with a typed
shared/api.tscontract between client and server - Devvit Triggers (
onCommentCreate,onPostCreate,onModAction,onAppInstall) feed the scoring engine - Devvit Scheduler with cron
0 17 * * 0drives the weekly MVP job - Redis sorted set (
gn:score:{sub}) ranks contributors; JSON-encoded badges per-user; 24h endorsement cooldown to prevent abuse; weekly snapshot for the leaderboard post - Reddit Plugin at
moderatorscope forsetUserFlair,getPostById,getCommentById, andsubmitCustomPost - TypeScript end-to-end, esbuild for both client and server bundles
Tier badges derive purely from cumulative score (1 → Newcomer, 25 → Active, 100 → Long-time), so badge state is rebuildable from the ZSET — no separate audit log needed.
Challenges I ran into
- Devvit Web
permissionsblock must explicitly declareredis: trueandreddit: { scope: "moderator" }— otherwise the webview asset endpoint silently breaks. (Carried over from earlier Devvit work.) - Schema-first config — we navigated the trigger and scheduler shape directly from
@devvit/shared-types/schemas/config-file.v1.jsoninstead of guessing, which saved several upload cycles. - Idempotent endorsement — mod endorsements had to be cooldown-gated per user so a click-happy mod can't inflate someone's score. Implemented with a per-user timestamp key (
gn:endorsed:{sub}:{user}) and a 24h window. - Trigger-driven flair updates —
setUserFlairmay fail (flair disabled in sub, user not in sub) but scoring must continue. We swallow the flair error and warn, so the scoring engine is never blocked by an optional cosmetic side effect.
Accomplishments we're proud of
- Zero-config install: a mod installs GoodNeighbor and scoring starts on the next comment. No setup wizard, no config screen.
- Mobile-first mod UX: every mod action (endorse from post, endorse from comment, view leaderboard) works in the Reddit mobile app.
- Compounding cultural value: every
⭐ Weekly MVPflair a user sees in a thread is a passive, durable signal that says "this is what we celebrate here." That's mod-tool ROI that increases over time. - Net-new lane in the Devvit ecosystem: the hackathon brief explicitly invites "incentivize good behavior" tools as an alternative to enforcement, and no app currently occupies it.
What we learned
- The Devvit trigger model is genuinely cheap to use — feed every relevant event into a single small Redis-backed scoring function and you've built a community-recognition system in ~400 lines of server code.
- User flair is the right surface for "ambient" recognition because every Reddit thread already shows it. Custom posts are the right surface for "active" recognition (the weekly MVP).
- Schema-first config (reading the JSON Schema directly) is dramatically faster than guessing — for both triggers and scheduler.
What's next
- Per-subreddit tunable thresholds — let mods configure badge cutoffs in the app settings.
- Negative signals — automatically decay or strip badges on repeat removed content.
- Streaks — bonus points for consistent weekly participation, displayed as a separate flair badge.
- Mod team endorsement — require 2+ mod endorsements before a badge sticks permanently, to distribute trust.
- Cross-post recognition — opt-in inter-sub recognition for users who carry their good standing across multiple installed subs.
Built With
- css
- devvit
- devvit-scheduler
- devvit-triggers
- esbuild
- html
- node.js
- redis
- typescript

Log in or sign up for Devpost to join the conversation.