Explore charts react native: Build Interactive Charts in Mobile Apps

Practical guide to charts react native: choose libraries, connect data with Supabase, and optimize performance for Expo apps.

Profile photo of SanketSanket
19th Feb 2026
Featured image for Explore charts react native: Build Interactive Charts in Mobile Apps

When you need to add charts to a React Native app, the conversation almost always boils down to two main players: Victory Native for its incredible flexibility and ease of use, and React Native Skia when you need raw, unadulterated performance. Your final decision really hinges on a simple question: Do you need to get beautiful charts up and running quickly, or are you wrangling massive, complex datasets that demand silky-smooth rendering?

Choosing The Right Charting Library For Your Expo App

Picking the right charting library for your Expo project is one of those early decisions that pays dividends down the line. It’s not just about finding something that can draw a line graph. You're looking for a tool that slots into your workflow effortlessly, performs reliably on both iOS and Android, and has documentation that actually helps you, rather than sending you down a rabbit hole of configuration issues.

The good news is that the React Native ecosystem is mature and thriving. It’s a powerhouse for cross-platform development, currently backing over 11 million websites and hitting an impressive 4 million weekly downloads. With a solid 35% market share in the cross-platform world and over 207,000 stars on its GitHub repo, you're building on a solid foundation. You can see how it stacks up against other frameworks if you're curious about the numbers.

Key Evaluation Criteria

When you're weighing your options, there are a few things I always tell developers to focus on.

First, Expo compatibility is a must-have. A library that "just works" with Expo will save you from a world of configuration pain. Performance is the next big one—a janky, stuttering chart can make an otherwise great app feel cheap. And finally, think about long-term maintainability, which usually comes down to the quality of the docs and the size of the community.

This simple flowchart breaks down the core decision. If your app is going to be handling huge datasets or needs fluid, complex animations, the GPU-accelerated power of Skia is your best bet. For just about everything else, Victory offers a much smoother development experience.

Flowchart for React Native chart library selection: Skia for high performance, Victory for others.Flowchart for React Native chart library selection: Skia for high performance, Victory for others.

As you can see, it really comes down to how much performance you need to squeeze out of the device.

Comparing The Top Contenders

To give you a clearer picture, I've put together a quick comparison of the libraries I see used most often in professional projects.

React Native Charting Library Comparison

A head-to-head comparison of popular charting libraries based on key criteria for modern developers.

LibraryBest ForExpo CompatibilityPerformanceCustomization
Victory NativeGeneral purpose, rapid development, highly customizable chartsExcellent (no config needed)Good (SVG-based)High
React Native SkiaRealtime data, large datasets, complex animationsExcellent (requires setup)Exceptional (GPU)High (lower-level)
RechartsTeams familiar with the web version, simple chartsFair (needs react-native-svg wrapper)ModerateModerate

Ultimately, the choice depends on your project's specific needs, but this should give you a solid starting point.

Here's a bit more detail on each one:

  • Victory Native: This is the go-to for a reason. It masterfully balances ease of use with deep customization. If you're comfortable with React's declarative, component-based approach, you'll feel right at home.

  • React Native Skia Charts: For apps where performance is the top priority, Skia is king. It taps directly into the GPU, which makes it perfect for visualizing realtime data streams or animating thousands of data points without breaking a sweat.

  • Recharts (with a wrapper): While it’s a web-first library, you can get Recharts working in React Native using react-native-svg. It's a decent option if your team already has a lot of experience with its API from web development, saving some ramp-up time.

My personal take: For 90% of projects, Victory Native is the sweet spot. It's powerful enough to create stunning, interactive charts right out of the box, and it doesn't have the steeper learning curve that can come with a lower-level graphics engine like Skia. Start with Victory, and only reach for Skia if you hit a performance wall.

Bringing Your First Interactive Chart to Life

Alright, enough theory. Let's get our hands dirty and actually build something. This is where you see how the pieces fit together inside a real Expo app. For this guide, we're going with Victory Native. I find its component-based API is a natural fit for anyone coming from React, and it hits that sweet spot between power and ease of use.

We’re not just going to render a static image. The goal here is to create a simple bar chart and then sprinkle in some interactivity. We’ll add tooltips that pop up when a user taps a bar, which immediately makes the chart feel more alive and useful. This first, tangible result will give you a solid foundation for building much more complex visualizations down the line.

Getting the Right Packages Installed

First things first, we need to get Victory Native and its dependencies into our project. The library works its magic using react-native-svg for drawing the actual chart elements and react-native-gesture-handler for managing all the touch interactions.

Pop open your terminal and run this single command in your project directory:

npx expo install victory-native react-native-svg react-native-gesture-handler

A quick but important tip: always use npx expo install. This little command is a lifesaver because it automatically picks versions of these packages that are guaranteed to be compatible with your project's Expo SDK. It's a simple way to sidestep a whole class of frustrating dependency headaches from the get-go.

Assembling the Bar Chart Component

With our libraries in place, it's time to build the chart component itself. We'll start with a straightforward bar chart to visualize some sample sales data. If you've ever built a React component, this declarative structure will feel right at home.

Go ahead and create a new file, SalesBarChart.js. Inside, we’ll pull in a few key components from victory-native: VictoryChart, VictoryBar, and VictoryTheme. That last one gives us a nice-looking chart with minimal styling effort.

Here’s the starter code for a clean, static bar chart:

import React from 'react'; import { VictoryBar, VictoryChart, VictoryTheme } from 'victory-native';

const data = [ { quarter: 1, earnings: 13000 }, { quarter: 2, earnings: 16500 }, { quarter: 3, earnings: 14250 }, { quarter: 4, earnings: 19000 } ];

const SalesBarChart = () => { return ( ); };

export default SalesBarChart;

What we're doing here is pretty simple: we set up a VictoryChart to act as our container, then render a VictoryBar inside it. We pass our data to the bars and tell Victory to map the quarter field to the x-axis and earnings to the y-axis. The domainPadding just adds a bit of breathing room so the bars aren't jammed up against the edges.

Making it Interactive with Tooltips

A static chart tells a story, but an interactive one invites users into that story. Let's add tooltips that show the exact earnings when someone taps on a bar. Victory’s compositional approach makes this surprisingly easy.

We just need to import VictoryTooltip and then wrap our VictoryBar with a special container component called VictoryVoronoiContainer. This container is a game-changer for mobile charts, as it intelligently enhances touch detection across the chart area.

The VictoryVoronoiContainer is a bit of a secret weapon. It creates an invisible layer of polygons around each of your data points, making the tappable area much larger and more forgiving. This means your users don't have to nail a perfect tap on a skinny little bar to get the tooltip to appear.

Wiring Up Your Charts to Live Supabase Data

Static charts are fine for a proof-of-concept, but the real magic begins when you hook them up to live, dynamic data. This is where your app transforms from a simple display into a powerful, real-time dashboard. For this, we'll use Supabase and its fantastic realtime capabilities to bring our charts react native component to life.

A hand holds a smartphone showing a donut chart, next to a monitor with a bar chart and an 'Interactive Chart' sign.A hand holds a smartphone showing a donut chart, next to a monitor with a bar chart and an 'Interactive Chart' sign.

The idea is simple: we'll set up a Supabase table, fetch the data from our Expo app, and then listen for changes. When a record is updated in the database, our chart will instantly and smoothly animate to reflect the new numbers. This gives users a responsive and professional experience, making your app feel genuinely alive.

Getting the Supabase Table Structure Right

Before you even think about writing code, your data needs a solid foundation. For a bar chart tracking something like monthly sales, you don't need anything complicated.

Let's create a table called monthly_sales with a few essential columns:

  • id (Primary Key, integer)
  • month (text, e.g., "Jan", "Feb", "Mar")
  • revenue (numeric)
  • created_at (timestamp with timezone)

This clean structure makes it trivial to pull the data, order it by month, and map the revenue field directly to our chart's y-axis. My advice? Always start with the simplest data model that works. You can always add complexity later if you need it.

Fetching the Initial Data with React Hooks

With our table in place, it’s time to pull that data into the app. We'll lean on React's useEffect and useState hooks to manage the entire data-fetching lifecycle, which includes handling those pesky loading and error states. This is a core pattern you'll use over and over in modern React development.

First things first, get the Supabase client installed in your project: npx expo install @supabase/supabase-js

Next, we’ll build a custom hook called useSalesData to keep all the data logic neatly tucked away. This is a great practice because it lets our chart component focus on what it does best: presentation. The hook will handle fetching the initial dataset as soon as the component loads.

// hooks/useSalesData.js import { useState, useEffect } from 'react'; import { supabase } from '../lib/supabase'; // Your initialized Supabase client

export const useSalesData = () => { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null);

useEffect(() => { const fetchSales = async () => { try { const { data: salesData, error } = await supabase .from('monthly_sales') .select('month, revenue') .order('id'); // Ensure consistent order

    if (error) throw error;
    setData(salesData);
  } catch (err) {
    setError(err);
  } finally {
    setLoading(false);
  }
};

fetchSales();

}, []);

return { data, loading, error }; };

Subscribing to Realtime Updates

Now for the fun part—making the chart react instantly to database changes. Supabase makes this almost laughably easy with its realtime subscriptions. We just need to extend our custom hook to listen for any inserts, updates, or deletes on that monthly_sales table.

Key Insight: The true power of a framework like React Native isn't just that you can build for both iOS and Android. It's how it empowers you to create complex, data-driven UIs that feel snappy and native. When you pair it with a backend-as-a-service like Supabase, you can slash your development time dramatically.

The industry has certainly taken notice. React Native's enterprise adoption is massive—as of 2026, 18,873 verified companies use it, including giants like Meta, Microsoft, and Shopify. The fact that companies with revenues over $600 billion trust it for their core apps speaks volumes about its scalability and reliability. You can learn more about React Native's widespread adoption to see who else is on board.

All we need to do is add a Supabase subscription inside our useEffect hook. When a change comes through, we'll simply re-fetch the entire dataset. This is a straightforward and effective way to guarantee your UI is always perfectly in sync with your database.

Styling Charts To Match Your App's Brand

Let's be honest: a chart that looks out of place can completely shatter the user experience. It makes the whole app feel disjointed and less professional. The goal is to make your data visualizations feel like a core part of your application, not some third-party widget you just dropped in. Getting this right is all about mastering the styling of your charts react native components.

A laptop on a wooden desk showing a real-time data chart, with a coffee mug and notebook.A laptop on a wooden desk showing a real-time data chart, with a coffee mug and notebook.

This goes way beyond just picking a few colors that look nice. It means making sure every single visual element, from the thickness of a line to the font of an axis label, lines up with your brand. It’s this attention to detail that creates a truly seamless and polished feel.

Mastering The Style Prop

Most of the solid charting libraries out there, including Victory Native, give you a powerful style prop to work with. This is your main entry point for customization. It basically works like a CSS-in-JS object, letting you target and tweak specific parts of the chart.

You get granular control over elements like:

  • Data styles: This is where you'll change the fill color, stroke width, and opacity of your bars, lines, or pie slices.
  • Label styles: You can adjust the font size, font family, and color for any data labels or tooltips.
  • Axis styles: Fine-tune the grid lines, tick marks, and axis labels to perfectly match your app's typography.

For instance, to get your charts to match our AppLighter theme, you'd probably set the bar fill to our signature blue and ensure all the labels use our standard app font. That kind of consistency is what makes the chart feel like it belongs.

Creating A Branded Theme

Styling every single chart component by hand is going to get old, fast. A much smarter and more scalable way to work is by creating a custom theme object. Victory Native, for example, lets you define a global theme that applies default styles to every chart you build.

A centralized theme isn't just a convenience; it's a best practice for maintaining visual consistency. It guarantees that every chart, from a dashboard bar graph to a detailed line chart, follows the same brand guidelines without you having to repeat a single line of code.

Your theme can define everything from color palettes to font weights. This approach doesn't just save a ton of time upfront; it makes future redesigns or brand updates incredibly simple. All you have to do is tweak the theme object, and every chart in your app will update automatically.

Building A Custom Tooltip Component

While the default tooltips get the job done, a custom tooltip is a fantastic opportunity to really inject your brand's personality into the chart. Most libraries will let you pass your own custom React component to render the tooltip, giving you total freedom over how it looks and acts.

This is where you can get creative. Design a tooltip that uses your app's custom icons and typography. You could even add interactive elements, like a "View Details" button that navigates the user to a more detailed screen. It's these thoughtful little touches that really elevate the user experience and can separate a good app from a truly great one.

Keeping Your Charts Fast and Fluid

A laggy, unresponsive interface can kill an otherwise brilliant app. When it comes to data visualizations, performance isn't just a nice-to-have; it's a core feature. If your charts stutter, especially with a decent amount of data, users will notice, and it reflects poorly on the entire experience.

A desk with a laptop, smartphone displaying color options, and a color palette book for brand matching.A desk with a laptop, smartphone displaying color options, and a color palette book for brand matching.

The biggest performance hog I see time and again is the excessive re-render. This is when your chart component redraws itself over and over again for no good reason. It usually happens because a parent component’s state changed, triggering a cascade of updates, even if the actual data feeding your chart is identical. This can easily jam up the UI thread, causing that dreaded jank.

Stop Wasted Renders with Memoization

So, how do we fix it? The go-to solution is memoization—a fancy word for caching the result of an expensive calculation. React gives us two fantastic tools for this job: React.memo and useMemo.

  • Wrap Components with React.memo: Think of this as a protective shield for your component. By wrapping your chart component in React.memo, you’re telling React, "Hey, don't bother re-rendering this unless its props have actually changed." It’s a simple, high-impact fix.

  • Cache Data with useMemo: If you're doing any heavy data crunching—like filtering, mapping, or reducing a large array before it even gets to the chart—that logic needs to be wrapped in a useMemo hook. This ensures the calculation only re-runs when its dependencies change, not on every single render cycle of the parent.

By strategically applying these hooks, you prevent your app from re-drawing and re-calculating when it doesn't need to. This frees up the UI thread and is absolutely the first place you should look when your charts feel slow.

The core principle of optimization is simple: do less work. Memoization is your way of telling React, "If the inputs are the same, the output will be too, so just use the last result and don't bother re-running everything." This is fundamental to a snappy mobile app.

Gracefully Handling Massive Datasets

What about when you’re dealing with thousands, or even tens of thousands, of data points? Shoving all that into a chart at once is a surefire way to crash your app or at least make it unusable on a mobile device. For these scenarios, we need to bring out the bigger guns.

A really effective strategy is data windowing (sometimes called virtualization). Instead of rendering every single point, you only render the small subset that's currently visible in the chart's viewport. As the user pans or zooms, you intelligently load and unload data points. The user gets a seamless experience, never realizing the app is only drawing a tiny fraction of the total dataset.

For the most intense use cases—think real-time financial dashboards or scientific data plotters—you may need to offload the work to the GPU. Libraries built on React Native Skia do just that. They use hardware acceleration to handle the heavy graphics rendering, leaving the CPU free for everything else. This unlocks incredibly smooth animations and interactions, even with enormous datasets. This is how you take an app from good to truly professional.

Frequently Asked Questions About React Native Charts

When you start building charts in React Native, a few questions tend to pop up again and again. I've run into these myself over the years, so here’s a quick rundown of the most common hurdles and how to clear them.

How Do I Handle Charts On Both iOS And Android?

This is one of the best parts about working with modern charting libraries: most of them are designed to be cross-platform from the get-go. A library like Victory Native handles the tricky native rendering differences for you, so you can focus on writing a single JavaScript component that just works.

The trick is to choose a well-maintained library with solid Expo support. Doing so saves you from a world of platform-specific bugs and configuration headaches. That said, always, always test on real physical devices for both iOS and Android. You'd be surprised by the subtle rendering quirks and performance hiccups that simulators just don't catch.

Can I Create Animated And Interactive Charts?

You absolutely can, and you should. Static charts are a thing of the past; users now expect data to come to life. The top-tier libraries give you some powerful APIs to make this happen.

  • Animations: Victory Native integrates beautifully with react-native-reanimated, giving you smooth, fluid transitions when your data updates. It's what makes your charts feel truly dynamic and modern.

  • Interactivity: Adding event handlers like onPress to data points is straightforward. This is your go-to for implementing tooltips, highlighting a selected bar, or letting a user tap a pie slice to drill down into a more detailed screen.

When you combine smart animations with intuitive interactions, you create the kind of rich data experiences that really impress users.

The best interactive charts feel completely natural. A simple tap to reveal more info is all it takes. This lowers the user's cognitive load and makes complex data much easier to digest.

What Is The Best Way To Handle Large Datasets?

Throwing thousands of data points at a mobile screen is a surefire way to kill your app's performance. The screen will freeze, and your users will get frustrated. The golden rule is to never try rendering everything at once.

Instead, here are a few battle-tested strategies:

  1. Aggregate Your Data: Do the heavy lifting before the data even hits the chart. Group your raw data into more manageable chunks, like daily or weekly averages.
  2. Implement Windowing: Only render the data points that are currently visible on the screen. As the user pans or scrolls, you can lazy-load the next "window" of data.
  3. Use a High-Performance Engine: For really demanding, interactive visualizations, an SVG-based library might not cut it. This is where a GPU-accelerated engine like React Native Skia shines, handling complex rendering with incredible efficiency.

Ready to build and ship your Expo apps faster? The AppLighter starter-kit gives you a production-ready foundation with pre-configured authentication, navigation, and a powerful data layer. Stop wrestling with boilerplate and start building features that matter.