Bosanet Xpress + Seller Portal · 2025 — present
Bosanet
Two separate front ends, two audiences, and one owner for both: a US marketplace and the seller portal behind it.
Context
Bosanet has two separate products with different users. Bosanet Xpress is the public marketplace where buyers in the United States purchase Latin American products. The Seller Portal is internal: sellers manage their onboarding with Bosanet, and the Bosanet team runs that same onboarding and tracks sales and metrics.
They are built and maintained separately. On Xpress I own performance and user experience. On the Portal I own design-system consistency across the seller view and the internal operations view, the experience for both, and the dashboards they use to make decisions.
Public marketplace · US buyers
Bosanet Xpress
Separate product. Performance and UX for the storefront: catalog, search and the cargo page used to plan a purchase.
Internal · sellers and Bosanet operations
Seller Portal
Separate product. Onboarding management, sales metrics and dashboards for the seller view and the internal view.

My role
Front-end Developer & Designer across two separate products: performance and UX on Xpress, design system and dashboards inside the Portal.
- Own performance and user experience on Bosanet Xpress.
- Unifying the Portal's design system across the seller view and the internal operations view.
- Built the metric dashboards used to run seller onboarding and track sales.
- Wrote 9,806 lines of charting code with memoized hooks for heavy logistics datasets.
Decisions
Unify the seller view and the internal view behind one design system
- Constraint
- Inside the Portal, the seller-facing view and the internal operations view implemented the same tables, filters and metrics twice. @components/redesign and @components/ui both exported components, so the two views drifted apart.
- Options
- Keep one system per view and document the difference
- Adopt an external design system
- Merge both into a single @components/ui layer (FEP-1)
- Choice
- Merge into one layer, with tokens, primitives and composed components in one hierarchy.
- Why
- The seller and the internal team run the same process from opposite sides. One system gave both views the same vocabulary without merging the screens themselves.
Migrate by strangling, not by rewriting
- Constraint
- 283 files still imported MUI while the team shipped weekly. A big-bang migration would have frozen the Portal.
- Options
- Rewrite every screen in one branch
- Codemod all MUI imports at once
- Migrate each screen when it is touched
- Choice
- Strangler migration: new and touched screens use the design system, old ones keep working.
- Why
- Adoption reached 232 files (~45%) with no release freeze. The cost is honest: 45% is not done, and the remaining MUI surface is now the largest piece of debt.
Different dashboards for two different readers
- Constraint
- Sellers need their own onboarding status; internal operations need the whole portfolio. A single dashboard for both hid what each one needed to decide.
- Options
- One dashboard with role-based filters
- Two dashboards with duplicated logic
- Shared chart hooks with two compositions
- Choice
- Extract useMonthlyChart, useCumulativeView, useYearComparison and useOrderedRegions, all memoized, then compose a screen per audience.
- Why
- The data transformations became consistent once; the screens stayed specific to who reads them. Sharing the math is not the same as sharing the product.
Performance on Xpress: fix the critical path, not the page
- Constraint
- The marketplace cargo page took ~10s to become usable. The page itself was fine; its dependencies were not.
- Options
- Buy a bigger CDN tier
- Rewrite the page from scratch
- Audit scripts, bundles and CSS delivery
- Choice
- Remove unnecessary scripts, split JavaScript and CSS bundles, and adopt above-the-fold styles.
- Why
- Load dropped from 10s to 4s — a 60% reduction — without a rewrite. The page was not slow because of its code; it was slow because of what it loaded first.
Outcome
The Portal's design system is now the default for new work: 232 files on it, 31 components and 17 test files, covering both the seller view and the internal view. Xpress is a separate codebase; there, the cargo page went from 10s to 4s. Over the period I shipped 464 commits and 99 merged pull requests.
- 232
- files on the Portal's design system (~45% off MUI)
- 31
- components covering the seller and internal views
- 17
- test files for UI components
- 10s → 4s
- Xpress cargo page load (separate product, −60%)
Lessons
- The marketplace and the Portal are separate products. Sharing one design system across both would have been the wrong abstraction; the right boundary was inside the Portal, between two views of the same process.
- Building the components was the easy half. Adoption is the product: a design system only its author uses is a private library.