Sep 8, 2026 · Core Selection · About 9 min read

Xray vs. V2Fly: Which Core Should You Use with v2rayNG or v2flyNG?

Compare Xray and V2Fly support for protocols and config formats, understand how Project V relates to both, and choose the right Android client.

At a glance

On Android, choose a core based on your node parameters, then choose a client based on your config source. For VLESS, REALITY, and Vision, first check whether the Xray version bundled with v2rayNG meets your needs. If you already have configs maintained for V2Fly, v2flyNG may be a better fit. This guide distinguishes clients, cores, and subscriptions, with field checks, config examples, and switching steps to help you avoid mistaking a successful import for a compatible connection.

How Project V, V2Fly, and Xray are related

Project V is an ecosystem of network proxy tools, with V2Ray as its core software. V2Fly continues the community development of V2Ray, while Xray started as a V2Ray fork and later developed its own protocol extensions and implementation path. They share a configuration history, but they are not the same program under different names. The fact that both use a file called config.json does not make them interchangeable.

The client handles the interface, subscription management, and system-level traffic routing; the core parses configuration, establishes connections, and applies routing. v2rayNG bundles Xray on Android, while v2flyNG bundles V2Fly. On desktop, v2rayN's core options depend on the specific version, node type, and core settings. Its flexibility should not be assumed to apply to either Android client.

LayerComponentPrimary role
Project and implementationV2Fly、XrayMaintains protocol implementations, configuration parsing, and connection handling.
Android clientv2rayNG、v2flyNGManages nodes and subscriptions, requests Android VPN permission, and launches its bundled core.
Desktop clientv2rayNManages desktop proxy access, nodes, and core runtime settings.
Connection configVMess, VLESS, transport, and TLS parametersDefines how the client negotiates with the server and must match the capabilities of the core in use.

Version numbers from these two development tracks are not directly comparable. Track the app version and core version separately: an app update may change the interface without switching core families, while a node connection error may stem from a field unsupported by the bundled core. When troubleshooting, having both version numbers is more useful than simply saying you installed the latest version.

Protocol support: check the full connection setup

VMess and VLESS are proxy protocols; WebSocket and gRPC are transport options; TLS and REALITY are connection security settings. Choose a client by checking all of these layers together. Seeing a vless:// link alone does not prove that every VLESS-compatible implementation can connect to the same server.

Xray core / v2rayNG

Recommended

For nodes that explicitly require VLESS, REALITY, and Vision, start with this option and verify that the Xray version bundled with the client meets the server's requirements. This recommendation is based on protocol compatibility, not a promise of faster performance on every network.

Best for: nodes that specify Xray or use VLESS + REALITY + Vision.

V2Fly core / v2flyNG

A good fit for configs written to V2Fly documentation and already confirmed to work. Common VMess and WebSocket/TLS setups still require checking the transport, path, and certificate parameters individually.

Best for: existing configs built around V2Fly that don't depend on Xray-specific features.

Node detailsCheckHow to choose
VMess + WebSocket + TLSUser ID, server port, path, Host, and TLS server name.Both implementations have corresponding support; verify against the specific version and config.
VLESS + REALITY + Visionflow, security, server name, key-related parameters, and short ID.Prefer v2rayNG / Xray; don't assume the config can be migrated directly to V2Fly.
Full custom JSONConfig format, protocol fields, transport fields, and asset file paths.Choose based on the core the config targets, not the file extension.

Bottom line: match the server first, then compare the experience

Start by noting four items: protocol, transport, security layer, and flow. If any one exceeds the target core's capabilities, resolve compatibility first. A latency test is no substitute for checking the fields.

config.json: shared structure and migration limits

Common configs include inbounds, outbounds, and routing. Inbounds accept traffic from local apps, outbounds determine how to reach destinations, and routing selects an outbound. The example below uses a traditional JSON structure common to both and sets up a local SOCKS connection with direct routing. It's for understanding the fields only: it contains no remote proxy node and does not create an encrypted proxy connection.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "ip": ["127.0.0.0/8"],
        "outboundTag": "direct"
      }
    ]
  }
}

Here, listen limits the local listening interface, tag is an internal reference name, and outboundTag must match an outbound tag. The direct outbound is listed first, so traffic that matches no rule also goes direct. If you migrate only the routing rules without the referenced outbound, the config may fail to load rather than automatically filling in the missing node.

Subscription imports and Android VPN routing

A subscription distributes node details; it is not a core protocol. Adding the same subscription URL in two clients does not mean both will recognize every node field, and conversion can sometimes drop transport parameters. If both clients import the same number of nodes but one can't connect, open the node's settings and compare them with the original connection parameters instead of repeatedly refreshing the subscription.

Migration plan: verify subscriptions and network rules separately

Keep your current client
  • Record the app and core versions.
  • Back up node parameters and the subscription URL.
  • Note per-app lists, DNS, and routing mode.
  • Keep a set of configs already confirmed to work.
Test the target client
  • Import one node first and check each field.
  • Stop the current client before starting the VPN service.
  • Verify the connection first, then restore per-app and traffic-routing rules.
  • Recheck key parameters after updating the subscription.

A subscription distributes nodes only; it won't keep per-app lists, DNS, or routing settings in sync.

Android VPN routing and the proxy core are separate layers. The client receives traffic through the system VPN interface, then passes it to its internal processing chain; this does not mean the remote node uses a traditional VPN protocol. Usually, only one VPN service can be active for a given user or profile. When switching between v2rayNG and v2flyNG, stop the first client before authorizing and starting the second. Otherwise, the system may revoke the original service, which can look like a random connection drop.

  1. On first launch, approve the system VPN request, then check whether the client reports a startup error.
  2. To exclude specific apps, check the client's per-app proxy settings and confirm whether the list includes apps or bypasses them.
  3. If the connection stops after you leave the app, check Android background restrictions and battery optimization before changing the server protocol.
  4. Pause other tools that use the VPN interface during testing to reduce traffic-routing conflicts.

Connection problems: check the port, handshake, then DNS

Choosing a core doesn't replace network troubleshooting. A connection timeout may mean the server port is unreachable; a TLS error may point to the server name or device clock; and pages that won't load may be caused by an unexpected DNS path. The three numbers below are diagnostic reference points, not client defaults or performance benchmarks.

10808
Local SOCKS listening port used in this example
443
Common TLS server port; use the value specified by the node
1
Change one variable at a time to isolate the cause
SymptomCheck firstNext step
Fails immediately on startupUnknown fields, config format, or port conflict.Read the first specific error and check the core version and where the field came from.
Remote connection times outAddress, port, current network, and server listener.Keep the node unchanged and test on different networks. Don't change DNS and protocol at the same time.
TLS or authentication failureDevice clock, server name, user ID, security layer, and key parameters.Compare each item with the server config; don't treat disabling certificate verification as a fix.
Some domains failDNS resolution path, IPv6 reachability, and routing rule order.Use a fixed test domain and check the DNS result and selected outbound.
Only one app failsPer-app list, UDP requirements, and the app's own network behavior.First check whether the app is included in the proxy routing scope.

Control conditions when comparing performance: use the same network, server, time window, and test destination, and record connection success rate, latency, and sustained throughput separately. One latency test can't show which core uses less battery or delivers higher throughput; mobile network changes, device temperature, and background tasks can all affect the results. Before sharing diagnostic logs, remove connection details such as subscription URLs, user identifiers, and keys.

Choosing between v2rayNG and v2flyNG

If the server explicitly provides an Xray-specific connection setup, v2rayNG is the more direct choice. If you have a V2Fly config that has worked for a long time and don't need new protocol features, v2flyNG can reduce migration variables. Judge both by actual connectivity and field compatibility; there's no need to replace a proven config just to use a different core name.

Recommended order: one node, one set of rules, one switch

Test one node in the target client before adding subscriptions and routing rules. Keep the original config until you've tested real-world access with the new setup, so you can quickly roll back and pinpoint differences if something goes wrong.

Download client