Skip to content

[Feature]: Mobile: themes and custom themes — parity with the desktop theme system #6405

Description

@amanthanvi

Before submitting

  • 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/contractsClientSettingsSchema 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:

  1. 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.
  2. 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.
  3. 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.
  • OS-level dark-mode toggling only (no themes): solves the smallest pain (UI/UX Fix (broken app icon & no theme switcher) #5138's ask) but leaves the actual theme system desktop-only.

Risks or tradeoffs

  • 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.

Examples or references

Related issues:

Key code references:

  • apps/web/src/themePalette.ts (theme definitions, ThemeFile v1, 58 color roles, localStorage keys)
  • apps/web/src/components/settings/ThemeSettings.tsx (ThemeLibrary), ThemeEditorPanel.tsx, ThemeImportDialog.tsx, ThemeSearchSection.tsx, openVsxThemes.ts, vscodeThemeImport.ts
  • apps/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.ts

Screenshots (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 Appearance settings showing System/Light/Dark tiles, six theme cards, and Create theme / Import theme buttons

Web/desktop — theme editor ("Create theme") and the "Add a theme" import dialog with Open VSX search:

Web Create theme editor with name field, Light/Dark appearance, Background and Accent colors, and Advanced switch

Web Add a theme dialog with Open VSX community theme search, Dracula/Catppuccin/Nord/Tokyo Night suggestions, file drop, and theme JSON paste area

Web/desktop — a built-in theme (Ocean, dark) applied:

Web app with the Ocean dark theme applied showing navy surfaces and cyan accent

Mobile — the entire Appearance screen: typography only, no theme or light/dark/system controls (top and bottom):

Mobile Appearance screen top showing Text and Terminal font size controls only Mobile Appearance screen bottom showing Terminal and Code and Diffs font controls and Word break, with nothing else below

Contribution

  • I would be open to helping implement this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions