Setup
How to choose a VLESS and Hysteria2 client in 2026: Xray, sing-box or Clash
Search results for 'best VLESS client' are mostly ranked lists, and the ranking is the least useful part of them. On any given platform the real shortlist is short, and the differences that decide it are structural: which core the app embeds, what it does with a subscription URL, and how much control it gives you over routing. Those three decide whether the app stays quiet for months or becomes something you re-import every week.
The client is not the service
A modern setup splits in two. The service runs the servers and issues a subscription URL. The client is a local app that fetches that URL, builds the tunnel and applies routing rules. Clients are free and usually open source; they hold no servers and sell nothing.
The split is worth holding on to, because it tells you where to look when something breaks. Throughput, latency and the exit address belong to the server side. What the client decides is whether your configuration is current, how quickly you find out that it is not, and how much traffic ends up in the tunnel that should not be there.
Which core the client runs
Most clients are a user interface wrapped around one of a few cores. The core sets the feature ceiling; the interface only decides how pleasant it is to reach that ceiling.
- Xray-core — VLESS, VMess, Trojan and Shadowsocks, with Reality and XHTTP as transports on top. It is the reference implementation of Reality, and Reality changes land here first. Background in the guide on how VLESS Reality works.
- sing-box — the same VLESS and Reality, plus Hysteria2, TUIC and ShadowTLS. Its configuration format and its rule-set files are its own, not Xray's. SagerNet publishes official apps for Android, iOS and macOS; Hiddify is a friendlier interface over the same core.
- mihomo, the continuation of the Clash.Meta line — a rule engine first, protocols second. Configuration is YAML, and the routing language is the reason people choose it. The Clash-family desktop and Android apps sit on top of it.
- The Hysteria client — the Hysteria2 protocol and nothing else. Rarely a daily driver, useful for testing a server in isolation when a general-purpose client will not say why it fails.
One core-level detail that clients expose unevenly is the TLS fingerprint. A Reality profile carries an fp= parameter — fp=chrome, fp=firefox and so on — and the core uses the uTLS library to send a ClientHello shaped like that browser's, so the handshake does not stand out as a proxy client at the JA3 or JA4 level. A core without uTLS ignores the parameter, and some interfaces do not let you set it at all. Treat it as a mitigation rather than a guarantee: a handshake can match a browser while everything else about the connection does not.
What a client does with a subscription link
A subscription URL is an HTTP endpoint that returns your node list. Two shapes are common: a base64 blob of one-line URIs (vless://, hy2://, ss://), or a complete configuration in a specific format such as sing-box JSON or Clash YAML. Many panels decide which to return by looking at the User-Agent of the request, which is why the same link can produce a full server list in one app and a partial one in another.
The differences worth checking before you settle on a client:
- Scheduled refresh, not only a manual button. Server addresses change. A client that refetches only when you tap it will keep serving a dead node list until you work out that the problem is not the network.
- Merge or overwrite. Some clients replace the whole profile on refresh, routing rules and per-node preferences included. Others update the node list and leave local settings alone. This is invisible until the first time it wipes something you set by hand.
- Header support. Panels commonly answer with
subscription-userinfo(upload, download, total, and expiry as a Unix timestamp) andprofile-update-interval(in hours) — de facto conventions from the Clash ecosystem that most panels now emit. A client that shows you remaining traffic and an expiry date is reading them; one that shows nothing is ignoring them. - Where the refresh itself goes. If the subscription host is only reachable through the tunnel, an update attempted while disconnected fails — and if the node list is already stale, that is a loop. Clients differ in whether they route their own fetch through the active tunnel or outside it.
- More than one subscription. Obvious if you run your own server next to a paid one. Not every mobile client supports it, and a few support it but apply routing rules from whichever profile loaded last.
What a routing profile actually does
A routing profile is the rule set that decides, per connection, whether traffic goes through the tunnel, goes direct, or is refused — plus which resolver answers which names. It carries no keys and no server list; those live in the subscription. It is the part most people never open and the part responsible for most of the strange behaviour.
- Domain rules — exact, suffix, keyword, regex. They need the client to know a hostname, and how it learns one depends on the mode. Through a local SOCKS or HTTP proxy the application hands the hostname over itself. In TUN mode the client sees an IP address, so it either sniffs the name out of the TLS handshake or the HTTP Host header, or maps it back from a fake-IP DNS answer. With sniffing off and fake-IP unused, domain rules match nothing and only address rules apply.
- Address and geo rules — Xray uses
geoip.datandgeosite.dat; sing-box uses its own rule-set files. Either way these are downloaded databases of a meaningful size, on their own update schedule. A partial or failed update is one of the ordinary reasons a profile stops matching anything at all. - Per-app rules — Android in practice. A VPN app there can include or exclude individual packages from the tunnel, and on Android 10 and later it can also ask the system which app owns a given connection. iOS exposes neither to third-party clients: per-app VPN exists, but as a managed-device feature that requires MDM. On an iPhone you route by domain and address, and that is the whole toolbox.
- DNS — which resolver serves which branch of the rules, and whether the lookup happens before or after the routing decision. Getting this wrong produces the confusing case where the tunnel is clearly up but certain names resolve to the wrong place.
- IPv6. If your network has native IPv6 and the tunnel carries IPv4 only, connections to v6 destinations can leave outside it. Clients differ in whether they pull IPv6 into the tunnel, blackhole it, or ignore the question — and the third option is the one that shows a real address on a leak test.
Without a profile, everything goes through the tunnel. That works, and for some people it is the right answer. It stops being the right answer when local services start seeing a foreign address: banking and government portals often respond to that with extra verification steps, and local content delivery gets slower because you are now fetching it from another continent.
iOS and Android
On iOS the binding constraint is the platform, not the software. Every client runs inside a Network Extension under the same operating-system limits, so what differs is the core, the interface, and whether the app is listed in your storefront at all. App Store availability is per-country: several VLESS clients are not listed in the Russian storefront, so an app that exists on paper may not be installable on a given Apple ID.
- Subscription-first clients — Happ, Streisand, V2Box and their like: built around a single link, with automatic refresh and, in some of them, support for a routing profile the provider supplies. Least configuration, and a reasonable default for a phone you would rather not think about.
- Core-first clients — the official sing-box app, or Hiddify for the same core with a friendlier front end. You can paste a full configuration and have it honoured as written. The right choice if you run your own server and already have a config you trust.
- Rule-engine clients — the Clash-family apps, and paid utilities such as Shadowrocket, where the rule editor is the product. Genuinely capable, and more machinery than a single subscription needs.
Android is looser: apps install from the store or from an APK, per-app routing works, and the same package usually runs on Android TV. v2rayNG exposes close to everything Xray-core accepts and hides nothing behind a friendly screen — plain, but when a node misbehaves you can see why. sing-box publishes its own Android app in the same spirit. Above those sit the subscription-first clients and the Clash-family apps.
Desktop and Linux
On Windows and macOS there is no store gate — clients install by direct download, and the split is the same as on mobile: thin interfaces over Xray, sing-box's own builds, Clash-family interfaces built around the rule engine, and cross-platform subscription-first apps.
The desktop-specific thing to check is how the client captures traffic. A TUN interface takes everything system-wide and needs elevated rights to create. A local SOCKS or HTTP proxy only affects applications that were told to use it. A client sitting in proxy mode is the usual explanation for 'the VPN is on, but this one program ignores it' — and for a leak test that comes back with your real address.
TUN mode brings a knob of its own: MTU. Set it too high for the path and small requests succeed while large transfers stall, because the oversized packets are dropped and the ICMP messages that path MTU discovery depends on are frequently filtered before they reach you. If a connection loads text pages but hangs on downloads, lower the MTU before you blame the server.
On Linux the honest answer is often no graphical client at all: sing-box or xray as a binary, a config file under /etc, and a systemd unit. sing-box publishes its own repositories; xray is usually a release binary or a third-party package. Either restarts cleanly and logs to the journal, and if you already administer servers that is less work than any desktop app. The trade-off is that subscription refresh becomes your job — a timer that fetches the URL, writes the config and reloads the service, with a check that the fetch actually returned a config before it overwrites a working one.
TV, routers and everything without an app store
Android TV runs the same packages as a phone, and the awkward part is input rather than compatibility: a TV has no camera, so the QR code that makes setup trivial on a phone is of no use. You type the subscription URL with the on-screen keyboard, use your phone as a remote keyboard, or paste it from the clipboard after getting it onto the device some other way. Apple TV gained third-party VPN support in tvOS 17, and a few clients ship a tvOS build. Samsung Tizen and LG webOS have no third-party clients at all; the realistic options there are a small Android box or moving the tunnel off the device entirely.
On a router the client is a package rather than an app: OpenWrt with sing-box or xray, configured over SSH or a web interface. Everything behind the router is covered without installing anything on individual devices, which is the only practical route for a game console or a smart TV. Two costs come with it. Routing rules now apply to the whole household from one place, and a consumer router's CPU is usually the throughput ceiling — encryption on a low-power SoC without crypto acceleration is where the bandwidth goes.
What choosing a client does not fix
- Speed and reachability. These come from the server, its route to you, and its load. The same node through two different clients performs about the same. The one real lever is transport choice, and that is a protocol decision rather than an app decision.
- Anonymity. A client changes which network address a service sees. It does not touch operating-system telemetry, device identifiers, or the fact that you are signed in to your own accounts. That distinction is the whole subject of why a VPN is not anonymity.
- Leaks that come from configuration. DNS, IPv6 and WebRTC leaks are a property of your rules and your browser, not of an app's reputation. Re-test after any change to routing instead of assuming a well-regarded client makes them impossible.
- Rules that are not technical. Where a platform restriction is contractual or legal rather than a matter of routing, no client changes it. A different address changes what the network sees, not what an account is permitted to do.
- Trust. The client sees all of your traffic before it enters the tunnel. That is the argument for open source, reproducible builds and binaries you can trace back to a repository — and the argument against anything carrying an advertising SDK.
The short version: pick by core and by subscription handling, then check that routing does what you expect on your platform. Everything else on a comparison table is decoration.
Frequently asked questions
Which VLESS client is the fastest?
For practical purposes, none of them. The overhead a core adds is small next to the server's location, its route to you and how loaded it is, and the same node measured through two clients lands in the same range. Where you can gain something is the transport: a TCP-based profile and a UDP-based one behave differently on a lossy mobile link, and any client that carries both lets you test that in a couple of taps.
Can I use one subscription link in several clients at once?
The link itself is universal — it is an HTTP endpoint, and any client that understands the format can read it. What is usually limited is the number of simultaneous connections per subscription, which is a service-side setting rather than a client feature. Importing the same link on a laptop and a phone is normal; running it on ten devices at once may not be, and the limit is worth checking before you plan around it.
Why does the same subscription show fewer servers in one app than in another?
Two common causes. Panels often vary the response by User-Agent, so a client identifying itself differently receives a different list. And a client drops entries whose protocol its core does not implement, usually without saying so — a Hysteria2 node will not appear in a client whose core is Xray only. If a server is missing, compare the raw response from the subscription URL against what the app displays.
Do I need a routing profile at all?
No, and plenty of people run without one. The cost is that local services also reach you from the exit address, and the symptoms are indirect: an extra verification step on a site that never asked for one before, or a video that buffers because it is now being served from another continent. If you have no rules and something local starts behaving oddly, that is the first thing to suspect.
Should I use the client my provider recommends or a general one?
Either works, since the subscription format is not proprietary. The practical difference is the routing profile: a provider that ships one has already decided what goes direct, and a general client will either accept that profile or fall back to sending everything through the tunnel. If you prefer to write your own rules, a core-first client gives you more room and expects more from you.