stream-chat-react Development Patterns
Apply when generating or modifying UI code in this repo.
Styling
File and folder structure
- Format:
.scss only.
- Location:
src/components/<ComponentName>/styling/.
- Required: Each component styling folder has an
index.scss.
- Registration: Each
src/components/<ComponentName>/styling/index.scss is imported in src/styling/index.scss with an alias.
- Specificity: Each component has own
.scss file in the src/components/<ComponentName>/styling folder
Import order in src/styling/index.scss:
- Three groups; within each group, alphabetical order.
- Group 1: imports from
src/styling/.
- Group 2: general components (Button, Dialog, etc.).
- Group 3: chat components (MessageList, etc.).
SCSS practices
- Use full class names instead of only
&__suffix so selectors are easy to search.
- Avoid duplicate blocks for the same resolved CSS selector (after nesting).
Icons
- Icons live in
src/components/Icons.
- Do not move icons out of SCSS into
src/components/Icons; keep existing icon placement unless explicitly refactoring icons.
Source: .ai/DEV_PATTERNS.md.
Translating quantities (plurals)
- Use plural suffixes only:
_one, _other, and _few, _many where the locale requires them.
- Do not add a standalone key (e.g.
"{{count}} new messages"). Only add quantified variants: "{{count}} new messages_one", "{{count}} new messages_other", etc.
- Follow existing patterns in
src/i18n/ (e.g. {{count}} unread_one, unreadMessagesSeparatorText_other).
- Locale plural rules (CLDR):
en, de, nl, tr, hi, ko, ja use _one + _other; es, fr, it, pt add _many; ru uses _one, _few, _many, _other.
Imports
When importing from 'stream-chat' library, always import by library name (from 'stream-chat'), not relative path (from '..path/to/from 'stream-chat-js/src').
React components
Try to avoid inline style attribute and prefer adding styles to .scss files.
How a plugin works in stream-chat-react
A "plugin" is just a separate build entry point that ships as a subpath export (e.g. stream-chat-react/emojis, stream-chat-react/mp3-encoder). Concretely, each plugin is wired in 4 places:
- Source folder — src/plugins// with an index.ts re-exporting its public API (see src/plugins/Emojis/index.ts).
- Vite entry — a new key in build.lib.entry in vite.config.ts:20.
- package.json — an exports subpath + a typesVersions entry (package.json:18,44).
- Styling (optional) — a styling/index.scss added as a separate sass target in the build-styling script (package.json:185), producing its own CSS file like dist/css/emoji-picker.css.
1---2name: dev-patterns3description: Styling and structure conventions for stream-chat-react. Use when adding or editing components, SCSS, or icons in this repo—file layout, styling folder structure, SCSS imports, and icon placement.4---56# stream-chat-react Development Patterns78Apply when generating or modifying UI code in this repo.910## Styling1112### File and folder structure1314- **Format:** `.scss` only.15- **Location:** `src/components/<ComponentName>/styling/`.16- **Required:** Each component styling folder has an `index.scss`.17- **Registration:** Each `src/components/<ComponentName>/styling/index.scss` is imported in `src/styling/index.scss` with an alias.18- **Specificity:** Each component has own `.scss` file in the `src/components/<ComponentName>/styling` folder1920**Import order in `src/styling/index.scss`:**21221. Three groups; within each group, alphabetical order.232. **Group 1:** imports from `src/styling/`.243. **Group 2:** general components (Button, Dialog, etc.).254. **Group 3:** chat components (MessageList, etc.).2627### SCSS practices2829- Use **full class names** instead of only `&__suffix` so selectors are easy to search.30- Avoid duplicate blocks for the same resolved CSS selector (after nesting).3132## Icons3334- Icons live in `src/components/Icons`.35- **Do not** move icons out of SCSS into `src/components/Icons`; keep existing icon placement unless explicitly refactoring icons.3637Source: `.ai/DEV_PATTERNS.md`.3839## Translating quantities (plurals)4041- **Use plural suffixes only:** `_one`, `_other`, and `_few`, `_many` where the locale requires them.42- **Do not** add a standalone key (e.g. `"{{count}} new messages"`). Only add quantified variants: `"{{count}} new messages_one"`, `"{{count}} new messages_other"`, etc.43- Follow existing patterns in `src/i18n/` (e.g. `{{count}} unread_one`, `unreadMessagesSeparatorText_other`).44- Locale plural rules (CLDR): `en`, `de`, `nl`, `tr`, `hi`, `ko`, `ja` use `_one` + `_other`; `es`, `fr`, `it`, `pt` add `_many`; `ru` uses `_one`, `_few`, `_many`, `_other`.4546## Imports4748When importing from 'stream-chat' library, always import by library name (from 'stream-chat'), not relative path (from '..path/to/from 'stream-chat-js/src').4950## React components5152Try to avoid inline `style` attribute and prefer adding styles to `.scss` files.5354## How a plugin works in stream-chat-react5556A "plugin" is just a separate build entry point that ships as a subpath export (e.g. stream-chat-react/emojis, stream-chat-react/mp3-encoder). Concretely, each plugin is wired in 4 places:5758- Source folder — src/plugins/<Name>/ with an index.ts re-exporting its public API (see src/plugins/Emojis/index.ts).59- Vite entry — a new key in build.lib.entry in vite.config.ts:20.60- package.json — an exports subpath + a typesVersions entry (package.json:18,44).61- Styling (optional) — a styling/index.scss added as a separate sass target in the build-styling script (package.json:185), producing its own CSS file like dist/css/emoji-picker.css.