Most GUI clients already come with a graphical interface, but if you want a clearer view of live connections, per-connection traffic, and latency curves, connecting a web dashboard is much easier than scrolling through logs. The entry point for all of this is external-controller.

Enabling external-controller

This starts a local RESTful API service — the web dashboard reads the core's live state through this interface and has nothing to do with actual traffic forwarding.

external-controller: 127.0.0.1:9090 secret: "set an access secret here"
If you change the external-controller listen address to 0.0.0.0 so other devices on your LAN can access it, make sure to also set a secret — otherwise anyone who can reach that port can read or even modify your proxy config.

external-ui: a built-in static dashboard

Some cores support an external-ui field pointing at a packaged static dashboard directory, so visiting http://127.0.0.1:9090/ui opens the dashboard directly — no extra deployment needed.

external-ui: ./ui

What the dashboard shows

PanelContent
ProxiesAll nodes and proxy groups — view, manually switch, or trigger a speed test
ConnectionsAll active connections: destination, node used, data used, connection duration
LogsLive log stream — rule matches, connection open/close events
RulesAll currently loaded rules and rule sets, handy for checking match order
TrafficLive upload/download rate chart — a quick view of current bandwidth usage

Choosing a dashboard project

The open-source community offers several mature web dashboard projects you can connect directly. They're generally plain static front-end pages, and deployment is simple: download the packaged static assets, point external-ui at that directory, or just open the corresponding hosted online version in your browser and enter your external-controller address and secret to connect. When choosing one, focus on two things: whether the interface is clear and intuitive, and whether it supports the API fields of the core version you're running (different core branches occasionally diverge in their API, and an outdated dashboard version may not display everything correctly).

Hardening dashboard access

  • Always set a secret: even if you only ever access it on 127.0.0.1, getting into the habit avoids leaving a hole open if you later change the listen address without thinking.
  • Don't expose the control port to the public internet: if you genuinely need remote access, forward it through an SSH tunnel or VPN rather than binding external-controller directly to a public IP.
  • Vet where your dashboard comes from: stick to dashboards from official repos or well-known open-source projects, and avoid third-party builds of unknown origin.

Can you use the dashboard from your phone

Yes — the mechanics are identical. As long as your phone and the device running Clash are on the same LAN, open http://the-core-device's-LAN-IP:9090/ui in your phone's browser (after setting external-controller to listen on 0.0.0.0 with a secret) to reach the same dashboard. A lot of people use this as a lightweight "remote control" for the core: run it on a computer, monitor connections and traffic from a phone, without switching devices back and forth.

Using the dashboard to troubleshoot

  1. A site is slow or unreachable: find the connection in Connections, check which node it's using, then test that node's latency on its own.
  2. Suspect a rule mismatch: turn on the rule-match log level in Logs and watch in real time which rule a domain actually hits.
  3. Traffic usage seems unusually high: sort Connections by traffic to quickly pinpoint which connection/process is consuming bandwidth.
If your client doesn't have a built-in dashboard entry point, you can also open one of the common open-source web dashboard projects directly in a browser and enter your external-controller address and secret to connect.

How is the dashboard different from the client's built-in UI

A lot of people wonder: the client already has a graphical interface, so why bother with a separate web dashboard? The two actually serve different purposes. A client's built-in UI is usually heavily simplified, surfacing the most common day-to-day actions ("one-click connect," "quick node switch") while hiding most of the underlying detail. External Controller + a web dashboard, on the other hand, exposes the core's raw running state — more fields, more real-time updates, and it also supports building on top of the API (say, a script that polls traffic data on a schedule for your own stats). For everyday use, the client's own UI is plenty; a dashboard is only really necessary when you need deeper troubleshooting or automated monitoring.

Simple automated monitoring via the API

External Controller exposes a standard RESTful API, meaning you're not limited to viewing it through an existing web dashboard — you can also write your own script to poll the API on a schedule, log traffic data for long-term stats, or trigger a notification when a node shows repeated failures. This is an advanced use case, not a requirement, but if you want finer-grained visibility into your own network usage, it's worth exploring — and it's a lot less tedious than repeatedly opening the dashboard by hand.

Sharing one dashboard across multiple devices

If you have several devices at home (computer, router, NAS) each running its own Clash instance, you can in principle give each instance its own external-controller port and use the same dashboard project, just switching the connection address to view each one — no need to deploy a separate dashboard per instance. This "one dashboard, multiple instances" pattern is common in setups with a router running as a bypass gateway or multiple node deployments.

Summary

External Controller is essentially an "observability" interface the core exposes — getting connection-level detail doesn't cost any extra performance. Paired with a dashboard, vague concerns like "does it feel slower" or "am I on the wrong node" turn into something you can actually observe and verify directly.