How I architected an OTT streaming platform that ships to web, mobile, four TV OSes, and a Tauri desktop admin from one Nx monorepo.
I discovered the problem the painful way: the legacy Prachyam codebase had duplicated auth logic in at least four places. A subscription-state fix in one place didn't propagate to the mobile app because mobile had its own copy of the same function — slightly different, written by a different developer two years prior. Before I could add any new platform surfaces, I had to fix the same bug in multiple places.
That's the failure mode a monorepo is designed to prevent. So when the Sangam rewrite started, the architecture question was decided before the first commit.
Prachyam Studios needed a streaming platform across nine surfaces: web, iOS, Android, Apple TV, Android TV, Samsung Tizen, LG webOS, a Tauri desktop admin, and a docs site.
Building separate codebases for each platform? That's nine repos with duplicated business logic, diverging APIs, and the same auth bug appearing in four places all over again.
Nx gives you a monorepo with intelligent build caching, dependency graph awareness, and the ability to share code across projects. Combined with Expo / React Native (for mobile and the Apple TV / Android TV apps via Expo TV), vanilla-JS builds for Samsung Tizen and LG webOS, Next.js for web, and Tauri for the desktop admin, it was the right tool. Nx's executor model also handled the Tauri build's separate toolchain in a way Turborepo's pipeline didn't fit cleanly.
apps/
web/ # Next.js web app
mobile/ # Expo / React Native (Android + iOS)
tv-expo/ # Expo TV (Apple TV + Android TV)
tv-tizen/ # Samsung Tizen (vanilla-JS build)
tv-webos/ # LG webOS (vanilla-JS build)
admin/ # Tauri desktop admin
docs/ # Docs site
libs/
shared/
api/ # API client, auth, types
ui/ # Shared UI components
hooks/ # Custom hooks (usePlayer, useAuth, etc.)
utils/ # Helpers, formatters, validators
constants/ # Config, feature flags
platform/
tv-navigation/ # TV-specific D-pad navigation
mobile-gestures/ # Touch gesture handlersThe key insight: 80% of the code is platform-agnostic. Authentication, API calls, state management, business logic, types — all shared. Only the rendering layer and platform-specific features differ.
// libs/shared/hooks/usePlayer.ts
export function usePlayer(contentId: string) {
const [state, dispatch] = useReducer(playerReducer, initialState);
const api = useApiClient();
const play = useCallback(async () => {
const stream = await api.getStream(contentId);
dispatch({ type: 'PLAY', payload: stream });
}, [contentId, api]);
const pause = useCallback(() => {
dispatch({ type: 'PAUSE' });
}, []);
return { ...state, play, pause };
}This hook works everywhere — the platform-specific player component just wraps the native video implementation (ExoPlayer on Android, AVPlayer on iOS, etc.).
TV apps don't have touch or mouse — they have a D-pad (up, down, left, right, select). I built a shared navigation system:
// libs/platform/tv-navigation/useFocusGrid.ts
export function useFocusGrid(rows: number, cols: number) {
const [focused, setFocused] = useState({ row: 0, col: 0 });
const handleKey = useCallback((direction: Direction) => {
setFocused(prev => {
switch (direction) {
case 'up': return { ...prev, row: Math.max(0, prev.row - 1) };
case 'down': return { ...prev, row: Math.min(rows - 1, prev.row + 1) };
case 'left': return { ...prev, col: Math.max(0, prev.col - 1) };
case 'right': return { ...prev, col: Math.min(cols - 1, prev.col + 1) };
}
});
}, [rows, cols]);
return { focused, handleKey };
}Nx's computation cache was a game-changer. A full build of all nine apps from scratch takes ~15 minutes. But with cache hits, pushing a change to the shared API layer and rebuilding all affected apps takes under 2 minutes.
# Only rebuilds what changed
npx nx affected --target=build
# Remote cache for CI (with Nx Cloud)
npx nx run-many --target=build --all --parallel=4usePlayer breaks, it breaks everywhere.The monorepo approach isn't free, but for multi-platform products, the alternative is far more expensive.
Karanveer Singh Shaktawat
Full Stack Engineer & Infrastructure Architect
I build production systems across web, mobile, and infrastructure — then document what went wrong and why.
Pick what you want to hear about — I'll only email when it's worth it.
Did this resonate?
How I architected a full-stack OTT streaming platform for web, mobile, four TV OSes, and a desktop admin panel — solo, in one Nx TypeScript monorepo — and what I'd do differently.
How I designed the code structure for a streaming platform targeting Next.js web, Expo/React Native iOS/Android, Apple TV, Android TV, Samsung Tizen, LG webOS, and a Tauri desktop admin — shared business logic, platform-specific UI, one Nx repo.