Appearance in Telegram Web K is controlled by a layered system: a global day/night mode, per-theme accent color overrides, a flexible chat background engine that handles solid colors, gradients, and tiled patterns, and per-peer accent colors that give each contact a distinct visual identity. All of these ultimately write to CSS custom properties onDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/TelegramOrg/Telegram-web-k/llms.txt
Use this file to discover all available pages before exploring further.
document.documentElement, so the entire UI reacts instantly without re-renders.
ThemeController
src/helpers/themeController.ts is the central authority for active theme state. It is exported as the singleton themeController and is accessible globally via MOUNT_CLASS_TO.themeController in debug builds.
Day and night mode
The controller listens to the OSprefers-color-scheme media query through setThemeListener() and stores the result as systemTheme. When the user switches manually, switchTheme() writes the preference to app settings and dispatches a theme_change event.
coordinates is provided (e.g., the position of the toggle button) and the browser supports the View Transitions API, the switch plays a circular-reveal animation expanding from that point.
Color maps
Two built-in palettes —day and night — define the baseline hex values for every semantic color token:
| Token | Day | Night |
|---|---|---|
primary-color | #3390ec | #8774E1 |
message-out-background-color | light green | purple-tinted |
surface-color | #ffffff | #212121 |
danger-color | #df3f40 | #ff595a |
primary-text-color | #000000 | #ffffff |
secondary-text-color | #707579 | #aaaaaa |
primary-color also produces --primary-color-rgb, --light-primary-color, --light-filled-primary-color, and --dark-primary-color. This is controlled by the appColorMap descriptor per token.
Applying a theme from Telegram servers
Telegram supports downloadable themes that override the accent and message colors.applyNewTheme() fetches the wallpaper and color settings from a Theme object returned by the API and blends them with the baseline palette using HSV color math, ensuring contrast is maintained regardless of the chosen accent.
Theme params for Web Apps
getThemeParamsForWebView() maps internal CSS variables to the TelegramWebViewTheme schema so that Mini Apps receive matching colors when the user switches themes.
Chat backgrounds
Background tab — src/components/sidebarLeft/tabs/background.ts
AppBackgroundTab extends SliderSuperTab and presents the wallpaper picker. It fetches available wallpapers from appThemesManager.getWallPapers() and displays them in a grid. Three top-level buttons let the user:
- Upload — pick a local image file via
requestFile(), scale it withscaleMediaElement(), and set it as the wallpaper. - Set color — open
AppBackgroundColorTab(backgroundColor.ts) to choose a solid or gradient background. - Reset — restore the default wallpaper.
WallPaper.settings.blur and immediately re-renders the active background.
Gradient renderer — src/components/chat/gradientRenderer.ts
ChatBackgroundGradientRenderer handles multi-stop color gradient backgrounds. It interpolates between up to four colors from the wallpaper’s settings using a moving gradient animation, drawing frames to a <canvas> element that sits behind the message list.
Pattern renderer — src/components/chat/patternRenderer.ts
Pattern backgrounds tile a semi-transparent SVG or image over the gradient layer. The renderer composites the pattern with the gradient colors and respects theintensity setting from the wallpaper object. It runs on a <canvas> and is hardware-accelerated.
SCSS architecture
Styles are split acrosssrc/scss/ and imported through src/materialize.scss.
src/scss/variables.scss:
.module.scss files). Global styles live in the src/scss/partials/ and src/scss/components/ directories.
CSS custom properties
All semantic colors are surfaced as CSS custom properties (e.g.,--primary-color, --surface-color, --message-out-background-color). themeController.applyAppColor() writes these directly to document.documentElement.style. SCSS only hard-codes structural values like spacing and radii; color always comes from var(--token-name).
Peer colors
Every Telegram user and channel has an accent color used for name labels, reply headers, and mention highlights.src/components/peerColors.ts provides setPeerColorToElement() which resolves the correct CSS variable for a given peer.
There are two color modes:
- Index-based — seven predefined color indices (
--peer-0-color-rgb…--peer-6-color-rgb) assigned by Telegram based on the peer’s ID. - Collectible — Premium users can choose custom colors or gradient sets (
peerColorCollectible). These include optional dark-mode variants and are applied as gradients via--peer-border-background.
Power saving mode
src/components/sidebarLeft/tabs/powerSaving.ts exposes the Lite Mode settings panel (LiteMode.Title). Users can individually toggle:
- Video autoplay
- GIF autoplay
- Sticker animations (panel and chat)
- Effect animations (reactions, premium stickers, emoji)
- Chat background animation and spoiler effects
- General UI animations
liteMode helper (src/helpers/liteMode.ts) is queried throughout the codebase via liteMode.isAvailable('key') before starting any animation or effect, so disabling a category has immediate global effect without requiring a reload.
Related pages
UI components
The full component catalogue, rendering models, and animation infrastructure.
Localization
How language packs are fetched, cached, and applied across the UI.