Skip to content

Collaboration Workspace

This example is the “show me what the product can do” composition. It combines the collaboration, media, and interaction packages into one workspace-style backend instead of presenting them as isolated plugins.

Source-backed example app: examples/collaboration-workspace/

  • identity plus role-aware collaboration
  • forum-style community and room-based chat side by side
  • polls and interaction dispatch layered on top of content surfaces
  • uploaded assets, custom emoji, link unfurls, and GIF search
  • mobile and browser entry points through deep links and fallback redirects
Terminal window
bun add @lastshotlabs/slingshot \
@lastshotlabs/slingshot-assets \
@lastshotlabs/slingshot-auth \
@lastshotlabs/slingshot-chat \
@lastshotlabs/slingshot-community \
@lastshotlabs/slingshot-deep-links \
@lastshotlabs/slingshot-embeds \
@lastshotlabs/slingshot-emoji \
@lastshotlabs/slingshot-gifs \
@lastshotlabs/slingshot-interactions \
@lastshotlabs/slingshot-notifications \
@lastshotlabs/slingshot-permissions \
@lastshotlabs/slingshot-polls
app.config.ts
import { defineApp } from '@lastshotlabs/slingshot';
import { createAssetsPackage } from '@lastshotlabs/slingshot-assets';
import { createAuthPlugin } from '@lastshotlabs/slingshot-auth';
import { createChatPackage } from '@lastshotlabs/slingshot-chat';
import { createCommunityPackage } from '@lastshotlabs/slingshot-community';
import { createDeepLinksPlugin } from '@lastshotlabs/slingshot-deep-links';
import { createEmbedsPlugin } from '@lastshotlabs/slingshot-embeds';
import { createEmojiPackage } from '@lastshotlabs/slingshot-emoji';
import { createGifsPlugin } from '@lastshotlabs/slingshot-gifs';
import { createInteractionsPackage } from '@lastshotlabs/slingshot-interactions';
import { createNotificationsPackage } from '@lastshotlabs/slingshot-notifications';
import { createPermissionsPackage } from '@lastshotlabs/slingshot-permissions';
import { createPollsPackage } from '@lastshotlabs/slingshot-polls';
export default defineApp({
port: 3000,
security: { signing: { secret: process.env.JWT_SECRET! } },
plugins: [
createAuthPlugin({
auth: { roles: ['user', 'moderator', 'admin'], defaultRole: 'user' },
db: { auth: 'memory', sessions: 'memory', oauthState: 'memory' },
}),
createEmbedsPlugin({}),
createGifsPlugin({
provider: 'tenor',
apiKey: process.env.TENOR_API_KEY!,
rating: 'pg',
}),
createDeepLinksPlugin({
fallbackBaseUrl: 'https://app.example.com',
fallbackRedirects: {
'/join/*': '/workspace/:id',
'/share/*': '/thread/:id',
},
}),
],
packages: [
createNotificationsPackage({
dispatcher: { enabled: false, intervalMs: 30_000, maxPerTick: 500 },
}),
createPermissionsPackage(),
createCommunityPackage({ authBridge: 'auto', containerCreation: 'user' }),
createChatPackage({
storeType: 'memory',
permissions: {
createRoom: ['user', 'moderator', 'admin'],
sendMessage: ['user', 'moderator', 'admin'],
},
}),
createPollsPackage(),
createAssetsPackage({
storage: { adapter: 'memory' },
presignedUrls: true,
allowedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
image: { allowedOrigins: ['localhost'] },
}),
createInteractionsPackage({
handlers: {
'polls:vote:': { kind: 'route', target: '/internal/interactions/poll-vote' },
'chat:pin:': { kind: 'queue', target: 'jobs:chat.pin', fireAndForget: true },
},
}),
createEmojiPackage({}),
],
});
CapabilitySurface
Community/community/* for containers, threads, replies, moderation, reports
Chat/chat/* for rooms, messages, membership, pins, receipts
Notifications/notifications/sse for in-app realtime delivery
Polls/polls/* for attached multiple-choice polls
Assets/assets/* for uploaded files and metadata
Emoji/emoji/* for custom emoji records tied to uploaded assets
Embeds/embeds/unfurl for server-side link previews
GIFs/gifs/trending and /gifs/search for composer media search
Deep links/.well-known/* plus fallback browser redirects
Interactions/interactions/dispatch for buttons, menus, and custom action payloads
  • slingshot-auth establishes the user identity.
  • slingshot-permissions publishes shared authorization state for chat, emoji, and other packages.
  • authBridge: "auto" on the community plugin adapts auth context into communityPrincipal so community routes stay decoupled from auth internals.
  • slingshot-notifications gives both chat and community a delivery surface for unread updates, replies, mentions, and invitations.
  • slingshot-assets is the byte-storage foundation for uploads, while slingshot-emoji, slingshot-embeds, and slingshot-gifs build media experiences on top.
  • slingshot-polls and slingshot-interactions are the extension points that let content surfaces feel interactive instead of static.