Forum App
Four packages and one auth bridge give you a working forum: channels, threads, replies, reactions, moderation, bans, reports, and realtime notifications.
Install
Section titled “Install”bun add @lastshotlabs/slingshot @lastshotlabs/slingshot-auth @lastshotlabs/slingshot-community @lastshotlabs/slingshot-notifications @lastshotlabs/slingshot-permissions hono zodFull setup
Section titled “Full setup”import type { Context, Next } from 'hono';import { defineApp, getActor } from '@lastshotlabs/slingshot';import { createAuthPlugin } from '@lastshotlabs/slingshot-auth';import { createCommunityPackage } from '@lastshotlabs/slingshot-community';import { createNotificationsPackage } from '@lastshotlabs/slingshot-notifications';import { createPermissionsPackage } from '@lastshotlabs/slingshot-permissions';
const communityAuthBridge = async (c: Context, next: Next) => { const actor = getActor(c); if (actor.kind !== 'anonymous') c.set('communityPrincipal', { subject: actor.id, roles: actor.roles ?? [] }); await next();};
export default defineApp({ port: 3000, security: { signing: { secret: process.env.SECRET! } }, middleware: [communityAuthBridge], plugins: [ createAuthPlugin({ auth: { roles: ['user', 'moderator'], defaultRole: 'user' }, db: { auth: 'memory', sessions: 'memory', oauthState: 'memory' }, }), ], packages: [ createNotificationsPackage({ dispatcher: { enabled: false, intervalMs: 30_000, maxPerTick: 500 }, }), createPermissionsPackage(), createCommunityPackage({ containerCreation: 'user', }), ],});Routes
Section titled “Routes”slingshot-community mounts all routes under /community:
| Resource | Routes |
|---|---|
| Containers | GET /community/containers, POST /community/containers, GET /community/containers/:id |
| Threads | GET /community/containers/:id/threads, POST /community/containers/:id/threads, GET /community/threads/:id |
| Replies | GET /community/threads/:id/replies, POST /community/threads/:id/replies |
| Reactions | POST /community/threads/:id/reactions, POST /community/replies/:id/reactions |
| Moderation | POST /community/threads/:id/lock, POST /community/threads/:id/pin |
| Reports | POST /community/threads/:id/report, POST /community/replies/:id/report |
| Bans | POST /community/bans |
The auth bridge
Section titled “The auth bridge”Community middleware reads communityPrincipal — not raw auth state. The bridge maps the authenticated actor and roles (set by slingshot-auth) into that shape. This keeps the packages independent: community doesn’t depend on auth internals, and auth doesn’t know about community.
Container creation policy
Section titled “Container creation policy”containerCreation: 'user'; // Any authenticated user can create containerscontainerCreation: 'admin'; // Only admins can create containersUse 'admin' when containers are structured sections that only staff should manage.
Realtime notifications
Section titled “Realtime notifications”slingshot-notifications mounts its own SSE inbox at /notifications/sse when the plugin is enabled.
Clients connect to GET /notifications/sse with the same auth they use for the rest of the app. Notification events arrive as SSE messages scoped to the authenticated user.
Auto-moderation
Section titled “Auto-moderation”Use declarative AutoModRule records for pre-persist moderation instead of callback config. The
community package persists reports, warnings, bans, and audit log entries as first-class entities.
Permission grants
Section titled “Permission grants”Grant roles to users on specific containers:
await permissionsAdapter.createGrant({ subjectId: userId, subjectType: 'user', resourceType: 'community:container', resourceId: containerId, roles: ['moderator'], effect: 'allow', grantedBy: 'system',});Built-in community roles: owner (full access), moderator (pin, lock, ban), member (create threads and replies).
Where to go next
Section titled “Where to go next”- slingshot-community — full config reference
- slingshot-permissions — permission model and adapter API
- Config-Driven Domain — build your own domain package using this same pattern