- Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS. fix(theme): adapt custom styles to dark mode via design tokens - Add useEffect in App.tsx to set data-theme attribute on documentElement (also toggles html.dark class) so CSS rules can use [data-theme='dark'] selectors and Ant Design's darkAlgorithm can fully cascade. - Replace hardcoded rgba(0,0,0,*) colors in Dashboard.tsx with Ant Design tokens via theme.useToken(): - ProcessUsageWall: colorTextSecondary (was rgba 0.45), colorTextDisabled (was rgba 0.35), colorBorderSecondary (was rgba 0.06), colorFillQuaternary (was rgba 0.02 header bg), HIGH/MED/LOW usage colors now use colorError / colorWarning / colorSuccess tokens. - Statistic valueStyles and Progress trailColor also token-based. - Login.tsx: replace isDark ternary '#141414' / '#f5f5f5' with token.colorBgLayout (single source of truth, auto-adapts). - Logs.tsx: replace '#888' timestamp color with token.colorTextTertiary. - Sidebar.tsx: replace hardcoded rgba(5,5,5,0.06) logout divider border with var(--ant-color-border-secondary, ...) CSS variable fallback chain. - responsive.css: add dark variants for .app-bottom-nav box-shadow and .app-header-bar border so sticky surfaces stay readable in dark mode. - Delete dead hooks/useTheme.ts (never imported; the data-theme attribute is now set centrally by App.tsx). Tested: build PASS, lint 0 errors (42 pre-existing warnings unchanged), unit tests 16/16 PASS.
3m-ui
Languages / 语言: README · English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Español · Français · Deutsch · Русский · Português (Brasil) · Tiếng Việt · Bahasa Indonesia · ไทย · Türkçe · العربية · हिन्दी · Polski · Українська
Mihomo server web management panel
Stable first: install and update use formal releases by default. Pre-releases require an explicit choice. Full bundles and Docker images ship a pinned Mihomo core — see installation docs.
Lightweight and self-hosted. Manage Mihomo listeners, users, subscriptions, and runtime status on Linux.
Documentation: https://3m-ui.top/docs/ · Website
Features
| Area | Capabilities |
|---|---|
| Nodes | Protocol-registry listeners (VLESS / VMess / Trojan / Shadowsocks / Hysteria2 / TUIC / AnyTLS / Snell / ShadowQUIC, …); REALITY target scan; TLS self-signed certs; transport field validation |
| Users | Bind nodes, traffic/expiry, IP/HWID limits, start-on-first-use, cycle renew/reset, groups/tags, external sub merge, batch ops, subscription tokens |
| Subscriptions | UA routing for Clash/Mihomo YAML, v2ray Base64, sing-box JSON; optional ?target=; HTML info page |
| Config | Generate → validate → apply; rollback previous config.yaml on failure |
| Ops | Core start/stop/update, logs, dashboard, online connections, Geo, panel SSL/ACME, WARP one-click, backup/restore |
| Telegram | Alerts and bot commands (token + chat IDs) |
| Cluster | Register remote panels, health checks, node mirror sync, merged subscriptions |
Install
curl -fsSL https://raw.githubusercontent.com/kazeyukiro/3m-ui/main/scripts/install.sh | sudo sh
After install, update with:
sudo 3m-ui update
# sudo 3m-ui update v1.0.2
Default panel: http://SERVER_IP:8080/ — user admin, one-time random password printed at install (change on first login).
Install with an AI assistant prompt
Copy the prompt into ChatGPT / Claude / Cursor (and state your OS, e.g. Ubuntu 22.04, and whether you have root SSH). The assistant should only use the official installer — not rewrite URLs or invent third-party commands. The full prompt and usage notes live in the AI install prompt doc.
Skip manual copy-paste — load the plain-text prompt straight to your clipboard with curl:
curl -fsSL https://raw.githubusercontent.com/kazeyukiro/3m-ui/main/docs/ai-install-prompt.en.txt | pbcopy # macOS
curl -fsSL https://raw.githubusercontent.com/kazeyukiro/3m-ui/main/docs/ai-install-prompt.en.txt | xclip -sel clip # Linux X11
curl -fsSL https://raw.githubusercontent.com/kazeyukiro/3m-ui/main/docs/ai-install-prompt.en.txt | wl-copy # Linux Wayland
The prompt only ever runs the official one-liner below; all downloads verify SHA256SUMS:
curl -fsSL https://raw.githubusercontent.com/kazeyukiro/3m-ui/main/scripts/install.sh | sudo sh
For the optional pre-release / test channel, see installation docs.
Build from source
cd frontend && npm install && npm run build
cp -r dist ../backend/cmd/server/web/dist
cd ../backend && CGO_ENABLED=0 go build -tags sqlite_modernc -trimpath -ldflags='-s -w' -o ../3m-ui ./cmd/server
Static Linux binaries for multiple architectures are on Releases.
Acknowledgements
- Mihomo — core engine and listener model
- clashmeta-inbound — listener examples
- 3x-ui / s-ui — panel UX inspiration
- Gin, GORM, React, Ant Design, Zustand, golang-jwt/jwt
- Go, Node.js, and the open-source community
Contributors: Contributors
Star History
License
Third-party notices: THIRD-PARTY-NOTICES.md.
