Self-hosted service
MetaCubeX/metacubexd avatar
MetaCubeX/metacubexd

metacubexd: a web dashboard for a Mihomo (Clash Meta) kernel you already run

Mihomo Dashboard, The Official One, XD

4,441 stars532 forksTypeScriptMIT

At a glance

What is it?
metacubexd is the official web panel for Mihomo. It ships as a hosted static panel, a desktop app with a bundled kernel, and an all-in-one Docker server, and it keeps working as a pure panel against any remote mihomo.
Who is it for?
Adopt metacubexd if you already run a Mihomo kernel and want a maintained web UI for proxies, connections, rules and logs, or if you want the all-in-one Docker image to get a kernel and panel together on a router, NAS or VPS. Do not adopt it if you need a dashboard for a different proxy core, or if you cannot put the external controller behind a firewall and a strong secret, since the pure-panel mode assumes you expose that controller yourself.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap metacubexd fills between a Mihomo kernel and a browser

Mihomo is a proxy kernel. It exposes an external controller, which is an HTTP API, and it does not ship a user interface of its own. Everything you would normally want to do against a running kernel, switching the selected node in a proxy group, reading live traffic counters, closing a connection, grepping rules, tailing logs, has to go through that API. metacubexd is the official web dashboard for that API, written in TypeScript, and it is the panel the Mihomo project itself points at.

The audience is narrow and specific. It is for people who already have a mihomo process somewhere, on a VPS, a router, a NAS, or a laptop, and who want a browser-based view of it rather than a config file and a restart. The repository describes three deployment forms from one codebase, and the choice between them is really a question of who hosts the UI and who runs the kernel. In hosted panel mode, the official sites or your own static files serve the interface and your own remote mihomo does the work. In desktop mode, the app supervises a bundled mihomo. In all-in-one server mode, the Docker image carries both the UI and the kernel.

That split matters more than the feature list. A dashboard that talks to a remote kernel over the external controller is a thin client, and metacubexd is honest about it: the README states that kernel-control and profile features stay hidden when the dashboard is not talking to a bundled agent. So the same interface looks different depending on which of the three forms you picked.

How the panel, the kernel and the bundled agent talk to each other

The data flow is HTTP in both directions. You give the panel a URL and a secret, and it authenticates against the kernel's external controller. From there it reads and writes through that API: proxy group selection, latency tests, connection listings, rule search, and a live log stream. Nothing is proxied through a third party in hosted panel mode, because the browser talks to your kernel directly.

That direct connection is why CORS shows up as a real configuration topic rather than a footnote. When the panel is served from one origin and the controller lives on another, the kernel has to be told which origin is allowed. The README links to an external-controller-cors anchor in its own troubleshooting section, which tells you the maintainers treat this as the standard failure mode for self-hosting. If you load the panel from a static host and your kernel refuses the request, the answer is in that key, not in the panel.

The all-in-one Docker form changes the topology. Instead of a browser reaching out to a kernel you configured separately, the container runs a bundled mihomo plus an agent, and the image serves the UI. The README describes this as the form for a router, NAS or VPS. The desktop app is the third variant: it fetches a mihomo build and supervises it as a child process, which is why the build script for that target runs a fetch step before Electron is involved.

The monorepo layout reflects the three targets. There is an apps directory and a packages directory, a pnpm workspace, and separate filter targets for the UI, the server and the desktop app. The root package.json exposes dev:ui, dev:server and dev:desktop as distinct scripts, and the desktop script does two things the others do not: it fetches mihomo and ensures Electron is present before starting.

Installing metacubexd with Docker and pointing it at a kernel

The fastest path is the standalone panel container. It serves the interface on port 80 inside the container, mapped to 8080 on the host in the README example.

bash
docker run -d --name metacubexd -p 8080:80 ghcr.io/metacubex/metacubexd:latest
# Open http://localhost:8080

After that, the container is only a front end. You still need a mihomo instance with its external controller enabled, and the README shows the two keys to set in config.yaml:

yaml
external-controller: 0.0.0.0:9090
secret: 'replace-with-a-strong-secret'

Binding the controller to 0.0.0.0 publishes it on every interface, and the README says so directly, recommending a firewall, a strong secret, and external-controller-cors for the exact dashboard origin. In the browser you then enter the mihomo URL and secret. If the panel loads but cannot reach the kernel, CORS or the secret is the first thing to check.

If you would rather not run the pieces separately, the all-in-one compose file is the alternative. The README gives a curl for it and then a compose command:

bash
curl -O https://raw.githubusercontent.com/metacubex/metacubexd/main/docs/docker-compose.yml
# Edit .env with your secrets, then:
docker compose up -d

The comment in that snippet is the instruction: the environment file holds your secrets, and you edit it before bringing the stack up. This form bundles the kernel, so the kernel-control and profile features that stay hidden in pure-panel mode are available here.

There is also a static-asset route. The README shows cloning the prebuilt gh-pages branch if you want to serve the files yourself, and it names external-ui as the mihomo setting for hosting a dashboard from the kernel side. For development, the root package.json defines a dev:ui script that runs the UI package directly, and dev:server builds the UI first and then starts the server package.

What metacubexd does not do, and when it is the wrong tool

The clearest limitation comes from the project's own description of its modes. Against a remote kernel with no bundled agent, kernel-control and profile features are hidden. If your workflow depends on editing profiles or restarting the kernel from the dashboard, the hosted panel pointed at someone else's mihomo is the wrong configuration, and you want either the desktop app or the all-in-one container.

The second limitation is the exposure model. The panel authenticates with a secret against an HTTP API. The README's own example binds the controller to 0.0.0.0:9090, which is convenient and also the reason it immediately follows with firewall and CORS advice. Anyone who can reach that port and knows the secret has the same control the dashboard has. If you cannot restrict network access to the controller, the dashboard is not the weak point, your deployment is.

Third, it is a Mihomo dashboard. The name, the topics and the README all tie it to the Mihomo kernel and its API. Pointing it at a different proxy core is not a supported path, and the feature set is shaped around what that kernel exposes. If you run something else, this is not the panel for you regardless of how the UI looks.

Finally, the browser is now in the loop. A dashboard that streams logs and refreshes connection state is another thing that can be slow or unreachable, and the README does not document a rollback or a degraded mode for when the panel itself fails. The kernel keeps proxying either way, but your visibility into it does not.

metacubexd against a terminal client or a hand-rolled API script

The realistic alternative is not another dashboard, it is skipping the dashboard. The mihomo external controller is an HTTP API, so anything the panel does can be done with curl or a short script: list proxies, switch a selection, close a connection, read the log stream. That approach has real advantages. It fits into automation, it produces diffs you can review, and it adds no long-running process.

The difference in approach is state versus one-shot commands. A script answers a question and exits. metacubexd keeps a live view: traffic counters that update, a proxy group with latency numbers you can compare at a glance, a connection table you can sort and act on, and a log view that follows the stream. For interactive troubleshooting on a machine you are already looking at, that is a different job than a script, and it is the job the panel was built for.

The trade-off is operational surface. A script needs no port, no CORS configuration, and no container. The panel needs all three, plus a secret you now have to manage in a browser. If your use of the kernel is mostly automated and you rarely inspect it by hand, the script wins on simplicity. If you find yourself reading logs and switching nodes several times a day, the panel earns its port.

Maintenance, releases and what the MIT licence leaves to you

The repository is not archived, and its last push was on 2026-09-22. Releases are frequent and versioned: v1.272.0 and v1.273.0 landed on 2026-08-15 and 2026-08-16, and v1.273.1 followed on 2026-09-10. The project uses release-please, with a manifest and a config file in the repository root, and commitlint plus husky and lint-staged are wired into the root package.json, so the release cadence is automated rather than manual. The monorepo version in package.json matches the latest release tag.

The upgrade cost depends on which form you run. The standalone panel container is a tag pull and a restart, and because it holds no kernel state, a bad version costs you the UI rather than the proxy. The all-in-one image is heavier: it carries a bundled kernel and an agent, so a version bump can change kernel behaviour, and the README's compose path expects an .env file with your secrets that you keep across upgrades. The desktop app carries a fetched mihomo build, which means upgrading the app can also change the kernel you are running.

On licensing, the repository is MIT. That is permissive and short, and it is the whole of what the repository states. The MIT text says nothing about the licence of the mihomo kernel you pair with the panel, which is a separate project and a separate question. If you redistribute the all-in-one image or bundle the panel into a product, check the terms of every component you ship rather than assuming one licence covers the stack. This is not legal advice, and the LICENSE file in the repository is the authoritative text.

Editorial conclusion

Adopt metacubexd if you already run a Mihomo kernel and want a maintained web UI for proxies, connections, rules and logs, or if you want the all-in-one Docker image to get a kernel and panel together on a router, NAS or VPS. Do not adopt it if you need a dashboard for a different proxy core, or if you cannot put the external controller behind a firewall and a strong secret, since the pure-panel mode assumes you expose that controller yourself. Before deploying, verify that your mihomo build accepts external-controller-cors for the exact origin you will load the panel from, and check whether your deployment needs the bundled agent, because kernel-control and profile features stay hidden without it.

Frequently asked questions

What is mihomo?

Mihomo is the proxy kernel that metacubexd is built to control, referred to in the README as Clash Meta. It exposes an external controller HTTP API, which is what the dashboard connects to with a URL and a secret.

What is Clash Meta?

The README identifies Mihomo as Clash Meta in its opening description of the project. metacubexd is described there as the web dashboard for that kernel.

How do I run metacubexd with Docker?

The README gives a single command: docker run -d --name metacubexd -p 8080:80 ghcr.io/metacubex/metacubexd:latest, after which you open http://localhost:8080. For the all-in-one form that also bundles the kernel, the README points at a compose file fetched with curl and started with docker compose up -d after editing .env.

Why can the metacubexd panel not connect to my mihomo kernel?

The README treats this as a CORS problem when the panel is self-hosted, and links to the external-controller-cors setting for the exact dashboard origin. The other value to check is the secret, since the panel authenticates against the external controller with it.

Does metacubexd work against a remote mihomo, or does it need the bundled kernel?

The README states that the classic pure-panel mode still works against any remote mihomo. In that mode the kernel-control and profile features stay hidden, because the dashboard is not talking to a bundled agent.

Official sources

  1. License: MIT
  2. MetaCubeX/metacubexd on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/metacubex-metacubexd.svg)](https://hysenlabs.com/projects/metacubex-metacubexd)