ModSync
I built a lightweight coordination layer on top of moderation. It does not replace Reddit moderation — it makes moderation clearer, faster, and far less duplicated.
Inspiration
Before writing any code, I spent time looking at what moderators actually complain about:
- duplicate work
- unclear ownership
- coordination gaps that Reddit’s native modqueue does not solve
In communities with several active mods, it is common for two people to review the same post, undo each other’s mental context, or waste time on items someone else is already handling.
The modqueue is strong at listing what needs attention. But during day-to-day moderation, I realized it does not answer the most important question:
Who is working on what right now?
That gap inspired me to build ModSync: a lightweight coordination layer on top of moderation. A real-time shared state where moderators can claim posts and instantly communicate ownership to the rest of the team.
What I built
ModSync gives moderator teams a shared, live view of the queue with explicit ownership.
Claim & release
A moderator can claim a post directly from the dashboard or from the post menu. I use a Redis lock with a 5-minute TTL to mark the item as In review.
If another moderator tries to claim the same post, the action is blocked and they can immediately see who is already handling it.
Live updates
Claim, release, and resolve events are broadcast through Devvit Realtime, allowing every open dashboard session to stay synchronized without relying entirely on polling.
Shared dashboard
I built a custom subreddit post that loads a React WebView containing:
- tabs: All / Pending / In review / Resolved
- priority labels: Urgent / High / Normal
- source labels: human vs automod
Team visibility
Instead of focusing only on individual actions, I wanted moderators to see coordination impact across the team:
- collisions avoided
- actions completed today
- a lightweight leaderboard
Automatic queue hygiene
I wired triggers for reports, filtered submissions, and moderator actions to keep Redis synchronized automatically.
Periodic reconciliation with Reddit’s modqueue and unmoderated feeds ensures ModSync stays aligned with Reddit’s source of truth.
ModSync does not replace Reddit moderation — it complements it with coordination Reddit does not provide out of the box.
How I built it
I built the entire project using Devvit Blocks end-to-end without relying on a separate Node.js server.
| Layer | Technology |
|---|---|
| Server logic | src/main.tsx — triggers, mod menus, WebView postMessage handlers |
| State | Redis — per-post hashes, active sorted set, expiring locks, daily stats |
| Real-time | Devvit Realtime channel per subreddit |
| UI | React + Vite in webview/ → static bundle in assets/dashboard/ |
| Contract | Shared TypeScript types in shared/modsync-types.ts |
Architecture flow
Reddit events (reports, filtered posts, mod actions)
→ Devvit Blocks update Redis
→ dashboard requests GET_QUEUE
→ moderators CLAIM_ITEM / RELEASE_ITEM
→ Realtime broadcasts updates
→ UI refreshes instantly
I also implemented:
- post context menus for claim, release, and status visibility
- a subreddit menu that opens or creates a single canonical dashboard post
This prevented duplicate dashboard threads and kept moderation centralized.
Challenges I ran into
WebView messaging
Devvit wraps iframe messages inside devvit-message.
At first, the dashboard never handled GET_QUEUE or claim events correctly because I was not unwrapping the payload properly.
I solved this in bridge.ts.
Iframe layout on Shreddit
A plain <webview height="100%"> could render at zero height.
I adjusted the layout to align with Devvit’s tall-post rendering behavior.
Lock vs. state drift
Redis TTLs automatically expire locks, but queue hashes could still remain marked as claimed.
To solve that, I implemented a scheduled cleanup job that resets orphaned claims.
Post ID consistency
Context menus sometimes returned post IDs without the t3_ prefix.
I standardized canonical IDs so locks and queue entries always matched correctly.
Development workflow
npm run dev serves the built bundle inside assets/dashboard/, not the live webview/ source.
That meant UI and branding changes required running:
npm run build:webview
before playtest would reflect updates.
Accomplishments I am proud of
- Turning a real moderation pain point — duplicate work — into a usable product installable inside a subreddit.
- Shipping atomic claims with collision prevention and a visible collisions avoided metric.
- Building a complete full-stack Devvit app using Blocks + Redis + Realtime + React WebView without external infrastructure.
- Designing priority rules based on report volume and source (human vs automod) to improve moderation triage.
- Keeping the entire workflow inside Reddit through dashboard posts, post menus, and native moderator actions.
What I learned
Listening to users matters more than guessing features. Reading moderator communities revealed a much clearer problem than I originally expected.
Devvit’s architecture requires strong boundaries. Blocks own the truth; the WebView behaves like a client. Shared TypeScript contracts became critical to prevent silent failures.
Realtime and polling complement each other. Realtime delivers responsiveness, while polling acts as a recovery layer when state synchronization fails.
Coordination is fundamentally a state problem. The real value was not the UI itself — it was the locking system, TTL handling, and shared synchronization layer.
Platform constraints shape architecture. Moderator-only APIs, channel naming rules, and deployment limitations pushed me toward a simpler and more reliable system design.
What’s next for ModSync
Richer notifications
Optional alerts when:
- urgent items are claimed
- urgent items remain unclaimed for too long
Per-subreddit policies
Configurable moderation behavior including:
- lock duration
- priority thresholds
- automatic release rules
Moderator notes on claims
Allow moderators to leave short handoff notes when releasing items back into the queue.
Historical analytics
Weekly analytics for:
- collisions avoided
- moderation throughput
- team retrospectives
Deeper modqueue integration
Smarter synchronization for edge cases like:
- cross-posts
- removed-but-reported submissions
Accessibility & internationalization
Improved keyboard-first workflows and broader language support for moderation teams worldwide.
Closing thought
ModSync started from a simple realization:
Moderation does not just need a visible queue. It needs visible coordination.
That is the difference.
Demo
Built With
- api
- blocks
- css
- eslint
- html
- javascript
- node.js
- prettier
- react
- realtime
- redis
- typescript
- vite
- webview
Log in or sign up for Devpost to join the conversation.