Skip to main content

Victory Native vs React Native Chart Kit vs ECharts: Mobile Charts 2026

·PkgPulse Team

Victory Native vs React Native Chart Kit vs ECharts: Mobile Charts 2026

TL;DR

Data visualization on mobile is harder than web — no SVG in the native renderer, performance constraints on 60fps animations, and touch interactions that feel native. Victory Native XL (the rewritten version using React Native Skia) renders charts directly on the GPU via Skia canvas — smooth 60fps animations, declarative API, and full TypeScript types; it's the modern choice for performant React Native charts. React Native Chart Kit is the pragmatic option — uses SVG via react-native-svg, covers the most common chart types with minimal configuration, and has been the community default for years despite limited customization. Apache ECharts for React Native brings the full power of the ECharts ecosystem — 20+ chart types, rich interactions, WebView-based rendering; best when you need advanced chart types or are already using ECharts on web. For performant, customizable charts with Skia: Victory Native XL. For quick standard charts with SVG: React Native Chart Kit. For advanced chart types ported from a web ECharts implementation: Apache ECharts.

Key Takeaways

  • Victory Native XL uses React Native Skia — GPU-accelerated canvas, not SVG
  • React Native Chart Kit uses SVG — via react-native-svg, more compatible
  • Apache ECharts uses WebView — full web ECharts in a WebView; most chart variety
  • Victory Native XL supports Reanimated — gesture-driven interactions (pan, zoom)
  • React Native Chart Kit: no live updates — static charts, no built-in animation
  • ECharts React Native: 20+ chart types — map, sankey, sunburst, candlestick, etc.
  • Victory Native XL is a complete rewrite — not backward-compatible with Victory Native v36

Chart Type Coverage

Bar chart          → All three ✅
Line chart         → All three ✅
Pie / Donut        → All three ✅
Area chart         → Victory Native XL, RN Chart Kit ✅
Scatter plot       → Victory Native XL, ECharts ✅
Candlestick        → ECharts ✅
Heatmap            → ECharts ✅
Sankey diagram     → ECharts ✅
Radar chart        → ECharts, Victory Native XL ✅
Map / Geo          → ECharts ✅
Progress ring      → Victory Native XL ✅
Sparkline          → Victory Native XL ✅

Victory Native XL: Skia-Powered Charts

Victory Native XL (v40+) is a complete rewrite of Victory Native using React Native Skia for direct GPU canvas rendering. It supports gesture-driven interactions via react-native-gesture-handler and react-native-reanimated.

Installation

npm install victory-native
# Required peer dependencies:
npm install react-native-skia react-native-reanimated react-native-gesture-handler
npx pod-install  # iOS

Line Chart

import { CartesianChart, Line, useChartPressState } from "victory-native";
import { Circle, useFont } from "@shopify/react-native-skia";
import { useSharedValue } from "react-native-reanimated";

const data = [
  { day: "Mon", revenue: 1200 },
  { day: "Tue", revenue: 1800 },
  { day: "Wed", revenue: 1500 },
  { day: "Thu", revenue: 2100 },
  { day: "Fri", revenue: 2400 },
  { day: "Sat", revenue: 1900 },
  { day: "Sun", revenue: 800 },
];

function RevenueChart() {
  const font = useFont(require("../assets/fonts/Inter-Regular.ttf"), 12);
  const { state, isActive } = useChartPressState({ x: "day", y: { revenue: 0 } });

  return (
    <CartesianChart
      data={data}
      xKey="day"
      yKeys={["revenue"]}
      axisOptions={{
        font,
        formatYLabel: (value) => `$${value.toLocaleString()}`,
        labelColor: "#666",
        lineColor: "#e0e0e0",
      }}
      chartPressState={state}
    >
      {({ points }) => (
        <>
          <Line
            points={points.revenue}
            color="#3b82f6"
            strokeWidth={2}
            animate={{ type: "spring" }}
          />
          {isActive && (
            <Circle
              cx={state.x.position}
              cy={state.y.revenue.position}
              r={8}
              color="#3b82f6"
            />
          )}
        </>
      )}
    </CartesianChart>
  );
}

Bar Chart

import { CartesianChart, Bar } from "victory-native";

function SalesBarChart() {
  return (
    <CartesianChart
      data={data}
      xKey="day"
      yKeys={["revenue"]}
      domainPadding={{ left: 20, right: 20, top: 20 }}
    >
      {({ points, chartBounds }) => (
        <Bar
          chartBounds={chartBounds}
          points={points.revenue}
          color="#3b82f6"
          roundedCorners={{ topLeft: 4, topRight: 4 }}
          animate={{ type: "spring", duration: 300 }}
        />
      )}
    </CartesianChart>
  );
}

Pie / Donut Chart

import { PieChart } from "victory-native";

const pieData = [
  { label: "Direct", value: 40, color: "#3b82f6" },
  { label: "Organic", value: 25, color: "#10b981" },
  { label: "Paid", value: 20, color: "#f59e0b" },
  { label: "Referral", value: 15, color: "#ef4444" },
];

function TrafficSourceChart() {
  return (
    <PieChart
      data={pieData}
      labelKey="label"
      valueKey="value"
      colorKey="color"
      outerRadius="80%"
      innerRadius="50%"  // Donut chart
      animate={{ type: "spring" }}
    />
  );
}

Interactive Tooltip

import { CartesianChart, Line } from "victory-native";
import { useChartPressState } from "victory-native";
import Animated, { useAnimatedStyle, useDerivedValue } from "react-native-reanimated";

function InteractiveChart() {
  const { state, isActive } = useChartPressState({ x: "day", y: { revenue: 0 } });

  const tooltipLabel = useDerivedValue(() =>
    isActive.value
      ? `${state.x.value.value}: $${state.y.revenue.value.value.toFixed(0)}`
      : ""
  );

  return (
    <View>
      {/* Tooltip */}
      <Animated.Text style={tooltipStyle}>{tooltipLabel}</Animated.Text>

      <CartesianChart
        data={data}
        xKey="day"
        yKeys={["revenue"]}
        chartPressState={state}
        style={{ height: 250 }}
      >
        {({ points }) => <Line points={points.revenue} color="#3b82f6" strokeWidth={2} />}
      </CartesianChart>
    </View>
  );
}

React Native Chart Kit: SVG Charts

React Native Chart Kit is the long-standing community choice for standard charts via SVG — straightforward API, covers most use cases, with react-native-svg under the hood.

Installation

npm install react-native-chart-kit react-native-svg
npx pod-install  # iOS

Line Chart

import { LineChart } from "react-native-chart-kit";
import { Dimensions } from "react-native";

const screenWidth = Dimensions.get("window").width;

const chartConfig = {
  backgroundColor: "#ffffff",
  backgroundGradientFrom: "#ffffff",
  backgroundGradientTo: "#ffffff",
  decimalPlaces: 0,
  color: (opacity = 1) => `rgba(59, 130, 246, ${opacity})`,
  labelColor: (opacity = 1) => `rgba(100, 116, 139, ${opacity})`,
  strokeWidth: 2,
  propsForDots: {
    r: "4",
    strokeWidth: "2",
    stroke: "#3b82f6",
  },
};

function RevenueLineChart() {
  return (
    <LineChart
      data={{
        labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
        datasets: [
          {
            data: [1200, 1800, 1500, 2100, 2400, 1900, 800],
            color: (opacity = 1) => `rgba(59, 130, 246, ${opacity})`,
            strokeWidth: 2,
          },
        ],
      }}
      width={screenWidth - 32}
      height={220}
      chartConfig={chartConfig}
      bezier  // Smooth curves
      style={{ borderRadius: 12 }}
      formatYLabel={(value) => `$${parseInt(value).toLocaleString()}`}
      onDataPointClick={({ value, index }) => {
        console.log(`Tapped: ${value} at index ${index}`);
      }}
    />
  );
}

Bar and Pie Charts

import { BarChart, PieChart, ProgressChart } from "react-native-chart-kit";

function SalesBarChart() {
  return (
    <BarChart
      data={{
        labels: ["Mon", "Tue", "Wed", "Thu", "Fri"],
        datasets: [{ data: [1200, 1800, 1500, 2100, 2400] }],
      }}
      width={screenWidth - 32}
      height={220}
      chartConfig={chartConfig}
      yAxisLabel="$"
      yAxisSuffix=""
      showValuesOnTopOfBars
    />
  );
}

function TrafficPieChart() {
  return (
    <PieChart
      data={[
        { name: "Direct", population: 40, color: "#3b82f6", legendFontColor: "#666", legendFontSize: 12 },
        { name: "Organic", population: 25, color: "#10b981", legendFontColor: "#666", legendFontSize: 12 },
        { name: "Paid", population: 20, color: "#f59e0b", legendFontColor: "#666", legendFontSize: 12 },
      ]}
      width={screenWidth - 32}
      height={200}
      chartConfig={chartConfig}
      accessor="population"
      backgroundColor="transparent"
      paddingLeft="10"
    />
  );
}

Apache ECharts for React Native: WebView Charts

ECharts for React Native wraps Apache ECharts in a WebView — full access to ECharts' 20+ chart types, themes, and interactions.

Installation

npm install @wuba/react-native-echarts react-native-webview react-native-svg
npx pod-install  # iOS

Line Chart with ECharts

import { useRef, useState, useEffect } from "react";
import { SkiaChart, SVGRenderer } from "@wuba/react-native-echarts";
import * as echarts from "echarts/core";
import { LineChart } from "echarts/charts";
import { GridComponent, TooltipComponent, LegendComponent } from "echarts/components";

// Register required components
echarts.use([SVGRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]);

function EChartsLineChart() {
  const chartRef = useRef(null);

  useEffect(() => {
    const chart = echarts.init(chartRef.current, "light", {
      renderer: "svg",
      width: 350,
      height: 250,
    });

    chart.setOption({
      tooltip: {
        trigger: "axis",
        formatter: (params: any[]) => {
          return `${params[0].axisValue}: $${params[0].value.toLocaleString()}`;
        },
      },
      xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      },
      yAxis: {
        type: "value",
        axisLabel: { formatter: (val: number) => `$${val.toLocaleString()}` },
      },
      series: [
        {
          data: [1200, 1800, 1500, 2100, 2400, 1900, 800],
          type: "line",
          smooth: true,
          lineStyle: { width: 2, color: "#3b82f6" },
          areaStyle: { color: "rgba(59, 130, 246, 0.1)" },
        },
      ],
    });

    return () => chart.dispose();
  }, []);

  return <SkiaChart ref={chartRef} />;
}

Advanced: Candlestick Chart (Not available in other libraries)

import { CandlestickChart } from "echarts/charts";
echarts.use([CandlestickChart]);

function StockChart() {
  const chartRef = useRef(null);

  useEffect(() => {
    const chart = echarts.init(chartRef.current, "light", {
      renderer: "svg",
      width: 350,
      height: 300,
    });

    // [open, close, low, high]
    const stockData = [
      [150, 155, 148, 157],
      [155, 152, 149, 158],
      [152, 160, 151, 162],
      [160, 158, 155, 163],
      [158, 165, 156, 167],
    ];

    chart.setOption({
      xAxis: {
        data: ["Mon", "Tue", "Wed", "Thu", "Fri"],
      },
      yAxis: { scale: true },
      series: [
        {
          type: "candlestick",
          data: stockData,
          itemStyle: {
            color: "#10b981",      // Bullish
            color0: "#ef4444",     // Bearish
            borderColor: "#10b981",
            borderColor0: "#ef4444",
          },
        },
      ],
    });

    return () => chart.dispose();
  }, []);

  return <SkiaChart ref={chartRef} />;
}

Feature Comparison

FeatureVictory Native XLRN Chart KitECharts RN
RendererSkia (GPU canvas)SVGWebView/SVG
Performance✅ Excellent✅ Good⚠️ WebView overhead
Chart types8820+
Gesture/zoom✅ Reanimated
Animations✅ SpringLimited✅ Rich
Candlestick
Heatmap
Sankey/Flow
TypeScript✅ Excellent✅ Good✅ Good
Bundle sizeMediumSmallLarge (ECharts)
Custom drawing✅ Skia canvas
GitHub stars1.6k2.5k4k

When to Use Each

Choose Victory Native XL if:

  • Performance is critical — 60fps animations with gesture-driven interactions (pan, zoom, scrub)
  • Skia canvas gives access to custom drawing alongside charts
  • Standard chart types (line, bar, area, pie, scatter) cover your needs
  • TypeScript-first, modern React Native stack (Skia + Reanimated + Gesture Handler)

Choose React Native Chart Kit if:

  • Quick standard charts without performance requirements
  • Simpler setup — just react-native-svg as a dependency
  • Community-familiar API that's been stable for years
  • No need for gesture interactions or animation beyond basic entrance animations

Choose ECharts React Native if:

  • Advanced chart types not available in other libraries (candlestick, sankey, heatmap, geo maps)
  • You're porting a web ECharts implementation to React Native
  • Rich built-in interactions (click to filter, drill-down, zoom) matter
  • WebView overhead is acceptable for your use case

Methodology

Data sourced from official Victory Native documentation (commerce.nearform.com/open-source/victory-native), React Native Chart Kit GitHub repository, Apache ECharts for React Native documentation (wuba.github.io/react-native-echarts), npm download statistics as of February 2026, GitHub star counts as of February 2026, and community discussions from the React Native Discord and r/reactnative.


Related: FlashList vs FlatList vs LegendList for the list rendering performance that often houses chart data, or React Native Reanimated vs Moti vs Skia for the animation libraries that Victory Native XL is built on.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.