open-slack Svelte Themes

Open Slack

A headless, themeable Slack-style collaboration shell built with Svelte 5 + Tailwind CSS v4. Wire it to any WebSocket backend.

Open Slack

A headless, themeable Slack-style collaboration shell.

Built with Svelte 5 (runes) ยท SvelteKit ยท Tailwind CSS v4 ยท shadcn-svelte. Wire it to any WebSocket backend โ€” or run it standalone against the bundled mock server.


Open Slack is a "blank Slack": the channels, DMs, messages, reactions, mentions, members, and tasks are built; what they look like and what backend they talk to is yours. It's a UI framework for collaboration apps, not a finished product.

  • ๐Ÿงฉ Backend-agnostic โ€” talks a small typed WebSocket protocol (PROTOCOL.md). Bring your own server.
  • ๐ŸŽจ Theme-first โ€” a 3-tier design-token system (src/app.css), dark/light via [data-theme]. No hardcoded colors.
  • ๐Ÿ”Œ Plugin-driven โ€” rail items, sidebar sections, settings tabs, and toolbar items are data-driven via shellConfig.configure() and pluginRegistry.register().
  • โšก Runs standalone โ€” pnpm dev starts an in-memory mock server, so you get a working app with seed data in one command.
  • ๐Ÿ“ฆ Static output โ€” adapter-static, no SSR. Ship it on any CDN, or wrap it in Electron/Tauri.

Install (shadcn-svelte registry)

Open Slack ships as a shadcn-svelte registry โ€” add it to your own SvelteKit project with one command, no clone. You own the copied code.

Prerequisites: a SvelteKit project with Svelte 5, Tailwind v4, and shadcn-svelte initialized (npx shadcn-svelte@latest init).

# the whole UI (core + state + all components + mock backend), one command:
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack.json

It pulls the shadcn primitives it needs (avatar, dialog, โ€ฆ) from the official registry, the design tokens from the Open Slack registry, and the npm deps โ€” then writes everything into your $lib. One manual step: wire the theme into your CSS

/* src/app.css */
@import "tailwindcss";
@import "./open-slack-theme.css"; /* โ† adds Open Slack's @theme tokens */

Prefer ร -la-carte? Each cluster is its own item:

npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-core.json      # engine + state
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-message.json   # message list
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-composer.json  # composer
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-channel.json   # channels
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-panes.json     # home/activity/logs
npx shadcn-svelte@latest add https://open-slack.web.app/r/open-slack-theme.json     # tokens only

Develop / hack on Open Slack itself

pnpm install
pnpm dev          # starts the mock server (:6781) + the web app (:5173)

Open the app, enter any name/email on the login screen, and you're in a demo workspace with a few channels, teammates, and messages. Everything is in-memory โ€” refresh the mock server to reset.

pnpm build        # production build -> ./build (static)
pnpm check        # svelte-check (type + a11y)
node scripts/build-registry.mjs && npx shadcn-svelte registry build  # regenerate registry -> static/r

Wiring your own backend

The UI never imports backend code โ€” it only speaks the os: WebSocket protocol. To point it at your server:

  1. Implement the protocol in PROTOCOL.md (use mock-server/index.ts as the reference).
  2. On the login screen, open Advanced and set the server URL (or replace the /api/dev-token call in src/routes/login/+page.svelte with your real auth).

The typed client lives in src/lib/core/client.ts (SlackClient) โ€” extend it with extends SlackClient to add your own RPCs.

Project layout

src/
  lib/
    core/
      client.ts         # SlackClient โ€” typed WebSocket client + protocol
      types.ts          # Shared interfaces (User, Workspace, Channel, Message, โ€ฆ)
      state.svelte.ts   # Reactive state classes + singletons ($state)
      plugin.svelte.ts  # Plugin registry + shell config
    state/
      app.svelte.ts     # Orchestration: client events โ†” state, all actions
    components/
      message/  composer/  channel/  panes/  settings/  ui/ (shadcn)
  routes/               # SvelteKit file routes (workspace, channel, dm, settings, tasks)
  app.css               # Design tokens (@theme) + light/dark
mock-server/            # Standalone in-memory backend (the protocol reference)

Extending the shell

Register a plugin to add a rail item, a sidebar section, and a settings tab โ€” no core changes needed. See src/lib/plugins/example/ for a complete, copy-pasteable example.

import { pluginRegistry, shellConfig } from "$lib/core/plugin.svelte.js";

shellConfig.configure({ appName: "My App", features: { tasks: true } });

pluginRegistry.register({
  id: "notes",
  name: "Notes",
  railItems: [
    { id: "notes", label: "Notes", icon: "<svgโ€ฆ>", path: "/notes", position: "nav", order: 5 },
  ],
});

Tech & conventions

  • Svelte 5 runes only โ€” $state / $derived / $props, no stores.
  • TypeScript strict, named exports, PascalCase component files.
  • Tailwind v4 with @theme tokens; override tokens, don't hardcode.
  • shadcn-svelte primitives in src/lib/components/ui.

License

MIT ยฉ Open Slack contributors.

Open Slack is an independent open-source project and is not affiliated with, endorsed by, or sponsored by Slack Technologies / Salesforce. "Slack" is used only to describe the familiar UI pattern this shell replicates.

Top categories

Loading Svelte Themes