How do you choose what goes in your package.json?
Is it based on what the team’s used before? What has the most GitHub stars? Or because some article on dev.to told you to use it? 😶
As a React (Native) Developer, this was something I never really thought about until TV development forced me to. Think about the performance gap between an iPhone and a Fire Stick - devices with 1GB of RAM don’t give you room for extra library 'costs'.
Why? Your library choices directly affect how fast your app feels to users because your JavaScript bundle size impacts Time to Interactive (TTI - how long it takes for the app to become fully interactive after the initial load), memory usage, and CPU usage during run time.
So while an extra 100KB might feel negligible on mobile, we’re rarely just building for mobile. Every library decision, gets amplified and can carry hidden ‘costs’ across the hardware spectrum our apps now have to support.
Let's take an example, a commonly suggested swap - moment.js for date-fns:
We can use bundlephobia.com to quickly check the ‘cost’ of adding a npm library to your bundle. Upon checking, it tells us moment.js clocks in at around 300KB, while date-fns is a much leaner 77KB:
Okay so we should definitely use date-fns right? 🧐
Well since I no longer trust anything on the internet 👀, I did some more digging. I added each package to a clean app and then analysed the actual JS bundle using Expo Atlas(you could also use react-native-bundle-analyzer) and something surprising happened. date-fns showed up as the larger library:
Wait — waat?
date-fns is architected as 300+ small utility files, each doing one thing. Now that’s great if your bundler is properly configured for tree shaking — it can strip out unused code, and only include what you call. But for React Native developers, like me, the metro bundler isn’t configured for tree shaking by default. Now while it is currently experimental with Expo, if you aren’t tree shaking, or your import patterns are off —
import * from 'library'
— you end up bundling all 300 files, whether you use them or not.
At this point your probably still like:
Okay, So?
Its just a few extra KBs, how bad can it be? Well I decided to measure what those extra KB’s did to my app’s perceived speed. I created a simple Android app using React Native & Expo and rendered the date using each library. I then used our Fire-OS perf testing tool to see how each library would perform on my Amazon Fire Stick. The results were 😲
Those 200KB increased our time to interaction (latency) from cold start by 3%:
Now this is just an example but this could be any library.
So here’s the thing, a library might look super helpful but it always comes at a cost. And with a broad spectrum of devices, those costs hit harder. So how can we weigh up the costs? Heres a my -
Checklist for adding a library
- First, as we saw, check the actual bundle size on your target platforms
- Then measure the performance cost
- And finally consider platform quirks e.g. FlashList might work on mobile but on TV platforms it might not have the functionality to handle the the dynamic, focusable content we have to deal with.
So don’t wait for the hidden costs to sneak up on your app performance.
Be deliberate. Be Critical. Every library in your package.json should earn its place 🏅



