JournalCase StudyMar 25, 2025

Building Carrybee from Zero to Production.

A case study in leading end-to-end frontend architecture for a logistics platform — the decisions that shaped the system, the patterns that scaled it, and the trade-offs that kept it honest.

14 Min Read
Building Carrybee from Zero to Production.

There is a particular kind of pressure that comes with building something from nothing. No legacy to lean on, no prior art to reference — just a blank repository and a deadline that does not care about your architectural ambitions. Carrybee was that project.

The brief was deceptively simple: build the frontend for a logistics platform that connects shippers with carriers. The reality was a system of deeply nested workflows — booking flows, real-time tracking, multi-role dashboards, document management — each demanding its own patterns while sharing a single design language.

I chose Next.js with the App Router. Not because it was trendy, but because the platform demanded both static marketing pages and highly dynamic authenticated views. Server components handled the public-facing content. Client components managed the interactive dashboards. The boundary between them became the project's most important architectural decision.

The component system was built on Shadcn UI — not as a shortcut, but as a foundation. Every primitive was extended with logistics-specific variants: status badges with color-coded delivery states, timeline components that visualized shipment progress, data tables that handled thousands of rows without pagination becoming a performance cliff. The investment in this library paid for itself within weeks. New features that would have taken days started shipping in hours.

State management was deliberately minimal. React Query handled all server state — booking data, carrier listings, tracking updates. Local state stayed local. No global store, no Redux, no Context providers wrapping the entire tree. The constraint felt limiting at first, but it forced every component to be explicit about its data dependencies. Six months in, any engineer could open any component and understand exactly where its data came from.

TypeScript was strict from day one. Not the permissive kind where half the codebase is typed as `any` and the other half pretends the compiler does not exist. Strict null checks. No implicit any. Discriminated unions for every API response. The type system became the project's first line of defense — catching integration errors at compile time that would have otherwise surfaced as production incidents.

The hardest decision was not technical. It was resisting the urge to over-engineer. A logistics platform invites complexity — real-time WebSocket connections, optimistic updates, offline-first capabilities. We built none of these in the first release. We shipped polling. We shipped loading states. We shipped the simplest thing that could work, and then we measured. The metrics told us where to invest next, not our assumptions.

Carrybee launched on schedule. The frontend serves thousands of daily active users across desktop and mobile. The codebase remains maintainable because we treated architecture not as a blueprint drawn before construction, but as a living discipline practiced throughout it.

The lesson was not new, but it was deeply reinforced: the best frontend architecture is not the most sophisticated one. It is the one your team can understand, extend, and trust.