Inspiration
Many moderation teams already rely on powerful, wiki-backed automations, but legacy bots often require a long-lived server, OAuth setup, polling workers, SQL storage, metrics infrastructure, secrets, and maintenance outside Reddit. The goal for this migration was to keep the practical power of ContextMod while removing the operational tax for moderators.
ContextMod Devvit tries to reduce the second term. Moderators still define community-specific policy, but the repetitive checking, dry-run planning, action execution, and audit logging happen inside Reddit.
What We Built
We rebuilt ContextMod as a Devvit app named hexa-mod. It keeps the legacy YAML/JSON5 configuration model and wiki page convention at r/<subreddit>/wiki/botconfig/contextbot, then maps the old bot workflow onto Devvit primitives:
- Post and comment submit triggers for new content.
- Scheduled modqueue and unmoderated scans for bounded queue coverage.
- Moderator menu actions for status, config validation, manual item checks, permalink or thing-ID checks, fixture tests, and dashboard launch.
- Redis-backed audit, action, config history, cache, dispatch, retry, and retention records.
- A Devvit custom post dashboard with React, Monaco YAML validation, AG Grid tables, current status, config editing, audit logs, dispatch queue visibility, and operations views.
The port supports the major ContextMod rule and action families: author, regex, history, recent activity, repeat activity, attribution, repost, sentiment, toxicity, approve, remove, report, lock, comment, flair, submission, user flair, ban, message/modmail, contributor, Reddit mod notes, Toolbox user notes, dispatch, and cancel dispatch.
How We Built It
The app is structured around a shared moderation processor used by triggers, scheduled tasks, menu actions, and dashboard APIs. Configuration is loaded from the subreddit wiki or a raw Devvit setting override, parsed as YAML/JSON5, hydrated with same-subreddit and cross-subreddit wiki fragments where Reddit permissions allow, validated against schemas, and then evaluated through the migrated rule engine.
Every action goes through explicit safety gates:
- Event processing must be enabled.
- Global dry-run mode must be disabled.
- The action must have
enable: true. - The action cannot be marked action-level dry-run.
- The planning path must be fully supported.
This makes playtesting safer because moderators can validate real configs and inspect planned actions before allowing live moderation actions.
What We Learned
Porting a mature self-hosted bot is less about copying APIs and more about translating runtime assumptions. A polling daemon becomes Devvit triggers and scheduled tasks. SQL and InfluxDB become bounded Redis operational records. External dashboard controls become Devvit settings, menus, and custom post views. Broad network behavior needs explicit fetch-domain decisions.
We also learned that migration tooling matters. The repo includes a static audit script that scans legacy ContextMod configs and reports blockers, fetch-domain needs, and manual review items before a subreddit tries to cut over.
Challenges
The hardest parts were preserving legacy behavior while respecting Devvit boundaries:
- Devvit does not provide the same always-on server model as the old bot, so queue scans and delayed dispatches had to be scheduler-safe.
- Redis is intentionally bounded operational storage, not a direct replacement for the old SQL/Influx/Grafana stack.
- Arbitrary URL config fragments and arbitrary image fetching were not ported because they do not fit a safe Devvit fetch-domain policy.
- Some legacy Reddit behaviors, such as public
comment.asModTeamreplies and broad cross-subreddit action targets, are not exposed the same way in Devvit. - MHS moderation was replaced with Gemini toxicity classification, and image comparison was scoped to Reddit-hosted image domains.
Built With
- Devvit
0.12.24 @devvit/public-api,@devvit/web, Devvit triggers, scheduler, forms, menus, settings, custom posts, Reddit API, Redis, and HTTP fetch domains- TypeScript, Vite, Hono
- React 19
- Monaco Editor and
monaco-yaml - AG Grid
- YAML, JSON5, JSON Schema validation
- Vitest, ESLint, TypeScript build checks
- VADER sentiment
- Gemini API for toxicity/MHS replacement
- YouTube Data API for YouTube repost checks
- Discord webhooks for notifications
pngjsandjpeg-jsfor Reddit image comparison support
Built With
- devvit-sdk
- discord-api
- gemini-api
- node.js
- react
- typescript
- youtube
Log in or sign up for Devpost to join the conversation.