Replace lucide-svelte with @manacore/shared-icons across all web apps for consistent icon usage throughout the monorepo. Apps migrated: - calendar (12 files) - contacts (1 file) - matrix (16 files) - nutriphi (7 files) - presi (6 files) - questions (9 files) - skilltree (9 files) - storage (16 files) - todo (package.json only) Key icon mappings: - Trash2 → Trash - ChevronLeft/Right/Up/Down → CaretLeft/Right/Up/Down - Search → MagnifyingGlass - Settings → Gear - Loader2 → CircleNotch - AlertCircle → WarningCircle - ExternalLink → ArrowSquareOut - LogOut → SignOut
4.7 KiB
Matrix Client
Self-hosted Matrix chat client built with SvelteKit and matrix-js-sdk.
Project Overview
A minimal, privacy-focused Matrix client that connects to your self-hosted Synapse server (matrix.mana.how).
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | SvelteKit 2, Svelte 5 (runes), Tailwind CSS 4 |
| Matrix SDK | matrix-js-sdk |
| State Management | Svelte 5 runes ($state, $derived) |
| Icons | @manacore/shared-icons (Phosphor) |
| Date Handling | date-fns |
Project Structure
apps/matrix/
├── apps/
│ └── web/ # SvelteKit web client
│ ├── src/
│ │ ├── routes/
│ │ │ ├── (auth)/ # Login flow
│ │ │ ├── (app)/ # Protected chat routes
│ │ │ └── health/ # Health check endpoint
│ │ └── lib/
│ │ ├── matrix/ # Matrix SDK integration
│ │ │ ├── store.svelte.ts # Reactive Matrix store
│ │ │ ├── client.ts # Login/auth functions
│ │ │ ├── types.ts # TypeScript types
│ │ │ └── polyfills.ts # Browser polyfills
│ │ └── components/
│ │ └── chat/ # Chat UI components
│ └── package.json
└── packages/
└── shared/ # Shared types
Development
# Start the Matrix web client
pnpm dev:matrix:web
# Or from monorepo root
pnpm matrix:dev
The client runs on http://localhost:5180
Key Files
Matrix Store (src/lib/matrix/store.svelte.ts)
Central reactive store using Svelte 5 runes:
import { matrixStore } from '$lib/matrix';
// State
matrixStore.syncState // 'STOPPED' | 'PREPARED' | 'SYNCING' | etc.
matrixStore.isReady // boolean - client ready for use
matrixStore.rooms // SimpleRoom[] - all rooms
matrixStore.messages // SimpleMessage[] - current room messages
matrixStore.currentRoom // Room | null - selected room
// Actions
await matrixStore.initialize(credentials);
matrixStore.selectRoom(roomId);
await matrixStore.sendMessage('Hello!');
await matrixStore.sendTyping(true);
matrixStore.logout();
Login Client (src/lib/matrix/client.ts)
import { loginWithPassword, checkHomeserver } from '$lib/matrix';
const result = await loginWithPassword('matrix.mana.how', 'user', 'password');
if (result.success) {
await matrixStore.initialize(result.credentials);
}
Features
Phase 1 (Current)
- Password login
- Room list (DMs and groups)
- Message timeline
- Send text messages
- Typing indicators
- Read receipts
- Unread counts
- Message pagination (load more)
Phase 2 (Planned)
- End-to-end encryption (E2EE)
- File/image uploads
- Message editing/deletion
- Room creation
- User search/invite
Phase 3 (Future)
- VoIP calls (WebRTC)
- Video calls
- Screen sharing
Configuration
Environment Variables
No environment variables required for basic usage. The client stores credentials in localStorage.
Default Homeserver
The login page defaults to matrix.mana.how but any Matrix homeserver can be used.
Matrix SDK Notes
Browser Polyfills
matrix-js-sdk requires polyfills for browser usage. These are automatically loaded in src/lib/matrix/polyfills.ts:
Bufferfrom buffer packageglobalmapped toglobalThisprocess.envstub
Vite Configuration
Special Vite config in vite.config.ts:
define: {
global: 'globalThis',
},
optimizeDeps: {
include: ['buffer', 'events'],
}
Client-Side Only
matrix-js-sdk only works client-side. Always guard with:
import { browser } from '$app/environment';
if (browser) {
await matrixStore.initialize();
}
Troubleshooting
"super.off is not a function"
This is a known issue with typed-event-emitter. Make sure polyfills are loaded before any matrix-js-sdk imports.
Login fails with network error
- Check if homeserver is reachable:
curl https://matrix.mana.how/_matrix/client/versions - Verify CORS is configured on Synapse
- Try without https:// prefix in homeserver field
Messages not loading
The initial sync can take time depending on room history. Check matrixStore.syncState for status.