meow-rs: a Rust rewrite of the Clash Meta proxy kernel
A high-performance Rust implementation of the mihomo (Clash Meta) proxy kernel.
At a glance
- What is it?
- meow-rs is a Rust implementation of the mihomo proxy kernel with rule-based tunnelling, a dozen outbound protocols, ECH and uTLS fingerprinting, and two additions mihomo does not have: a logbook that survives restarts and dialer-proxy chains that keep working when a group member cannot reach the chained server.
- Who is it for?
- meow-rs fits an operator who wants the mihomo rule and provider model in a Rust implementation with a smaller and faster core, and it fits anyone whose chained proxies keep dropping because the front hop is chosen by latency rather than by whether it can actually reach the target. It does not fit someone who wants a desktop client, since this is the kernel and its configuration format is the mihomo one, with a REST API and a web dashboard rather than a user interface.
- 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 Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What it is and what it adds to mihomo
meow-rs is a high-performance Rust implementation of the mihomo, or Clash Meta, proxy kernel, with rule-based tunnelling, support for multiple proxy protocols, transparent proxy, DNS snooping, a persistent logbook, a REST API and a built-in web dashboard. The two extensions beyond mihomo are specific and both come from the same place, operational frustration with a chained proxy setup. The first is that meow keeps dialer-proxy chains working when a member of the dialer group can pass its URL test but not reach the chained server. The second is a logbook of what the engine did, covering reloads, provider failures, crashes and chained nodes going down, and it survives restarts. The project describes the logbook as a meow extension and says mihomo has none, and the naming borrows from Surge's Logbook.
The outbound protocols, and BoringSSL everywhere
The protocol list is long and each entry has detail worth knowing. Shadowsocks does TCP and UDP relay with AEAD and stream ciphers. Trojan is TLS 1.2 or 1.3 with SNI and an optional skip-cert-verify. Hysteria2 is a QUIC-based TCP and UDP relay with Salamander obfuscation, port hopping, a down bandwidth auth hint, SNI, skip-cert-verify and certificate pinning. VLESS covers plain VLESS and the XTLS-Vision splice over TLS with WebSocket, gRPC, H2 and HTTPUpgrade transports. VMess is AEAD with TCP and WebSocket, HTTP is a CONNECT outbound with optional TLS and basic auth, and SOCKS5 is an outbound proxy with optional TLS and auth. Snell covers versions three through six with UDP over TCP and optional HTTP or TLS obfuscation, and AnyTLS is a separate outbound. Direct and Reject round out the list, with Reject dropping connections under configurable behaviour. The crypto story is the strictest part. BoringSSL is the single crypto library for the whole application, and every proxy handshake, health check, DoT or DoH upstream, internal HTTP or HTTPS fetch including the uTLS fingerprints and ECH, and the Hysteria2 QUIC transport link one vendored BoringSSL, with rustls not used at runtime at all.
Privacy features: ECH and uTLS fingerprinting
Two features in the TLS and privacy section are about not being recognised. Encrypted Client Hello is implemented with DNS-based ECH config fetching from HTTPS and SVCB records, using the BoringSSL backend behind a boring-tls feature flag. uTLS fingerprinting offers Chrome, Firefox, Safari, iOS, Android and Edge profiles to bypass TLS fingerprint detection, which is the mechanism where a client presents a handshake that does not look like the browser it claims to be. Both are built on the same vendored BoringSSL rather than on a separate TLS stack, which is consistent with the rule that rustls is not used at runtime. The security trade-off is worth stating plainly, because uTLS fingerprinting exists to defeat a detection system, and the ECH implementation exists to hide a server name from a network observer.
Dialer-proxy chains, and the failure they hit
The dialer-proxy feature is mihomo compatible and dials a node's own connection through another proxy or group, for example to reach your own server through an airport node. The configuration looks like this.
proxies:
- name: home
type: snell
server: home.example.com
port: 8443
psk: "your-psk"
version: 4
dialer-proxy: fast # reach home's server through a member of `fast`
proxy-groups:
- name: fast
type: url-test
proxies: [hk-01, hk-02, jp-01]
url: http://www.gstatic.com/generate_204
interval: 300The problem meow solves is specific. A member of a url-test, fallback or load-balance dialer group can pass the group's URL test and still be unable to reach the home server, for example when an airport's audit rules drop the port. meow notices when two chains in a row through that member close before any reply, and probes the chain itself after each health check, then routes the chain around the member until it works again, while the group's other traffic keeps its normal pick. This is on by default, with no configuration, and the project says there is no mihomo equivalent.
The rest of the chain behaviour
The other chain behaviours are worth knowing because they change which node carries your traffic. A chained node stays in its group, so with home first in a fallback group a failing front hop no longer moves traffic off home. A url-test dialer group keeps home's chains on the member that last carried them instead of following its fastest member, and a health check of home that fails is checked again through up to three other members before home counts as down, and a member refusing the connection counts against that member rather than against home. Traffic is accounted per hop, so GET /statistics credits the group member that carries the front hop for both TCP and UDP, meaning the node in the middle of a chain shows its traffic too, while the totals still count each connection once. With connection-notes turned on, GET /connections/{id} shows which member carried the chain, one note per hop when chains nest. UDP through chains rides the front proxy's own UDP relay for Shadowsocks UDP, SOCKS5 UDP ASSOCIATE and domain targets, and a front without UDP fails the dial instead of leaking around the chain. The same dialer-proxy field works on proxy-provider nodes, following mihomo's precedence.
The logbook, and what it does not record
The logbook keeps the engine events worth reading later, where /logs only streams to a client connected at the time. It records starts and stops along with runs that ended without a clean stop, a crash, a kill or a power cut. It records config reloads and API edits, with the error when a reload is rejected, and subscription, proxy-provider, rule-provider and geodata updates with their failures. It records listeners that did not start, outbound interface changes, and dialer-proxy chains moving to another member or chained nodes going down. Repeats of a failure fold into one entry with a count, so a provider that fails every minute for a day is one entry with a count of 1440. Entries live in an SQLite database under the home directory for seven days, up to 2 MiB, and survive restarts and crashes. You can query it over HTTP.
# The 20 newest warnings and errors
curl 'http://127.0.0.1:9090/logbook?level=warning&limit=20'The endpoint filters by level, kind and subject, pages back with a before parameter and polls with since, and a client application in another process can read the database directly. Two limits are stated. The logbook never records where user traffic goes, and it records rule edits by index rather than by rule text.
The crate layout, the proxy groups and the build
The workspace is split into fourteen crates, and the names map onto the layers of a proxy core. There is meow-common, meow-trie for the routing structure, meow-anytls, meow-lwip for the network stack, meow-dns, meow-rules, meow-transport, meow-proxy, meow-tunnel, meow-listener, meow-api, meow-config, meow-app and meow-bench. The proxy group types are the familiar set. Selector gives manual selection over the REST API or web UI, URLTest picks automatically by latency with a tolerance threshold, Fallback fails over to the first alive proxy, LoadBalance distributes by round robin or consistent hashing, and Relay chains through multiple hops. The release profile is tuned for size and speed, with link time optimisation on, stripping, one codegen unit, panic set to abort and the optimisation level at z, and a separate dhat profile keeps debug symbols for heap profiling with lint, no stripping and no link time optimisation. The project also runs a workspace clippy configuration with a long list of denied lints, and the comments explain that the allocation-focused ones are warnings because the fixes land later.
Editorial conclusion
meow-rs fits an operator who wants the mihomo rule and provider model in a Rust implementation with a smaller and faster core, and it fits anyone whose chained proxies keep dropping because the front hop is chosen by latency rather than by whether it can actually reach the target. It does not fit someone who wants a desktop client, since this is the kernel and its configuration format is the mihomo one, with a REST API and a web dashboard rather than a user interface. It also does not fit a deployment that cannot accept a BoringSSL-only crypto stack, because the project states that rustls is not used at runtime at all. Before you deploy, read the dialer-proxy section for the exact chaining semantics, decide between the full and minimal builds depending on whether you want the logbook, and expect the release binaries to be tagged closely since v0.24.0 and v0.25.0 landed within two days.
Frequently asked questions
What is meow-rs and how does it relate to mihomo?
It is a high-performance Rust implementation of the mihomo, or Clash Meta, proxy kernel, with rule-based tunnelling, transparent proxy, DNS snooping, a REST API and a web dashboard. It adds two things mihomo does not have: dialer-proxy chains that keep working when a group member cannot reach the chained server, and a persistent logbook that survives restarts.
Which crypto library does meow-rs use?
BoringSSL is the single crypto library for the whole application, and every proxy handshake, health check, DoT and DoH upstream, internal HTTP and HTTPS fetch including the uTLS fingerprints and ECH, and the Hysteria2 QUIC transport link one vendored BoringSSL. The project states that rustls is not used at runtime at all.
How does meow-rs handle a dialer-proxy chain that stops working?
A member of a url-test, fallback or load-balance dialer group can pass the group's URL test and still fail to reach the chained server. meow detects when two chains in a row through that member close before any reply, probes the chain itself after each health check, and routes the chain around the member until it works, while the rest of the group keeps its normal pick. This is on by default with no configuration.
What does the meow-rs logbook record and how do I read it?
It records starts and stops, unclean exits, config reloads and API edits with rejection errors, subscription and provider update failures, listeners that did not start, and chain movements. Entries live in SQLite under the home directory for seven days, survive restarts, and are read with GET /logbook, which filters by level, kind and subject and pages with before or polls with since.
Official sources
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.
[](https://hysenlabs.com/projects/meow-rs-meow-rs)Was this useful?