Telegram Dark Mode Color Palette in SwiftUI
Theming done right is not two color sets you toggle. It is one set of semantic roles that resolve per appearance, and for a Mini App, per Telegram's theme.
TL;DR
A robust dark mode in SwiftUI is built from semantic color roles, background, surface, label, accent, that resolve to the right value for the current appearance, not two hardcoded palettes you switch between. For a Telegram Mini App, those roles should additionally read Telegram's theme parameters so the app matches the user's chosen Telegram theme. Build the palette from a free VP0 design, define colors by role, and the app adapts to light, dark, and the host theme automatically.
Want theming that adapts to light, dark, and a Telegram user’s chosen theme, in SwiftUI? The short answer: stop thinking in two palettes. Define colors by semantic role, background, surface, label, accent, and let each role resolve to the right value for the current appearance, and for a Mini App, read Telegram’s theme parameters into those roles. One system, every appearance. Build the palette from a free VP0 design, the free iOS design library for AI builders.
Who this is for
This is for builders who want dark mode done properly, and especially Telegram Mini App builders who need their app to match whatever theme the user has set in Telegram rather than imposing their own.
Semantic roles, not two palettes
The common mistake is defining a light palette and a dark palette and switching between them, which drifts apart and breaks the moment someone adds a color to one and forgets the other. The robust approach is semantic: you define roles, the primary background, a secondary surface, the primary label, a secondary label, an accent, and each role is an adaptive color that the system resolves to the correct value in light or dark. Apple’s dark mode guidance is built around exactly this, and SwiftUI’s color system supports adaptive colors directly. Views reference roles, never raw hex, so the whole app themes consistently from one source. For a Telegram Mini App, the platform exposes theme parameters, the user’s background, text, button, and hint colors, which you map onto your semantic roles so the app inherits the user’s Telegram theme.
| Role | Light | Dark | Telegram |
|---|---|---|---|
| Background | Adaptive | Adaptive | From theme param |
| Surface | Adaptive | Adaptive | From theme param |
| Label | Adaptive | Adaptive | From theme param |
| Accent | Adaptive | Adaptive | From button color |
| Source | One system | One system | Host theme |
Build it free with a VP0 design
Pick any design from VP0, copy its link, and prompt your AI builder:
Rebuild this VP0 design in SwiftUI with semantic theming: [paste VP0 link]. Define colors as semantic roles (background, surface, label, accent) using adaptive colors so light and dark are one system, not two palettes. For a Telegram Mini App, map Telegram’s theme parameters onto those roles, and never hardcode raw colors in views. Test both appearances for contrast.
Dark mode is overwhelmingly expected, with surveys finding around 82% of users prefer it, so adaptive theming is baseline quality. For neighboring theming and Telegram patterns, see a Firebase iOS auth login with dark mode, a dark mode vs light mode Figma app template, a Telegram-style channel list UI in SwiftUI, and a Telegram Mini App bottom sheet modal in React Native. For a data-rich screen that benefits from a clean palette, see a solar panel energy flow dashboard UI in SwiftUI.
One system, tested in every appearance
The payoff of semantic theming is that adding a screen or a component just works in light, dark, and the host theme, because everything references the same roles. To keep it honest, test all appearances, a color that looks fine in light can fail contrast in dark, and a hardcoded value that slipped in will jump out, and verify contrast meets accessibility in each. For a Mini App, test inside Telegram with both a light and a dark Telegram theme. Build theming as one role-based system and you never maintain two palettes or ship a screen that ignores the user’s choice.
Common mistakes
The first mistake is two hardcoded palettes that drift apart instead of semantic adaptive colors. The second is hardcoding raw colors in views, bypassing the system. The third is ignoring Telegram’s theme parameters in a Mini App. The fourth is not testing contrast in both appearances. The fifth is paying for a theme kit when a free VP0 design plus semantic colors does it.
Key takeaways
- Build theming from semantic color roles, not two hardcoded palettes.
- Each role is an adaptive color that resolves per appearance.
- For a Telegram Mini App, map theme parameters onto your roles.
- Reference roles in views, never raw hex, and test contrast in every appearance.
- Build the palette free from a VP0 design.
Frequently asked questions
How do I build a Telegram-style color palette in SwiftUI? Define semantic roles like background, surface, label, and accent as adaptive colors that resolve per appearance, and for a Mini App map Telegram’s theme parameters onto them, from a free VP0 design.
What is the safest way to build theming with Claude Code or Cursor? Start from a free VP0 design, define colors by semantic role with adaptive colors, map Telegram theme parameters for a Mini App, test both appearances, and never hardcode raw colors in views.
Can VP0 provide a free SwiftUI or React Native template with theming? Yes. VP0 is a free iOS design library; pick a design and your AI tool rebuilds it with semantic adaptive colors handling light, dark, and a host theme at no cost.
Should I use semantic colors or two palettes for dark mode? Semantic colors: roles that resolve per appearance give one consistent system that adapts automatically, while two hardcoded palettes drift apart and are easy to get inconsistent.
Frequently asked questions
How do I build a Telegram-style color palette in SwiftUI?
Define semantic color roles like background, surface, label, and accent as adaptive colors that resolve per appearance, rather than maintaining two hardcoded light and dark palettes. For a Telegram Mini App, map those roles to Telegram's theme parameters so the app matches the user's theme. Build the palette from a free VP0 design.
What is the safest way to build theming with Claude Code or Cursor?
Start from a free VP0 design and define colors by semantic role using adaptive colors, so light and dark are one system, not two. For Telegram, read the host theme parameters and map them to your roles, test both appearances for contrast, and never hardcode raw colors in views.
Can VP0 provide a free SwiftUI or React Native template with theming?
Yes. VP0 is a free iOS design library for AI builders. Pick a design, copy its link, and your AI tool rebuilds it using semantic, adaptive colors that handle light, dark, and a host theme at no cost.
Should I use semantic colors or two palettes for dark mode?
Semantic colors. Defining colors by role, with each role resolving to the right value per appearance, gives you one consistent system that adapts automatically. Two hardcoded palettes you toggle between drift apart over time and are easy to get inconsistent, so prefer adaptive, role-based colors.
Part of the Web3, Telegram Mini-Apps & Crypto UI hub. Browse all VP0 topics →
Keep reading
Firebase iOS Auth Login With Dark Mode (Free SwiftUI)
Build a Firebase auth login screen in SwiftUI with proper dark mode: email, social sign-in, and Sign in with Apple, from a free VP0 design.
App Tracking Transparency Prompt UI in SwiftUI
How to do the App Tracking Transparency prompt right in SwiftUI: prime it in context, ask at the correct moment, and keep the app working when the user says no.
iOS Address Autocomplete: Google Places or Free MapKit
How to build an address autocomplete UI for iOS with the Google Places API, plus MKLocalSearchCompleter, the free native alternative built into MapKit.
Build a Language Learning App Like Duolingo in SwiftUI
A free SwiftUI pattern for a language learning app: a lesson path, exercise types, spaced repetition, and forgiving streaks. Learn the pattern, not the brand.
Native In-App Purchases in SwiftUI Without RevenueCat
How to build in-app purchases in SwiftUI with StoreKit 2 directly, no RevenueCat: the tradeoffs, the compliance rules, and what you own server-side.
Headless Shopify Mobile App in SwiftUI
A free SwiftUI pattern for a headless Shopify app: drive your own native storefront with the Storefront API, then hand checkout to Shopify and Apple Pay.