Portfolio/Writing/The UX nobody sees: designing an e-commerce back-office that people can actually work in

The UX nobody sees: designing an e-commerce back-office that people can actually work in

Consumer UX advice optimises for first impressions. E-commerce operations optimise for product readiness, speed and consistency: suppliers, NGPs, categories, gender, stock, campaigns and the long pipeline before a product goes live.

Somewhere, a customer is about to see a perfectly ordinary product card: a shoe, a title, a price and a reassuringly clickable button.

What they do not see is the small bureaucratic opera that happened before that moment. A supplier sent a feed. An NGP was created. Someone mapped a category. Someone else fixed the gender. Images were checked. Stock was reconciled. Attributes were enriched. Rules argued with each other. A campaign decided whether the product was invited. Only then did the product earn the right to exist on the website.

The invisible pipeline
A product does not simply appear on an e-commerce site
01INPUT
Supplier
Merchant sends product data
02INGEST
NGP
Products enter the pipeline
03EDIT
Enrichment
Category · Gender · Attributes
04CHECK
Validation
Images · Stock · Price · Rules
05PREPARE
Campaign
Eligible and scheduled
06PUBLISH
Live
Customer sees the product
!A failure anywhere in the pipeline can prevent a product from reaching the customer.
The customer sees the last box. Back-office users deal with everything before it.

This is why I find generic advice about design systems slightly suspicious. Most of it assumes you are designing for someone browsing for a few minutes. In operational e-commerce, the user might spend eight hours moving through suppliers, products, categories, campaigns and validation queues. They are not exploring. They are trying to get 847 things ready before someone asks why the campaign is still blocked.

What I mean by back-office
The operational machinery behind e-commerce: supplier and merchant onboarding, catalogue enrichment, NGPs, category and gender mapping, stock, pricing, campaign preparation, validation and publication. The customer sees the result. Operators live inside the process.

Back-office is a different design problem#

Consumer interfaces and operational interfaces disagree on nearly every default. Import the instincts of one into the other and you get a lovely interface that quietly makes experienced users slower.

Consumer product instinctOperational e-commerce reality
Brand expression is everywhereBrand gets out of the way; status and data carry meaning
Generous whitespaceHigh information density
One primary actionMany actions, often in bulk
A table is a componentA table is an operational subsystem
A product is contentA product is a state machine
Visitors stay for minutesOperators work for hours
Redesign every few yearsThe system needs to survive organisational archaeology
Before the design system
Four teams. Four tables. One confused user.
TEAM 1
Catalogue
Table A
SelectCheckbox
StatusAmber
PagingPages
TEAM 2
Campaigns
Table B
SelectRow click
StatusYellow
PagingInfinite
TEAM 3
Stock
Table C
SelectCheckbox
StatusOrange
PagingPages
TEAM 4
Pricing
Table D
SelectShift-click
StatusGold
PagingVirtual
What the system should provide
One interaction model. Shared behaviour. Different domains.
The user experiences one operational ecosystem. They do not care that four teams built it.

Density is a decision, not a smaller padding token#

Here is a recurring UX conversation: someone looks at an operational table and says, "It feels crowded." The operator looks back, because they have 800 SKUs to validate before lunch, and wonders if the whitespace is going to help.

The density argument
"It feels crowded" depends on what you are trying to do
The design review
"It feels a little crowded."
4 products visible
Plenty of breathing room
Monday, 09:12
"I need to validate 800 SKUs."
SKUProductGenderStatus
SKU-847293Running shoeWomenReady
SKU-847294Trail shoeMenReady
SKU-847295Leather bootWomenBlocked
SKU-847296Canvas sneakerUnisexReady
SKU-847297Sport sandalWomenMissing
SKU-847298Winter bootMenReady
SKU-847299City runnerWomenReady
SKU-847300Classic trainerMenBlocked
SKU-847301Walking shoeWomenReady
SKU-847302Gym trainerUnisexMissing
10 products visible
The operator can actually work
Density is not about fitting more pixels on a screen. It is about reducing unnecessary interaction for people who know what they are doing.

Density is not about cramming more things into a rectangle. It is about reducing unnecessary interaction while preserving hierarchy.

  • A tight spacing scale with a 4px base.
  • A smaller base font when the domain supports it.
  • Rows around 32–40px for repetitive operational work.
  • A real comfortable/compact density mode driven by tokens.
  • Keyboard navigation that makes dense interfaces faster, not harder.
data-density="comfortable" · 44px rows
ReferenceCustomerTotalStatus
ORD-8891Ada Lovelace€128.40Processing
ORD-8892Alan Turing€64.00Shipped
ORD-8893Grace Hopper€212.90Refunded
ORD-8894Edsger Dijkstra€19.99Draft
data-density="compact" · 32px rows
ReferenceCustomerTotalStatus
ORD-8891Ada Lovelace€128.40Processing
ORD-8892Alan Turing€64.00Shipped
ORD-8893Grace Hopper€212.90Refunded
ORD-8894Edsger Dijkstra€19.99Draft
The same table at both density settings. One data attribute on the shell flips a token group (row height, control height, row gap); no component re-implements it.
Dense is not crammed
Density requires better hierarchy, not less hierarchy. At small sizes, alignment, weight, semantic colour and consistent column behaviour have to work harder.

A product is not ready because someone says it is#

In an e-commerce back-office, "ready" is usually a computed conclusion. Category complete. Gender mapped. Required attributes present. Images valid. Stock available. Price valid. Campaign eligible.

Product readiness
One SKU. Six reasons it might not go live.
SKU-847293 · NGP-2026-091
Running shoe — Navy
Supplier: ACME SPORT · Campaign: SUMMER-26
INCOMPLETE
Category✓ Women › Shoes › Sneakers
Gender✓ Female
Images× Missing 2
Stock✓ 1,284 units
Price✓ €89 → €59
Attributes✓ Complete
Publication result
BLOCKED
Missing mandatory product images
A publication state is usually the result of multiple systems and validation rules agreeing that a product is ready.

This changes the UX problem. A good interface does not merely show a status. It helps the operator understand why something is blocked and what needs to happen next. A red badge saying INCOMPLETE is not useful if the user still has to visit six screens to find the missing image.

The table is a subsystem, so treat it like one#

Most operational e-commerce screens are a list and something you need to do to that list. Products by supplier. SKUs by campaign. Stock by warehouse. NGPs by state. If the system ships a thin wrapper around<table>, every team eventually rebuilds the rest.

  • Column types: text, number, currency, date, status and custom.
  • Filtering across supplier, category, gender, campaign and state.
  • Sort, hide, reorder, resize and pin columns.
  • Selection across pages and honest bulk-action counts.
  • Bulk validation and partial failure states.
  • Loading, empty, no-results and error states as distinct concepts.
  • Saved views because operators should not rebuild the same filters every morning.
The operational workspace
This is why "just a product list" becomes complicated
Products12,847
FiltersColumnsExport
NGP-2026-091 ×Summer campaign ×Status ≠ Ready ×
SKU ↕SupplierCategoryGenderStockStatus
847293Sport Co.SneakersWomen1,284READY
847294Sport Co.Men842BLOCKED
847295NorthlineBoots0INCOMPLETE
847296Urban Ltd.SneakersUnisex412READY
847297NorthlineSandalsWomenMISSING DATA
347 products selected
Different roles interrogate the same dataset in different ways. The system needs to support the work, not just render rows.
DataTable
2 selected
Reference CustomerTotalStatus
ORD-8891Ada Lovelace€128.40Processing
ORD-8892Alan Turing€64.00Shipped
ORD-8893Grace Hopper€212.90Refunded
ORD-8894Edsger Dijkstra€19.99Draft
Loading
Empty
📭No orders yetNew orders show up here as they arrive.
No results
🔍Nothing matches this filterTry widening the date range.
Error
⚠️Could not load ordersThe request timed out.
One organism, assembled from the atoms and molecules above: selection, a sorted column, currency alignment, status chips, per-row actions, a bulk bar, and the four states every list has to handle.

Build the behaviour once on a headless core and own the defaults. The API should describe data and intent rather than force every screen author to invent interaction patterns again.

tsx
<DataTable
  data={products}
  columns={[
    { id: 'ngp', header: 'NGP', accessor: 'ngp', pin: 'left' },
    { id: 'supplier', header: 'Supplier', accessor: 'supplier.name' },
    { id: 'category', header: 'Category', accessor: 'category.path' },
    { id: 'gender', header: 'Gender', accessor: 'gender' },
    { id: 'stock', header: 'Stock', accessor: 'stock', type: 'number', align: 'end' },
    { id: 'status', header: 'Readiness', accessor: 'status', type: 'status' },
  ]}
  bulkActions={[
    { label: 'Assign category', onSelect: assignCategory },
    { label: 'Validate selected', onSelect: validateProducts },
  ]}
  savedViewsKey="catalogue.products"
/>

Forms are the second subsystem#

The same applies to forms. An operator creating or enriching products does not need a magical onboarding experience every time. They need labels, predictable tab order, visible validation and a fast route through fields they already understand.

  • Dense multi-column layouts with deliberate keyboard order.
  • Labels always visible; placeholders are not documentation.
  • Validation on blur rather than punishment on every keystroke.
  • Server errors mapped back to the fields that caused them.
  • Unsaved-change protection for long enrichment workflows.
  • Actions such as “Save and validate next” for repetitive work.

The customer sees the tip of the iceberg#

One reason back-office UX is difficult is that success is often invisible. When everything works, the customer simply sees a product and assumes it has always existed.

The invisible UI
The customer sees the product. Not everything required to create it.
What the customer sees
What happens before that
01Supplier feed
02NGP ingestion
03SKU matching
04Category mapping
05Gender
06Product attributes
07Image validation
08Stock allocation
09Price rules
10Campaign eligibility
11Publication workflow
The customer never sees the back-office. They absolutely experience its mistakes.

Colour carries meaning, so use a semantic system#

In operational products, colour is information: validation, severity, publication state, stock warnings and environments. A brand palette does not solve this by itself.

  • A long neutral ramp for dense information hierarchy.
  • Semantic intents: success, warning, danger, info and neutral.
  • Background, border, text and solid variants for each intent.
  • Non-colour signals: labels, icons or position.
Neutral ramp
0
50
100
200
300
400
500
600
700
800
900
Semantic intents · solid / bg / border / text
DangerAachip
WarningAachip
SuccessAachip
InfoAachip
NeutralAachip
Categorical · data viz only
A sample palette. The neutral ramp does most of the work; each semantic intent ships four slots (solid, background, border, text) so a component never has to invent a tint; the categorical set is for charts only and is checked against colour-blindness.
css
:root {
  --intent-danger-text: #b42318;
  --intent-danger-bg: #fef3f2;
  --intent-danger-border: #fda29b;

  --row-h: 36px;
  --control-h: 32px;
}

[data-density="comfortable"] {
  --row-h: 48px;
  --control-h: 40px;
}

Atoms, molecules, and what the system actually ships#

The answer is not a component for every rectangle. It is a small set of atoms, a set of composable molecules, and a few serious organisms. The table is one of those organisms. Product readiness might be another.

Buttons
Fields
ORD-8891
Status: Processing
Notify Full Partial Live
Status chips
ActiveProcessingFailedDraftRefunded
Atoms: the pieces that carry no layout opinion. Every status chip pairs a colour with a shape and a word, so it still reads with the colour removed.
Field · default and error
REFUND_DUPLICATE
Shown to the customer in the refund email.
€ 0.00
Must be more than €0 and at most the order total (€128.40).
Filter bar · saved views
Status: Processing Warehouse: Lyon
ViewsMy queueUnassignedSave current…
Bulk action bar
37 selectedacross 2 pages
Molecules: atoms composed into a unit with one job. The field owns its label, hint and error slot; the filter bar owns saved views; the bulk bar owns the selection count and its actions.

Build on headless, skin it thin#

The useful distinction is not build versus buy. It is deciding which layer is worth owning. Tokens and visual language are yours. Keyboard behaviour, focus management and grid engines are specialised problems where headless primitives can save years of reinvention.

LayerOwn it?Why
Design tokensYesThey outlive framework decisions
App shell and layoutYesThey encode your operational model
Behaviour and accessibilityUsually headlessHard, specialised and reusable
Grid engineWrap itSorting and virtualisation are not your differentiator
Presentational componentsYesThis is the design system
IconsAdoptNobody needs to draw 400 icons

Tailwind + headless, or a themed component library?

The honest answer is timeline-dependent. A themed component library can get an operational tool useful quickly. A thin layer over headless primitives gives a larger organisation more control over long-term consistency. The important rule is the same: applications consume your wrapper layer, not raw dependencies.

A back-office design system is mostly two subsystems done properly: the table and the form. Everything else is the discipline required to stop twenty teams from inventing a twenty-first version of both.

The system is governance, not a component folder#

A design system succeeds when a user moving from catalogue enrichment to campaign management feels like they are still inside the same product. That is an organisational outcome.

  • Versioning. Semver the package and write a deprecation policy.
  • Contribution. Useful domain components return to the shared system rather than becoming permanent local forks.
  • Metrics. Track current-major adoption, raw-value usage and local overrides.
  • Domain language. Agree on what supplier, merchant, NGP, campaign and readiness mean before components encode five different interpretations.

Accessibility is not the compliance section#

Accessibility and speed often point in the same direction in operational tools. Full keyboard operation helps power users. Visible focus helps everyone. Clear error summaries prevent expensive mistakes.

  • Keyboard operation for tables, forms and dialogs.
  • Visible focus states that survive compact density.
  • Error summaries with managed focus.
  • Reduced motion support.
  • Targets that remain usable in compact mode.

Failure modes#

  • The back-office designed like a marketing landing page.
  • A beautiful Figma library with no implementation contract.
  • Every team creating its own table because the shared one is too generic.
  • Generic statuses that hide the actual reason a product cannot go live.
  • A system team becoming a bottleneck, so teams route around it.
  • Domain terminology drifting until supplier, merchant and owner mean different things in different tools.

The checklist#

  1. Model the operational pipeline, not just individual screens.
  2. Make density a token-level decision.
  3. Treat product readiness as explainable state, not decoration.
  4. Build one serious <DataTable> rather than ten approximate ones.
  5. Use forms optimised for repetition and expertise.
  6. Use semantic colour and never colour alone.
  7. Own tokens and the visual skin; borrow complex behaviour where appropriate.
  8. Keep applications away from raw component-library APIs.
  9. Run contributions, versioning and migration as governance.
  10. Measure whether the system is actually being used.
The point
The most interesting UX in e-commerce is often the UX nobody sees. Customers experience the result: the right product, the right price, the right stock, at the right moment. Behind that simple card is a network of suppliers, NGPs, categories, gender mappings, attributes, validation rules and campaigns. Design the operational system as seriously as the storefront and the whole machine becomes faster, calmer and much harder to accidentally break.

Next up
Broken windows, ownership, and other people's money

Years ago I got interview feedback that I lacked a "fix broken windows" mindset. Here is why that framing breaks down for software that moves other people's money, where real ownership means routing a fix through the framework (code owners, review, staged rollout, audit trail) rather than around it.

Read next →