Klark Mobile
iOS & Android mobile app for the Klark platform
5K+
Active users
4.9/5
Rating
< 500ms
Sync time
Stack technologique
Background
Following the success of the Klark web platform, field teams at Klark Industries needed access to their business data on the go — in factories, while traveling, and on job sites. The web dashboard wasn't suited for mobile screens, and some industrial sites had limited connectivity.
The mission: develop a native iOS & Android mobile app providing quick access to KPIs, real-time push notifications, and a full offline mode for environments with limited connectivity.
Technical Challenges
Offline-First Architecture
Industrial sites often have unreliable connectivity. The application had to work in offline mode and synchronize data as soon as connectivity was restored.
// hooks/useOfflineSync.ts
import { useEffect, useCallback } from "react";
import NetInfo from "@react-native-community/netinfo";
import { syncQueue } from "../lib/sync-queue";
export function useOfflineSync() {
const syncPendingOperations = useCallback(async () => {
const pending = await syncQueue.getPending();
if (pending.length === 0) return;
for (const op of pending) {
await api.post(`/sync/${op.collection}`, op.data);
await syncQueue.markCompleted(op.id);
}
}, []);
useEffect(() => {
const unsubscribe = NetInfo.addEventListener((state) => {
if (state.isConnected && state.isInternetReachable) {
syncPendingOperations();
}
});
return unsubscribe;
}, [syncPendingOperations]);
}Mobile Dashboard with Interactive Charts
Adapting the complex web dashboards to mobile screens while keeping interactivity. We used React Native Skia for performant GPU-rendered charts.
// components/MetricCard.tsx
import { Canvas, RoundedRect, LinearGradient } from "@shopify/react-native-skia";
import Animated, { useSharedValue, withSpring } from "react-native-reanimated";
export function MetricCard({ metric }: { metric: Metric }) {
const scale = useSharedValue(1);
return (
<Animated.View style={useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}))}>
<Pressable
onPressIn={() => { scale.value = withSpring(0.97); }}
onPressOut={() => { scale.value = withSpring(1); }}
>
<View className="bg-zinc-900 rounded-2xl p-4">
<Text className="text-zinc-400 text-sm">{metric.label}</Text>
<Text className="text-white text-2xl font-bold">{metric.value}</Text>
<SparklineChart data={metric.history} />
</View>
</Pressable>
</Animated.View>
);
}Smart Push Notifications
Alerts are personalized based on user role and organization-configured thresholds. A manager gets notified if daily revenue drops by more than 15%, an operator is alerted when an anomaly is detected on their production line.
// functions/src/notifications/alert-engine.ts
export async function evaluateAlerts(orgId: string, metrics: MetricSnapshot) {
const rules = await getAlertRules(orgId);
for (const rule of rules) {
const currentValue = metrics[rule.metricKey];
const threshold = rule.threshold;
if (rule.condition === "below" && currentValue < threshold) {
await sendPushToRole(orgId, rule.targetRole, {
title: rule.alertTitle,
body: `${rule.metricLabel}: ${currentValue} (threshold: ${threshold})`,
});
}
}
}Deployed Solution
The app is built with Expo (managed workflow) for fast OTA updates. It communicates with the existing Klark API via tRPC, with a local SQLite cache layer for offline mode. Push notifications go through Firebase Cloud Messaging with intelligent routing by role and organization.
SSO authentication is shared with the web platform via a common JWT token, enabling a seamless experience between both interfaces.
Results
Launched in January 2026, the app was adopted by 5,000 active users in under 2 months. The average rating is 4.9/5 on both stores. Time to access KPIs went from several minutes (opening a laptop + VPN connection) to under 3 seconds. Field teams report significant productivity gains thanks to contextual push alerts.