You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and did not find a duplicate.
I am describing a concrete problem or use case, not just a vague idea.
Area
apps/mobile
Problem or use case
Web/desktop now ships a full theme system (visible today in nightly desktop builds; it is ungated on main):
Built-in themes: T3 Code (default) plus T3 Chat, Grove, Ocean, Ember, Iris (apps/web/src/themePalette.ts), each with light and dark variants.
Appearance mode tiles (System / Light / Dark) orthogonal to theme choice, including per-appearance theme mixing (useTheme.ts, "pair model").
Custom themes: a guided/advanced theme editor (ThemeEditorPanel.tsx, 58 color roles), JSON import/export (ThemeFile v1 format), VS Code theme file conversion (vscodeThemeImport.ts), and Open VSX marketplace search ("try dracula, nord, catppuccin..." — ThemeSearchSection.tsx, openVsxThemes.ts).
The mobile app has none of it. Its Appearance screen (apps/mobile/src/features/settings/SettingsAppearanceRouteScreen.tsx) is typography-only — "Text" (Text size), "Terminal" (font size), "Code & Diffs" (font size, word break). There is:
no theme picker of any kind (zero references to the built-in theme ids anywhere in apps/mobile);
no custom theme support;
not even a light/dark/system override — mobile strictly follows the OS via useColorScheme(), with a hardcoded two-mode token set in apps/mobile/global.css (@variant dark).
So a user who has set up Ocean dark with a custom accent on desktop picks up their phone and gets the stock palette with no way to change anything. Theming is one of the most user-visible personalization features the product now has, and mobile is entirely left out.
There is also a structural blocker worth naming: the entire theme state lives in browser localStorage (t3code:theme, t3code:theme-appearance-mode, t3code:theme-halves:v1, t3code:themes:v1) and has no representation in packages/contracts — ClientSettingsSchema has appearance-adjacent keys (glassOpacity, font settings, …) but no theme/color-scheme/appearance-mode key. Nothing can sync to a native client even in principle today.
Proposed solution
Bring the theme system to mobile, staged:
Color scheme section on the mobile Appearance screen: an appearance-mode control (System / Light / Dark) and a built-in theme picker (the six cards web shows). The five built-in palettes are already defined as structured color roles in themePalette.ts; mobile needs a mapping from the core roles onto its uniwind CSS variables (apps/mobile/global.css, useThemeColor.ts) instead of the hardcoded light/dark token blocks. Device-local persistence via mobile-preferences.ts matches how mobile stores other prefs today.
Custom themes: accept the existing portable ThemeFile v1 JSON (import from file/paste, like web's "Add a theme" dialog). The parser (parseThemeFile) and OKLCH canonicalization already live in web code and could move to a shared package.
Sync: promote theme state (appearance mode, selected theme id, custom theme library) from web localStorage into ClientSettings in packages/contracts so all clients share one theme setup. This benefits web/desktop multi-device users too and is the natural end state, but items 1–2 don't have to wait for it.
Why this matters
Personalization is now a headline feature of the product on desktop (theme editor, VS Code import, Open VSX search), and prior demand for it was strong enough that several issues asked for exactly this before the web system shipped (#418, #1279, #1567 — all closed once web got themes). Mobile users currently can't even force dark mode independently of the OS. Cross-client visual consistency — same theme on desktop and phone — is the obvious expectation once themes exist at all.
Smallest useful scope
Item 1 only, minimal form: a light/dark/system override plus a picker over the five built-in themes (core color roles mapped; terminal/code accent roles can lag), stored device-locally. No editor, no import, no sync.
Alternatives considered
Waiting for full settings sync first: blocks indefinitely on contracts work that items 1–2 don't need.
The web palette has 58 color roles; mobile's token set is smaller. The mapping must pick sensible fallbacks (web already falls back to the flagship palette for omitted roles in custom themes — the same approach works).
Decorative sidebar artwork is built-in-theme-only on web (themeAllowsSidebarArtwork); mobile can simply skip artwork initially.
If sync (item 3) lands later, migrating device-local mobile theme prefs into synced client settings needs a one-time reconciliation.
Before submitting
Area
apps/mobile
Problem or use case
Web/desktop now ships a full theme system (visible today in nightly desktop builds; it is ungated on
main):apps/web/src/themePalette.ts), each with light and dark variants.useTheme.ts, "pair model").ThemeEditorPanel.tsx, 58 color roles), JSON import/export (ThemeFilev1 format), VS Code theme file conversion (vscodeThemeImport.ts), and Open VSX marketplace search ("try dracula, nord, catppuccin..." —ThemeSearchSection.tsx,openVsxThemes.ts).The mobile app has none of it. Its Appearance screen (
apps/mobile/src/features/settings/SettingsAppearanceRouteScreen.tsx) is typography-only — "Text" (Text size), "Terminal" (font size), "Code & Diffs" (font size, word break). There is:apps/mobile);useColorScheme(), with a hardcoded two-mode token set inapps/mobile/global.css(@variant dark).So a user who has set up Ocean dark with a custom accent on desktop picks up their phone and gets the stock palette with no way to change anything. Theming is one of the most user-visible personalization features the product now has, and mobile is entirely left out.
There is also a structural blocker worth naming: the entire theme state lives in browser
localStorage(t3code:theme,t3code:theme-appearance-mode,t3code:theme-halves:v1,t3code:themes:v1) and has no representation inpackages/contracts—ClientSettingsSchemahas appearance-adjacent keys (glassOpacity, font settings, …) but no theme/color-scheme/appearance-mode key. Nothing can sync to a native client even in principle today.Proposed solution
Bring the theme system to mobile, staged:
themePalette.ts; mobile needs a mapping from the core roles onto its uniwind CSS variables (apps/mobile/global.css,useThemeColor.ts) instead of the hardcoded light/dark token blocks. Device-local persistence viamobile-preferences.tsmatches how mobile stores other prefs today.ThemeFilev1 JSON (import from file/paste, like web's "Add a theme" dialog). The parser (parseThemeFile) and OKLCH canonicalization already live in web code and could move to a shared package.localStorageintoClientSettingsinpackages/contractsso all clients share one theme setup. This benefits web/desktop multi-device users too and is the natural end state, but items 1–2 don't have to wait for it.Why this matters
Personalization is now a headline feature of the product on desktop (theme editor, VS Code import, Open VSX search), and prior demand for it was strong enough that several issues asked for exactly this before the web system shipped (#418, #1279, #1567 — all closed once web got themes). Mobile users currently can't even force dark mode independently of the OS. Cross-client visual consistency — same theme on desktop and phone — is the obvious expectation once themes exist at all.
Smallest useful scope
Item 1 only, minimal form: a light/dark/system override plus a picker over the five built-in themes (core color roles mapped; terminal/code accent roles can lag), stored device-locally. No editor, no import, no sync.
Alternatives considered
Risks or tradeoffs
themeAllowsSidebarArtwork); mobile can simply skip artwork initially.Examples or references
Related issues:
Key code references:
apps/web/src/themePalette.ts(theme definitions,ThemeFilev1, 58 color roles, localStorage keys)apps/web/src/components/settings/ThemeSettings.tsx(ThemeLibrary),ThemeEditorPanel.tsx,ThemeImportDialog.tsx,ThemeSearchSection.tsx,openVsxThemes.ts,vscodeThemeImport.tsapps/web/src/hooks/useTheme.ts(appearance mode + theme mixing)packages/contracts/src/settings.ts(ClientSettingsSchema— no theme keys today)apps/mobile/src/features/settings/SettingsAppearanceRouteScreen.tsx,apps/mobile/global.css,apps/mobile/src/lib/useThemeColor.ts,apps/mobile/src/persistence/mobile-preferences.tsScreenshots (captured on current
main@ac1264e2c; web via local dev server at 1440×900, mobile via the iOS dev client on an iOS 26.5 simulator):Web/desktop — Settings → Appearance: mode tiles, theme cards (T3 Code, T3 Chat, Grove, Ocean, Ember, Iris), Create/Import theme:
Web/desktop — theme editor ("Create theme") and the "Add a theme" import dialog with Open VSX search:
Web/desktop — a built-in theme (Ocean, dark) applied:
Mobile — the entire Appearance screen: typography only, no theme or light/dark/system controls (top and bottom):
Contribution