← All projects

Marketplace

Best Project

Cross-platform mobile marketplace with adaptive dark/light theme, Firebase backend, real-time Firestore sync, and full i18n (EN/UK). Built with Expo SDK 54.

iOS · Android
ExpoReact NativeFirebaseTypeScriptZod
The Problem

Building a modern marketplace means choosing between costly native development for each platform or sluggish hybrid alternatives. Most solutions lack adaptive theming, feel heavy on mobile, and lock you into a single ecosystem without real-time capabilities.

The Solution

A cross-platform marketplace delivering native-quality experience on iOS, Android, and Web from a single Expo codebase. Features Firebase-powered real-time sync, seamless checkout flow, push notifications, and a polished adaptive theme that respects system dark/light mode preferences.

Architecture

Expo Router drives file-based navigation across 14+ screens with auth-guarded routing. Firebase handles authentication, Firestore provides real-time data sync via onSnapshot listeners. State is managed through React Context with custom hooks. Zod schemas ensure type-safe validation from registration to checkout.

Design System

A cohesive design system with a purple (#6055D8) accent, 16px border radius on inputs, pill-shaped buttons, and consistent spacing. Every component automatically adapts to system color scheme via useColorScheme. Eight skeleton variants ensure smooth perceived loading across all screens.

8
Key Features
5
Technologies
Best Project
iOS · Android
Platforms

Key Features

1

Real-time Sync

Firestore onSnapshot listeners keep products, cart, and orders in sync across devices instantly. No polling, no manual refresh.

2

Adaptive Theming

Automatic dark/light mode across all 14+ screens. System color scheme detection with smooth transitions and semantic token system.

3

Full i18n

English and Ukrainian translations powered by i18n-js with device locale auto-detection via expo-localization. Hot-switchable without app restart.

4

Type-safe Forms

Zod schemas + react-hook-form drive validation from auth to checkout. Shared type inference between validation logic and UI.

5

8 Skeleton Variants

Animated loading skeletons for products, banners, orders, cart rows, form sections, and more — no content flash, smooth perceived performance.

6

Push Notifications

Expo Push API + Firebase Cloud Messaging v1 for order updates and promotional alerts. System permission toggle with real-time feedback.

7

Auth Flow

Email/password login, Google Sign-In, password reset, and Telegram OIDC. Persistent sessions via AsyncStorage with automatic auth guard routing.

8

Promo System

Server-side promo code validation via Firestore. Configurable discount rates and expiration managed through Firebase Console.

Under the hood

Code
import { onSnapshot, doc, getDoc, setDoc, serverTimestamp } from 'firebase/firestore';

export const CartService = {
  subscribe(callback: (items: CartItem[]) => void): Unsubscribe {
    const uid = auth.currentUser?.uid;
    if (!uid) { callback([]); return () => {}; }
    return onSnapshot(doc(db, 'carts', uid), (snapshot) => {
      callback(snapshot.exists() ? (snapshot.data().items ?? []) : []);
    });
  },

  async upsertItem(item: CartItem): Promise<void> {
    const uid = auth.currentUser!.uid;
    const cartRef = doc(db, 'carts', uid);
    const snapshot = await getDoc(cartRef);
    const currentItems: CartItem[] = snapshot.exists()
      ? (snapshot.data().items ?? []) : [];

    const idx = currentItems.findIndex(i => i.id === item.id);
    if (idx >= 0) {
      currentItems[idx].quantity += item.quantity;
    } else {
      currentItems.push(item);
    }

    await setDoc(cartRef, { items: currentItems, updatedAt: serverTimestamp() });
  },
};

Gallery

Want to see more?

Explore the full project catalog or grab the source code.