
World Ex Ltd.
How we moved a 20-year-old specialist postal service off a legacy WordPress theme and onto a custom multilingual platform — marketing site, customer portal, full operations console, and admin layer — built from scratch on a modern, type-safe stack.
A specialist courier built around a single trade lane — and the legacy stack holding it back.
World Ex Ltd. has spent two decades doing one thing exceptionally well: moving parcels from Canada to Armenia and Georgia. They aren't a generic carrier. They are the carrier their diaspora customers trust to get a box of essentials, gifts, or documents from Toronto to Yerevan or Tbilisi — fast, intact, and at a fair price.
The brand was strong. The service was loved. The technology, however, was stuck. The website was a Sage-based WordPress theme that had grown organically over years — content scattered across plugins, a fragile theme, no real customer accounts, no shipment-level data model, and an internal team running operations on spreadsheets, paper manifests, and a Word-template label printer.
We were not asked to redesign the brand. We were asked to rebuild everything underneath it.

Replace a tangled WordPress theme with a single platform that runs the public site, the customer experience, and the entire back-office — without losing 20 years of customer trust during the switch.
A multilingual marketing site that earns trust in five languages.
WorldEx's customers don't all read English. We rebuilt the public site as a fully localised experience — English, Armenian, Georgian, Russian, and French — with locale-aware routing, SEO, and content. Every page is server-rendered, edge-cached, and ships with sub-second TTFB on every continent the brand serves.
- Five locales, one codebaseEN / HY / KA / RU / FR — full content parity, locale-prefixed URLs, hreflang done right
- Live quote calculatorCustomers price a shipment in seconds — destination, weight, and surcharges resolved against the live country pricing table
- Drop-off locatorAn interactive Leaflet map showing every drop-off point, with directions and locale-aware addresses
- Public parcel trackingCustomers track a shipment without an account using the human-readable tracking ID — full status timeline rendered server-side
- Performance-first buildReact Server Components, partial prerendering, image optimisation, and edge caching on Vercel

Accounts, history, and a real relationship with the brand.
The legacy site had no concept of a customer account. We introduced one — built on Supabase Auth with email, magic-link, and OAuth sign-in, optional MFA, and a clean self-serve account area. Customers now have a permanent home for their shipments, addresses, preferences, and documents.
- Modern authEmail + password, magic link, OAuth providers, password reset, and TOTP-based MFA — all on Supabase Auth with SSR cookie sessions
- Personal shipment historyEvery parcel a customer has ever sent or received, with full status timelines and exportable receipts
- Profile + securityAvatar uploads via Supabase Storage, password rotation, MFA enrolment, and locale preference per user
- Transactional emailBranded React Email templates delivered via Resend — sign-up, magic link, MFA, status changes, and shipment receipts


Behind every parcel is a courier team that has to receive it, label it, group it onto a manifest, ship it across an ocean, and hand it to a partner on the other side. We rebuilt that entire workflow.
Parcels, manifests, labels, and exports — the core of the business, rebuilt from zero.
We replaced spreadsheets and Word-template labels with a purpose-built operations console. Staff now receive parcels into the system, generate compliant labels with on-the-fly barcodes, group shipments into manifests, and export everything that customs and partner carriers need — without leaving the app.
- Parcel intakeAuto-populated forms, customer search, content categorisation, weight/size unit toggles (kg/lbs, cm/in), and human-readable display IDs (e.g. WXP000042)
- Label generationServer-rendered PDF shipping labels with embedded Code-128 barcodes — generated on demand via @react-pdf/renderer and bwip-js, printed straight from the browser
- Manifest builderBundle parcels into outbound manifests, change manifest status (draft → shipped → arrived → closed), and export the whole thing as a customs-ready PDF or Excel sheet
- Status timelinesEvery state change is captured in a parcel-status history table — the customer-facing tracking timeline is the same data, simply filtered for the public
- CSV / Excel exportsParcels, customers, manifests, and the audit log all exportable on demand via ExcelJS and Papaparse — gated by role
- Customer databaseFull CRUD with linked user accounts, search, dedupe, and a contents multi-select for parcel content declarations


Five-tier RBAC, audit logging, and feature flags — built in from day one.
A platform that handles real money, customer PII, and customs paperwork has to be defensible. We built a centralised permissions matrix that the UI and the API both import from — there is no version of "the API forgot to check" because the same function answers both questions. Every privileged action writes an audit event. MFA is enforceable per user with a deadline.
- 5-tier RBACsuper_admin → admin → manager → staff → user. Single permissions matrix shared between Server Components, Server Actions, and route handlers
- User managementInvite, suspend, role-change, and impersonate (super-admin only) — with display IDs and per-user MFA enforcement deadlines
- Audit logEvery privileged mutation persisted to the audit_events table — searchable, filterable, exportable for compliance reviews
- Feature flagsDatabase-backed flags managed from the admin UI — staff-only previews, gradual rollouts, instant kill-switches
- Country pricing engineAdmins manage destinations, ISO codes, first-kg / additional-kg / fee structures — quotes and labels read from the same source of truth
- Newsletter & contentNewsletter signup capture with admin-only export, content category management for parcel declarations, and tracking-code pool administration

Off WordPress. Onto a modern, type-safe, edge-rendered platform — with a single shared schema running through the marketing site, the portal, and the operations console.
A monorepo, one schema, end-to-end type safety.
We migrated WorldEx off a Sage-based WordPress theme and onto a pnpm-workspace monorepo running on Next.js 15 with the App Router, React 19, React Server Components, and Server Actions. Drizzle gives us a single Postgres schema that's authoritative across the app, the database, and the Zod contracts that validate every form and route.
- Monorepo, shared packagesapps/web (Next.js) plus packages/db (Drizzle), packages/auth (Supabase wrappers + permissions), packages/schemas (Zod), packages/ui (shadcn primitives), packages/config
- Postgres + DrizzleStrict typed schema covering users, customers, parcels, manifests, countries, tracking codes, audit events, feature flags, and translations — Supabase in production, Docker locally
- Data migration from MySQLA bespoke seed-from-mysql script ported customer records, historical parcels, and pricing tables out of the legacy WordPress database with zero data loss
- Edge-first performanceRSC + Server Actions on Vercel — no client-side data-fetch waterfalls, sub-second navigations, and dramatically smaller JS payloads than the legacy WP site
- ObservabilitySentry for errors, Axiom for structured logs, Vercel Analytics for real-user metrics — everything routed to a single ops Slack channel

We continue to ship features on a sprint cadence — managing the deploy pipeline, the Supabase project, the email infrastructure, and every feature request the WorldEx team submits.