Xray vs. V2Fly Core: Protocol Support, Config Compatibility, and Which to Choose

Compare Xray and V2Fly support for VLESS and REALITY, config compatibility, and release cadence to choose the right core for your setup.

At a glance

When choosing a core, start by checking the protocols, transport, and security layer your node requires. Then make sure your client can generate a valid config. This guide is for v2rayN users and anyone choosing v2rayNG or v2flyNG for Android. It explains what REALITY and Vision depend on, why configs from the two cores aren't interchangeable, and how to keep a working setup you can roll back to when switching cores.

Know the difference between the client, core, and server

v2rayN is a desktop GUI client for managing subscriptions, editing nodes, toggling the proxy, and generating configs. Xray-core and V2Fly's V2Ray handle the actual connections. A client window opening normally doesn't mean the core started successfully, and a node appearing in the list doesn't mean the active core supports all its fields.

Parse subscription Generate config Load core Match routing rules Complete remote handshake

Xray and V2Fly share some technical history, but they have evolved along separate paths. Xray isn't simply a newer V2Ray that can replace it in every situation. Likewise, seeing inbounds and outbounds in both configs doesn't mean they're fully compatible.

Protocol support: don't judge by VLESS or VMess alone

A node's full requirements usually depend on its proxy protocol, transport, and security layer. VLESS is a proxy protocol, WebSocket is a transport, TLS and REALITY provide connection security, and Vision is a flow-control mode used by Xray in specific setups. These belong to different layers and aren't interchangeable.

Node requirementXrayV2FlyWhat to check before choosing
VMess + WebSocket + TLSCommonly supported combinationsCommonly supported combinationsAuthentication settings, path, Host, and TLS server name
Basic VLESS protocolSupported, with additional Xray-specific capabilitiesRelated implementations exist in some versions or config formats; check the version in useThe VLESS name alone doesn't guarantee full compatibility
VLESS + REALITYA typical Xray use caseXray REALITY configs can't be used as-isPublic key, server name, short ID, and transport requirements
xtls-rprx-visionRequires a compatible Xray version and combinationDoesn't support this Xray flow valueWhether the server explicitly requires this flow
Local SOCKS / HTTP inboundCommon local proxy inbounds are supportedCommon local proxy inbounds are supportedListen address, port, and app proxy settings

In particular, avoid reducing the question of V2Fly support for VLESS to a blanket claim with no version context. Troubleshoot the binary, config format, and node requirements you're actually using. But if the subscription explicitly includes security=reality or flow=xtls-rprx-vision, don't pass it off as a basic VLESS node for V2Fly to run.

Bottom line: choose a core that supports your node

If a node explicitly requires REALITY or Vision, use an Xray setup that supports that combination. If your VMess + WebSocket + TLS nodes already work reliably, there's no need to rebuild their configs just to change the core name.

Config compatibility: parsing JSON doesn't mean a connection will work

The two config formats may contain similarly named fields, but field placement, accepted values, and runtime behavior can differ. V2Fly also has multiple config formats that shouldn't be treated as interchangeable. A complete client-generated config usually includes DNS, routing, and local inbounds, so copying a single outbound object isn't a complete migration.

The two cards below show parameter combinations to check one by one. They aren't ready-to-import nodes and don't include a server address or authentication details. The WebSocket path /ws is only an example; use the value set on the server.

VLESS + REALITY + Vision

Protocol
VLESS
Transport
TCP; the label may vary by version
Security layer
REALITY
Flow
xtls-rprx-vision
What to verify
Server name, public key, short ID

This combination requires the relevant Xray capabilities. Don't try to make it work with another core by deleting security fields.

VMess + WebSocket + TLS

Protocol
VMess
Transport
WebSocket
Example path
/ws
Security layer
TLS
What to verify
UUID, Host, server name

Both cores are commonly used with this combination, but each requires fields to be generated in its own config format.

Subscription imports and split routing: recheck after switching

A subscription URL is a way to distribute nodes; it isn't the core that runs them. A successful subscription update only confirms that some download and parsing steps completed. Depending on the client version, unrecognized fields may be ignored or the corresponding outbound may not be generated. After the node count increases, open the node editor and verify its key settings.

  1. Keep the original group: Export essential settings and save the subscription URL somewhere safe. Test in a new group instead of overwriting your only working config.
  2. Check the import: Compare the result with the provider's instructions. Verify the protocol, port, transport, security layer, and flow. For REALITY nodes, also check the public key, server name, and short ID.
  3. Confirm the active core: Restart the connection and check the log for the core identity, startup errors, and listener details. Changing a node's display name won't switch cores.
  4. Test outbound connections separately: First check whether the selected node can reach a test destination. Then verify that direct and proxied domains match the expected routing rules.

Split routing depends on rule order, DNS resolution strategy, domain and IP rule data, and sniffing settings. If two tests use different rule files or DNS settings, you can't attribute the results directly to Xray or V2Fly. System proxy and TUN mode also cover different traffic, so keep the traffic capture method the same when testing cores.

Local port and handshake errors: identify the failing stage

“No internet after switching” isn't enough to tell whether one core is better. First distinguish a core startup failure from an unavailable local inbound or a failed remote handshake. This is usually more useful than repeatedly switching nodes. The numbers below illustrate the connection flow; they aren't defaults for every client.

127.0.0.1
Example local loopback listen address
10808
Example local proxy listen port
443
Example remote server port
Log message or symptomCheck firstNext step
unknown field or config load failureField placement, config format, and core versionHave the current client regenerate the config; don't blindly delete unknown fields
address already in useWhether the local listen port is already in useStop duplicate proxy processes, or use matching listen and app ports
connection refusedWhether the error points to a local or remote addressCheck the local listener first, then confirm the remote service is open on the correct port
Certificate name mismatchTLS server name, certificate, and system clockCorrect the name and system time; don't routinely disable certificate verification
Handshake failure or connection timeoutProtocol settings and network reachabilityVerify the settings, then check network access; an error phrase alone doesn't identify the cause

For example, if an app's connection to 127.0.0.1:10808 is refused, first check whether the core is listening at that address. There's no need to immediately suspect remote port 443. If the local inbound works but the log shows a remote handshake failure, check the UUID, server name, and security settings. The two stages call for completely different troubleshooting steps.

Release cadence and performance: change one variable at a time

Xray and V2Fly maintain separate release histories. Their version numbers can't be compared directly, and release dates alone won't tell you which is better for your node. Usability also depends on whether the GUI client supports the newer fields, whether the bundled core is compatible, and whether the server uses the corresponding features.

Performance depends on the environment, too. Network congestion, server load, transport, DNS, and routing can all affect speed tests. Testing different protocols on different routes doesn't show that one core is consistently faster by a specific amount.

  1. Set a baseline: Record the actual client and core versions, node settings, proxy mode, and routing config. Keep the current working installer and a config backup.
  2. Control variables: Compare only the same protocol combination supported by both cores, using the same server, test destination, and traffic capture method.
  3. Repeat the tests: Run each setup at least 3 times under the same conditions. Record connection success, response time, and sustained transfer performance instead of relying on a single latency reading.
  4. Review the release notes: Check whether the new version addresses an issue relevant to your setup. After upgrading, recheck startup logs, DNS, direct access, and proxy access.

Bottom line: keep a rollback option before testing an upgrade

Upgrading only the client or replacing only the core can leave config generation and runtime capabilities out of sync. Check the client's documented support first, then test with a backup in place. If something breaks, restore a known-working combination instead of changing several settings at once.

Choose by node requirements: three common scenarios

Choose a core based on what your current nodes need and what your client can generate correctly. There's no need to replace every device just to standardize the core name, nor should you stick with an old config when the server's connection requirements have changed.

A good setup has a core that starts normally, complete node settings, a working connection to the destination, and routing that behaves as expected. Once those conditions are met, weigh update convenience and config maintenance costs. That's more useful than ranking cores by name alone.

Download v2rayNDesktop and Android clients