The Problem

Companies building a mobile‑first storefront often need a single code base that delivers a React Native app, an admin web UI, and a REST API. Coordinating authentication, product CRUD, cart handling, and payment integration across three separate runtimes creates duplication and hidden coupling, making onboarding and maintenance costly.

What This Does

The repository implements a full‑stack e‑commerce solution split into three workspaces:

  • mobile/ – React Native (Expo) app with screens for authentication, product browsing, cart, orders, addresses, and wishlist. Core UI lives in mobile/components/*.tsx and data fetching in mobile/lib/api.ts.
  • admin/ – Vite‑powered React dashboard (admin/src/App.jsx) that consumes the same API. Pages such as admin/src/pages/ProductsPage.jsx and admin/src/pages/OrdersPage.jsx provide CRUD UI for products, orders, and customers.
  • backend/ – Express server (backend/src/server.js) exposing routes under backend/src/routes/*.js. Controllers (e.g., backend/src/controllers/product.controller.js) implement business logic, while backend/src/config/db.js defines the connectDB function that opens a MongoDB connection via Mongoose.

All three layers share a common authentication layer (Clerk) and payment processing (Stripe). The admin and mobile front‑ends call the API endpoints defined in backend/src/routes/.

How It Is Wired

Execution begins at backend/src/server.js:64 where startServer is invoked. startServer calls connectDB (defined in backend/src/config/db.js) which performs mongoose.connect – the sole external side effect (database connection). The internal call graph shows connectDB being referenced by three callers (syncUser, deleteUserFromDB, startServer).

From the server entry point, the request flow is:

  1. Express router matches a path (e.g., /api/products) → loads the corresponding controller (backend/src/controllers/product.controller.js).
  2. Controller functions (createProduct, getAllProducts, etc.) invoke Mongoose models (backend/src/models/product.model.js) to read/write MongoDB.
  3. Responses travel back through the router to the client.

The admin UI’s entry point is admin/src/App.jsx, which imports admin/src/lib/api.js. API calls use Axios to hit the backend URL (VITE_API_URL from .env). The mobile app starts at mobile/app/(auth)/index.tsx, which triggers Clerk authentication and then uses mobile/lib/api.ts (TanStack Query) to fetch data from the same backend.

Hot spots:

  • backend/src/controllers/admin.controller.js and backend/src/controllers/user.controller.js each expose >7 functions, making them high‑impact change points.
  • backend/src/config/db.js is the only file that touches the database directly (via connectDB).
  • The import graph shows no circular dependencies, but the most connected module (backend/src/server.js) imports ten others, indicating a central coordination role.

Code quality signals: duplicated six‑line blocks appear across admin pages and backend models, and several files have nesting depth up to seven, which hampers readability.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/expo-ecommerce
cd expo-ecommerce

# Backend
cd backend
npm install            # installs deps, creates lockfile if missing
npm run dev            # starts Express on PORT (default 3000)

# Admin dashboard
cd ../admin
npm install
npm run dev            # Vite dev server, typically http://localhost:5173

# Mobile app
cd ../mobile
npm install
npx expo start         # QR code for physical device or emulator

Create three .env files as described in the README (backend, admin, mobile) and supply keys for Clerk, Stripe, Cloudinary, Inngest, and Sentry. The admin UI expects VITE_API_URL to point at the backend (http://localhost:3000/api).

Real‑World Use

A retailer could deploy the backend to a cloud VM, host the admin UI on a static site (Vite build), and ship the Expo app to iOS/Android stores. The mobile app authenticates with Clerk, fetches products via /api/products, adds items to the cart using mobile/hooks/useCart.ts, and completes checkout through the Stripe‑backed /api/payments endpoint. Admin staff manage inventory via admin/src/pages/ProductsPage.jsx, which calls the same API.

Code Health & Issues

  • HIGH – No LICENSE (root) – legal reuse undefined.
  • HIGH – No test suite (entire repo) – regressions unchecked.
  • HIGH – Missing root lockfile (package.json) – potential dependency drift.
  • HIGH – No CI workflow (root) – builds not automatically verified.
  • MEDIUM – Dependabot not configured (root) – vulnerable deps stay unpatched.
  • LOW – Missing repo conventions (.editorconfig, .gitattributes, formatter) – inconsistent style.
  • HIGH – Duplicated code blocks (admin pages, backend models) – DRY violation.
  • MEDIUM – Deep nesting (max depth 7) (admin pages) – hard to follow logic.

The Bottom Line

The repo provides a ready‑to‑run, three‑tier e‑commerce stack with clear separation of concerns, but it lacks the engineering safeguards (tests, CI, license) needed for production confidence. It is suitable for proof‑of‑concepts or teams willing to invest in test coverage and refactoring of duplicated UI logic.