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.
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.
- Desktop: With v2rayN, check which cores and node types your client version supports. Use the startup log to confirm which core is actually running; don't rely on the filenames in the install folder.
- Android: v2rayNG uses the Xray core, while v2flyNG uses the V2Fly core. They're separate apps, not two themes for the same app.
- Server: The client and server don't have to use cores with the same name, but both must support the same protocol combination and use matching authentication, transport, and security settings.
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 requirement | Xray | V2Fly | What to check before choosing |
|---|---|---|---|
| VMess + WebSocket + TLS | Commonly supported combinations | Commonly supported combinations | Authentication settings, path, Host, and TLS server name |
| Basic VLESS protocol | Supported, with additional Xray-specific capabilities | Related implementations exist in some versions or config formats; check the version in use | The VLESS name alone doesn't guarantee full compatibility |
| VLESS + REALITY | A typical Xray use case | Xray REALITY configs can't be used as-is | Public key, server name, short ID, and transport requirements |
| xtls-rprx-vision | Requires a compatible Xray version and combination | Doesn't support this Xray flow value | Whether the server explicitly requires this flow |
| Local SOCKS / HTTP inbound | Common local proxy inbounds are supported | Common local proxy inbounds are supported | Listen 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.
- Protocol fields: Check the UUID, encryption settings, and flow. Don't reuse authentication fields from a different protocol.
- Transport fields: Check the path, headers, and transport name against your current version. Names in older guides may not apply to newer configs.
- Security fields: The TLS server name and WebSocket Host serve different purposes. Even if an example uses the same domain for both, they aren't always the same.
- Routing fields: Check that the outbound tag still exists. If a rule refers to an old tag, the problem may occur during routing, not the protocol handshake.
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.
- 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.
- 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.
- 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.
- 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.
| Log message or symptom | Check first | Next step |
|---|---|---|
unknown field or config load failure | Field placement, config format, and core version | Have the current client regenerate the config; don't blindly delete unknown fields |
address already in use | Whether the local listen port is already in use | Stop duplicate proxy processes, or use matching listen and app ports |
connection refused | Whether the error points to a local or remote address | Check the local listener first, then confirm the remote service is open on the correct port |
| Certificate name mismatch | TLS server name, certificate, and system clock | Correct the name and system time; don't routinely disable certificate verification |
| Handshake failure or connection timeout | Protocol settings and network reachability | Verify 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.
- 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.
- Control variables: Compare only the same protocol combination supported by both cores, using the same server, test destination, and traffic capture method.
- 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.
- 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.
- Node requires REALITY or Vision: On desktop, confirm that v2rayN is using a supported Xray combination. On Android, choose v2rayNG with the matching capabilities and verify each imported field.
- Existing V2Fly config works reliably: Keep using it if the node uses a supported protocol combination and you don't need newer capabilities. On Android, v2flyNG is a good fit for nodes supported by that core.
- Planning a migration between cores: Generate a fresh config from the original subscription or server settings where possible. Check the protocol, security layer, DNS, and routing separately; don't treat an entire old JSON file as a universal config.
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.