Inspiration
Every subreddit moderator knows the feeling: you're reviewing a report, the username looks familiar, but you have no idea if this person was banned last month, had five posts removed last week, or if a fellow mod is already handling it. You open modmail, search the mod log, cross-reference ban history - all while the queue keeps growing.
The inspiration for ModTower was a simple analogy: a watchtower. Just like a sentinel watches the frontier and alerts the garrison to incoming threats, ModTower gives mod teams instant, contextual intelligence on any user - without ever leaving their workflow. No external dashboards. No tab-switching. No duplicated effort.
What it does
ModTower is a single Devvit app that gives Reddit mod teams two things: user intelligence and team coordination, both accessible from one mod menu click.
On any post or comment, a moderator can trigger ModTower's overlay to instantly see:
- A reputation score (🟢 GOOD / 🟡 MODERATE / 🟠 AT RISK / 🔴 CRITICAL) computed from the user's full behavioral history on that subreddit
- A breakdown of removals, bans, and reports, alongside account age and karma
- Ban history (last 5 entries) with dates, durations, and reasons
- Private mod notes - add, view, and delete notes scoped per subreddit
- Quick actions: ban, temp-ban (1d / 3d / 7d / 30d), or remove content - all with confirmation steps, executed without leaving the overlay
On the coordination side, ModTower prevents the duplicate-work problem that plagues active mod teams:
- Claimed-by locks on modqueue items so two mods don't process the same report simultaneously
- A shared mod notepad for shift handoff notes and pinned reminders - append-only so no mod can accidentally overwrite another's notes
Everything is built natively inside Reddit - no external services, no databases outside of Devvit, no dashboards to leave Reddit for.
How we built it
ModTower is built entirely on Devvit (TypeScript) using the Hono framework for server-side routing.
Passive data collection via triggers
User history is built automatically - no moderator action is required to start tracking. Devvit triggers fire on moderation events and write structured data to the KV (Redis) store:
onModAction→ handles both removals (incrementing the removal counter) and bans (appending a structured ban entry{ date, duration, reason, bannedBy }to the user's ban history), differentiating between action types within a single handleronPostReport/onCommentReport→ increments the user's report count each time their content is reported, firing at the exact moment the report is submittedonPostCreate/onCommentCreate→ tracks positive signals - post and comment counts that contribute to the user's score
The scoring engine
The reputation score starts at a baseline of 1000 and is adjusted by behavioral signals and positive account factors:
$$\text{score} = 1000 - (r \times 30) - (b \times 100) - (rep \times 10) + \min(a, 120) + \min!\left(\lfloor k/100 \rfloor, 100\right) + (p \times 5) + (c \times 2)$$
Where $r$ = removals, $b$ = bans, $rep$ = reports received, $a$ = account age in months, $k$ = karma, $p$ = post count, $c$ = comment count. The score is clamped to $[0, 1500]$ and maps to four tiers:
| Tier | Score Range |
|---|---|
| 🟢 GOOD | ≥ 800 |
| 🟡 MODERATE | 500 – 799 |
| 🟠 AT RISK | 200 – 499 |
| 🔴 CRITICAL | < 200 |
Every recomputation is logged as a snapshot { score, tier, delta, triggeredBy, ts } in a ring buffer capped at 100 entries - giving mods a full audit trail of how a user's standing has evolved.
UI via native Devvit forms
Rather than building a custom interactive post, ModTower surfaces everything through native Devvit forms chained together. This keeps the overlay reliable across desktop and mobile Reddit without any webview complexity.
Coordination layer
Claimed-by locks use optimistic writes to the KV store with a 10-minute TTL - stale claims auto-expire without any cleanup job. The shared notepad is an append-only log capped at 50 entries, with lazy cleanup on read to prevent unbounded KV growth.
Challenges we ran into
Devvit's UI constraints forced a full pivot. Our original plan involved rich React-based interactive overlays. We hit the wall quickly - Devvit's form and menu system is opinionated in ways that make custom React UIs unreliable in the mod context. We had to scrap those components and redesign the entire UI layer around native Devvit forms. Counterintuitively, the result is cleaner and works reliably everywhere Reddit runs.
KV schema design without relational queries. Designing a flat key-value schema that supports efficient lookup, bounded history arrays, and partial updates required careful upfront architecture. We went through several iterations before landing on a mergeUser() helper that handles partial patches safely and keeps bans capped at 50 entries, notes at 50, and score history at 100 - preventing unbounded KV growth.
Devvit's trigger model has useful surprises. We initially attempted to track reports via onPostCreate with a delayed scheduler re-fetch - store a preliminary snapshot at trigger time, then re-fetch 5 minutes later to capture reports that arrived after submission. Mid-build we discovered Devvit exposes dedicated onPostReport and onCommentReport triggers that fire at the exact moment of report submission, making the scheduler approach entirely unnecessary and giving us more accurate data with less complexity.
Scope discipline under a hard deadline. ModTower started with a much larger feature set. A modqueue risk-sort view, a cross-subreddit reputation federation layer, an auto-action rules engine, a mod presence panel, per-item coordination chat, and an analytics dashboard all got cut or deferred. Focusing on the core loop - instant user intelligence plus team coordination, from a single mod menu click - was what made the difference between a demo and a deployable tool.
Accomplishments that we're proud of
Zero-overhead data collection. Moderators don't have to do anything differently. The moment ModTower is installed, it starts building user history silently in the background via triggers. By the time a mod first checks a user, their record may already have weeks of history.
A scoring model that rewards good actors. Most risk systems only penalize bad behavior. Ours also rewards account age, karma, and posting history - so a long-standing community member isn't unfairly flagged by a single incident, and a new account with no positive signals gets appropriate scrutiny.
TTL-as-logic. Using Redis TTLs as the actual mechanism for claim lock expiry - rather than running cleanup jobs - is an elegant pattern we're proud of. It means the coordination layer is self-healing by design.
Staying fully native. ModTower has no external dependencies, no third-party APIs, and no data leaving Reddit's infrastructure. Everything runs on Devvit KV and the Reddit API. That's a genuine trust advantage for mod teams who are rightly cautious about what they install.
What we learned
- Devvit's trigger system is more powerful than it first appears. Once you stop trying to fight the architecture and lean into the event-driven model, passive data collection becomes almost trivial to implement.
- TTLs are a first-class design primitive, not just an expiry mechanism. Using them for claim locks eliminated entire categories of state management.
- Native forms beat custom UI in constrained environments. The temptation to build beautiful React overlays was real. Devvit forms chain elegantly, render reliably, and required far less debugging.
- Scoping is the hardest skill. Every cut feature felt like a loss in the moment. Shipping a polished, tight MVP is a better outcome than shipping an ambitious but rough one.
What's next for ModTower
- Score history timeline - surface the stored
scoreHistory[]ring buffer in the reputation overlay as a readable audit trail: "−30 · removal · 2 days ago", "+5 · post · 1 week ago" - so mods can see exactly how a user's standing has changed over time and what drove each shift. - Auto-action rules engine - let mods configure threshold-based triggers via a rule builder UI: if a user's score drops below a configured value on a new post, automatically remove it, flag it for review, or notify the mod team via modmail. Rules stored in Devvit settings, evaluated on every score recomputation.
- Modqueue risk sort - a custom modqueue view that surfaces the highest-risk items first using the
getModQueueAPI, so mod teams can triage the most dangerous content before anything else. Each item annotated with the author's reputation tier inline. - Per-item mod coordination chat - ephemeral discussion threads attached to individual modqueue items with a 7-day TTL, so mods can deliberate on borderline cases without leaving the queue or creating noise in modmail.
- Analytics dashboard - a scheduled daily aggregation job surfacing removals over time, top risky users, ban trends, and modqueue throughput as an interactive post pinned to the mod community wiki.
- Cross-subreddit opt-in reputation federation - an anonymized signal-sharing protocol that lets participating subreddits contribute to and query a shared reputation layer for users whose risk tier is CRITICAL, without sharing content, reasons, or personally identifiable context. Opt-in only, privacy-first, designed for multi-sub mod teams managing coordinated ban evasion.
Built With
- devvit
- devvit-cli
- eslint
- github-actions
- hono
- redis
- typescript
- vitest
Log in or sign up for Devpost to join the conversation.