Getting Started
This guide walks you through installing Synapse UI in an Angular application and using the MVP components.
Status: The npm packages and Nx workspace are not yet scaffolded. This guide describes the intended consumer experience. Track implementation progress in PROGRESS.md.
Prerequisites
- Node.js ^20.19.0
- Angular 21.x (latest stable)
- npm 9.x+
Installation
Install the MVP packages:
npm install @synapse-ui/theme @synapse-ui/ai-prompt @synapse-ui/stream-container
npm install marked shiki
Configure Theming
Add the theme provider to your application config:
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideSynapseTheme } from '@synapse-ui/theme';
export const appConfig: ApplicationConfig = {
providers: [
provideSynapseTheme({
defaultTheme: 'light',
persist: true,
}),
],
};
Import the base token stylesheet in angular.json or styles.css:
@import '@synapse-ui/theme/tokens.css';
Build a Chat Interface
1. Template
<!-- chat.component.html -->
<div class="chat-layout">
<synapse-ai-stream-container
[content]="response()"
[streaming]="isStreaming()"
/>
<synapse-ai-prompt-bar
[loading]="isStreaming()"
(submit)="sendPrompt($event)"
(stopGeneration)="stopStream()"
/>
</div>
2. Component
import { Component, signal, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { AiPromptBarComponent, PromptSubmitEvent } from '@synapse-ui/ai-prompt';
import { AiStreamContainerComponent } from '@synapse-ui/stream-container';
@Component({
selector: 'app-chat',
standalone: true,
imports: [AiPromptBarComponent, AiStreamContainerComponent],
templateUrl: './chat.component.html',
styleUrl: './chat.component.css',
})
export class ChatComponent {
private destroyRef = inject(DestroyRef);
private abortController: AbortController | null = null;
response = signal('');
isStreaming = signal(false);
sendPrompt(event: PromptSubmitEvent): void {
this.response.set('');
this.isStreaming.set(true);
this.abortController = new AbortController();
// Example: connect to your SSE backend
const source = new EventSource(`/api/chat?prompt=${encodeURIComponent(event.text)}`);
source.onmessage = (e) => {
this.response.update((prev) => prev + e.data);
};
source.onerror = () => {
source.close();
this.isStreaming.set(false);
};
}
stopStream(): void {
this.abortController?.abort();
this.isStreaming.set(false);
}
}
3. Styles
Use theme tokens — no hardcoded colors:
.chat-layout {
display: flex;
flex-direction: column;
gap: var(--synapse-spacing-4);
max-width: 48rem;
margin: 0 auto;
padding: var(--synapse-spacing-6);
background: var(--synapse-surface-primary);
min-height: 100vh;
}
Theme Switching
import { ThemeService } from '@synapse-ui/theme';
// In a settings component
themeService.setTheme('dark');
See ThemeService for the full API.
Next Steps
| Topic | Doc |
|---|---|
| Component APIs | Components |
| Architecture | Overview |
| Create your own component | Creating a Component |
| Publish packages | Publishing |
| Contribute | CONTRIBUTING.md |
Troubleshooting
Styles look unstyled / no colors
Ensure @synapse-ui/theme/tokens.css is imported and provideSynapseTheme() is in your app config.
Stream container not updating
Verify you are updating the content signal/input on each SSE chunk and that streaming is true during active streams.
Shiki highlighting slow on first render
Shiki loads grammars lazily. Pre-load common languages in app bootstrap if needed (documented in Phase 2 implementation).