Managing your monthly subscriptions shouldnโt be a mess of reminders and scattered notes. That's the idea behind SubXtract โ a thoughtfully designed subscription tracking app that helps users keep track of their recurring expenses in one simple place.
But behind the clean UI and user-friendly design lies a robust offline-first tech stack, built to ensure performance, reliability, and a delightful experience even without internet.
In this post, Iโll walk you through what SubXtract is, what tech powers it, and how I implemented key features using Expo, Zustand, MMKV, and Reanimated.
๐งน What is SubXtract?
SubXtract helps users:
- Track recurring subscriptions like Netflix, Spotify, Rent, etc.
- Add billing details like start date, cycle (monthly, yearly, etc.), and custom notes
- Set preferred currency and theme
- Toggle auto-renew status
- Archive old/canceled subscriptions
- Get notified about upcoming payments
- Use the app completely offline
With an elegant UI and local-first architecture, SubXtract focuses on privacy, speed, and user control.
๐ ๏ธ The Tech Stack
โก Expo
SubXtract is built with Expo for rapid development, native APIs out of the box, and easy deployment. I used the Bare workflow when necessary, especially for MMKV and notification features.
Why Expo?
- Fast iteration cycle
- OTA updates
- Great community ecosystem
๐ฆ Zustand + MMKV for Local-First State Management
SubXtract stores all user data locally on the device using a combination of Zustand (for state management) and MMKV (for super fast key-value storage).
๐ Setting up MMKV
// storage.ts
import { MMKV } from "react-native-mmkv"
export const storage = new MMKV()๐ง Zustand with Persistence Middleware
import { create } from "zustand"
import { persist } from "zustand/middleware"
import { storage } from "./storage"
export const useSubscriptionStore = create(
persist(
(set) => ({
subscriptions: [],
addSubscription: (sub) =>
set((state) => ({
subscriptions: [...state.subscriptions, sub],
})),
toggleRenewal: (id) =>
set((state) => ({
subscriptions: state.subscriptions.map((s) =>
s.id === id ? { ...s, autoRenew: !s.autoRenew } : s
),
})),
archiveSubscription: (id) =>
set((state) => ({
subscriptions: state.subscriptions.map((s) =>
s.id === id ? { ...s, archived: true } : s
),
})),
}),
{
name: "subxtract-store",
storage: {
getItem: storage.getString.bind(storage),
setItem: storage.set.bind(storage),
removeItem: storage.delete.bind(storage),
},
}
)
)This setup ensures lightning-fast access to your app's state, even when offline.
๐ญ Reanimated for Smooth Animations
To give users a fluid and polished experience, I used React Native Reanimated for subtle animations across components like the add/edit modal, theme transitions, and button presses.
๐ฎ Simple Reanimated Example
import Animated, {
useSharedValue,
withSpring,
useAnimatedStyle,
} from "react-native-reanimated"
const offset = useSharedValue(0)
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ translateY: withSpring(offset.value) }],
}
})๐ Custom Theming
Users can select between light, dark, or system themes. A Zustand store syncs the selected theme across the app, and I use context + MMKV to persist it.
export const useThemeStore = create(
persist(
(set) => ({
theme: "system",
setTheme: (theme) => set({ theme }),
}),
{
name: "theme-settings",
storage: {
getItem: storage.getString.bind(storage),
setItem: storage.set.bind(storage),
removeItem: storage.delete.bind(storage),
},
}
)
)๐ Local Notifications
SubXtract notifies users about upcoming payments based on their billing cycle. This is implemented using Expo Notifications and scheduled jobs at the time of adding a subscription.
๐ Check Out SubXtract on Product Hunt
If you like what you see, don't forget to check out SubXtract on Product Hunt and show your support!
๐ Coming Soon: Analytics + Budgeting
Iโm actively working on adding:
- ๐ธ Budget Cap Alerts
- ๐ Analytics and trends for monthly/yearly spend
- ๐๏ธ Upcoming view to filter subscriptions by due date
These features will make SubXtract even more powerful and insightful for users managing multiple recurring expenses.
โจ Final Thoughts
SubXtract is built with care to provide a fast, offline-first, and privacy-respecting experience for tracking subscriptions. Whether you're a minimalist user or someone who manages a dozen recurring payments, this app has you covered.
If you're curious to try it out, download it now on the App Store.
Thanks for reading! ๐
Happy tracking!




