OpenCart Mobile App · 7 min read · Updated

OpenCart Mobile App Developer Guide, Part 2: Tools and Libraries, Why Expo, and the Development Environment

The tools and libraries behind the OpenCart mobile app, why Expo and React Native were chosen, and how to set up the local development environment.

OpenCart Mobile App Developer Guide, Part 2

This is part 2 of 5 of the OpenCart Mobile App Developer Guide. New to the project? Start with Part 1: Overview, Architecture, Repository Layout and Languages.

In this post


5. Tools and libraries, and why each was chosen

5.1 Mobile app

PackagePurposeWhy this one
expo (SDK 58)Toolchain, native runtime, dev server, build serviceSee §6.
react 19.3 / react-native 0.88UI frameworkOne code base for iOS and Android with truly native views (not a web page in a wrapper). React is the most widely known UI model, so new developers ramp up fast. The versions are the ones SDK 58 pins; keep them in step with Expo (see §17).
@tanstack/react-query v5Server-state cache: fetching, caching, refetching, pagination, mutationsAlmost all app data is server state (catalog, cart, orders). React Query gives caching, deduplication, loading and error flags, pull-to-refresh, infinite scroll and cache updates after mutations, with no hand-written reducers. It replaces Redux for this kind of app.
@react-navigation/native, native-stack, bottom-tabs v7NavigationThe standard for React Native. native-stack uses the platform’s real navigation controllers (native swipe-back and modal sheets). Navigation parameters are fully typed.
react-native-screensNative screen containersRequired by native-stack. Keeps hidden screens out of the render tree to save memory.
react-native-safe-area-contextNotch and home-indicator insetsCorrect padding on every device. Required by React Navigation.
expo-secure-storeEncrypted key-value storageHolds the session token, which is effectively a login credential. It uses the iOS Keychain and Android Keystore, unlike AsyncStorage, which is plain text.
react-native-webviewEmbedded browserUsed for (1) store HTML such as product descriptions and information pages, and (2) the online payment page, so any OpenCart payment gateway works without writing native code for each one.
@expo/vector-iconsIcon font (Ionicons)Bundled with Expo. No image assets to manage.
expo-status-barStatus bar styleSwitches light or dark icons to match the header colour.
expo-font, expo-assetFont and asset loadingNeeded by the vector icons under SDK 58.
typescript, @types/reactType checkingSee §4. npm run typecheck runs tsc --noEmit.
@babel/coreTranspiler used by MetroRequired by Expo’s bundler.

Deliberately not used:

  • Redux / Zustand. React Query plus one small Context covers it. Adding a global store would duplicate server state and invite stale data.
  • Axios. fetch is built in. All HTTP lives in one 150-line file (client.ts), so a library adds nothing.
  • A UI kit (NativeBase, Paper…). A small set of components in components/ui.tsx keeps the bundle small and the look fully under the store’s control, including the admin-set colours.
  • Form libraries. Forms are small. useState plus field errors from the server is enough, and the server is the source of truth for validation.

5.2 Backend and dev environment

ToolPurposeWhy
OpenCart 4.1.0.4 extension systemPackaging and installInstalls through the admin UI with no core file edits, so OpenCart upgrades don’t overwrite it. Uninstalling removes it cleanly.
OpenCart startup actionsRun code on every catalog requestThe supported hook point for swapping the session before controllers run (see §8.3). No core edits.
Docker Compose (php:8.3-apache, mariadb:11.4)Local storeThe same environment on every machine. The store runs on port 8090 because 8080, 8081 and 3307 were already taken on the original dev machine.
zip (build.sh)PackagingOpenCart’s installer expects a .ocmod.zip whose contents sit at the root. The zip’s file name becomes the extension code.

6. Why Expo

Expo is a framework and toolchain on top of React Native. For this project it was the right choice for these reasons:

  1. No native toolchain to start. You can develop on a real phone with only Node.js and the free Expo Go app: run npx expo start and scan the QR code. No Xcode or Android Studio is needed until you make a store build. Backend developers who mostly know PHP can still run and debug the app.
  2. One code base, both platforms, plus web. The same TypeScript runs on iOS and Android. npx expo start --web runs it in a browser, which is handy for quick API debugging. client.ts and PaymentScreen include small web fallbacks.
  3. Versioned, tested native modules. Each SDK release pins versions of React Native and its modules (SecureStore, WebView, screens…) that are tested together. npx expo install <pkg> picks the matching version, which avoids the usual native dependency conflicts.
  4. Cloud builds and store submission (EAS). eas build produces signed .ipa and .aab files on Expo’s servers, so you don’t need a Mac for iOS builds. eas submit uploads them to the stores.
  5. Over-the-air updates (EAS Update). You can push JavaScript-only fixes, such as a text change or a bug in a screen, to installed apps without a store review. Native changes still need a new build.
  6. Config plugins instead of editing native projects. Native settings, such as iOS App Transport Security (NSAllowsLocalNetworking) or the SecureStore setup, are declared in app.json. Expo generates the iOS and Android projects (expo prebuild), so there are no ios/ or android/ folders to maintain.
  7. Fast iteration. Fast Refresh keeps app state while you edit. npx expo start -c clears the bundler cache when things get confused.

Trade-offs to know about:

  • Expo Go supports only the newest SDK. That is why the project was upgraded to SDK 58: the App Store version of Expo Go showed “No usable data” for an older SDK QR code. If you add a library with custom native code that isn’t in Expo Go, switch to a development build (npx expo run:ios or eas build --profile development).
  • You follow Expo’s upgrade cadence (about three SDKs a year). See §17 for how to upgrade.

7. Development environment

7.1 Prerequisites

  • Node.js 20 or newer (the project has been run with Node 26).
  • Docker Desktop, for the local store.
  • Expo Go on your phone, or Xcode (iOS Simulator) or Android Studio (emulator).
  • The phone and computer on the same Wi-Fi network.

7.2 Start the store

cd opencart-mobile-app
docker compose up -d                 # web on :8090, db internal only
open http://localhost:8090/          # storefront
open http://localhost:8090/admin/    # admin (credentials in .env)

store/config.php and store/admin/config.php build HTTP_SERVER from the request’s Host header. The same store therefore works at localhost:8090 on your computer and at <your LAN IP>:8090 from the phone, and image URLs always point at an address the client can reach.

Port 8090 is published on all interfaces ("8090:80"), so anyone on your Wi-Fi can open the dev store and its admin. Don’t do this on a public network. To restrict it to your computer, change it to "127.0.0.1:8090:80". Phones will then no longer reach it.

7.3 Start the app

cd mobile
npm install
npx expo start -c        # -c clears the Metro cache; use it after changing config or dependencies

Scan the QR code with the iPhone Camera (it opens Expo Go) or from inside Expo Go on Android.

In src/config.ts, set baseUrl to your computer’s LAN IP. Find it with ipconfig getifaddr en0 on macOS. localhost on a phone means the phone itself. For the Android emulator use http://10.0.2.2:8090/.

7.4 Useful commands

CommandWhereWhat it does
npm run typecheckmobile/Type-checks the whole app
npx expo start -cmobile/Dev server with a clean cache
npx expo export --platform iosmobile/Builds a production JS bundle; a quick way to catch bundling errors
npx expo-doctormobile/Checks dependency versions against the SDK
sh opencart-extension/build.shrootRebuilds mobile_api.ocmod.zip
NODE_PATH=/tmp/oc-docs/node_modules node docs/build-html.cjsrootRebuilds the HTML guide (install marked first, see the script header)
NODE_PATH=/tmp/oc-docs/node_modules node docs/build-wordpress.cjsrootRebuilds the WordPress import (needs Chrome for the diagrams)
docker compose exec web php -l extension/mobile_api/<file>rootPHP syntax check inside the container
docker compose logs -f webrootApache and PHP errors

7.5 Editing the extension locally

The source of truth is opencart-extension/mobile_api/. The running store uses its installed copy in store/extension/mobile_api/. After editing, either copy the changed file across:

cp opencart-extension/mobile_api/catalog/controller/api/cart.php store/extension/mobile_api/catalog/controller/api/cart.php

…or rebuild the zip and reinstall it through the admin. Reinstalling resets the module settings, including the API key, so the copy approach is faster during development. Always commit the source folder, not the store/ copy.


← Previous: Part 1: Overview, Architecture, Repository Layout and Languages
Next: Part 3: The OpenCart Extension and the Mobile App →

The series

  1. Part 1: Overview, Architecture, Repository Layout and Languages
  2. Part 2: Tools and Libraries, Why Expo, and the Development Environment (you are reading this part)
  3. Part 3: The OpenCart Extension and the Mobile App
  4. Part 4: Design Patterns, Hooks and End-to-End Flows
  5. Part 5: Configuration, Security, Extending, Testing, Releasing and Troubleshooting
Rupak Nepali
Written byRupak Nepali

Author of four Opencart book.
The recent are Opencart 4 developer book and Opencart 4 user manual

Leave a Reply

Your email address will not be published. Required fields are marked *