Design Engineering

Design Engineering

Design Engineering Is an Approach to Design

Designing interfaces at the intersection of product logic, UX architecture, design systems, and frontend development.

The interface is designed as a system of components, states, scenarios, data, and responsive rules.

Designing interfaces at the intersection of product logic, UX architecture, design systems, and frontend development.

Key principles

01.

Interface as a System

The interface is designed not as a set of separate pages, but as a system of components, states, scenarios, data, and responsive rules.

02.

Product Logic Before UI

Before the visual layer, it is important to analyze the product model: roles, entities, user flows, constraints, states, and decision points.

03.

Screen Families Instead of Individual Screens

Large products are easier to design through screen families: Home, Search / Catalog, Detail Pages, Booking Flow, Account, Workspace, Repository, Dashboard. This helps preserve shared logic as the product grows.

04.

Runtime Validation

Live Demo, reference surfaces, and component assembly help reveal what is not always visible in a static mockup: long data, empty states, responsive behavior, map/list sync, selected state, fallback scenarios, and component boundaries.

05.

Handoff as System Transfer

Handoff should explain not only the appearance, but also the structure: component map, states, variants, data dependencies, runtime boundaries, responsive behavior, and visual QA expectations.

What Design Engineering Is

In a complex product, drawing a set of screens is not enough. It is necessary to understand which entities participate in the system, which states appear, which components should be reusable, where the boundary between UI and runtime logic sits, how the interface will be validated, and how the solution will move into development.

Design engineering in my practice is a way to design an interface closer to how it will live in the product: in components, data, states, responsive scenarios, and documentation.

This does not mean that a designer should replace a frontend developer. The point is different: interface decisions become more precise when component boundaries, states, props-like thinking, data dependencies, and future page assembly logic are already understood at the design stage.

This approach is especially important for complex B2B, B2C, and B2E products, where a screen rarely exists on its own. Behind it are user roles, access rights, filters, catalogs, statuses, transactions, documents, maps, tables, empty states, responsive behavior, and handoff to development.

Why Figma Alone Is Not Enough

Figma is excellent for visual language, structure, component anatomy, and communicating a solution. But in a complex product, a static mockup does not always show how the interface will behave in a real environment.

For example, a mockup can neatly show an ideal card. But in the product, questions quickly appear:

  • what happens if the card has no image;
  • how the component behaves with a long title;
  • how a filter changes results and badges;
  • how the map and list are synchronized;
  • how a mobile bottom sheet is connected to the active pin;
  • where the selected offer is stored;
  • how one detail layout works for different entity types;
  • what is application state and what is local page composition;
  • where a separate component is needed and where adapter logic is enough.

These questions are easy to hide on a static screen. In runtime, they become visible. That is why Live Demo, reference surfaces, and component assembly are used as a continuation of design, not as a separate stage “after design.”

From Pages to Screen Families

One of the main principles is not to design a product as a set of isolated pages.

Instead, the interface is decomposed into screen families: groups of screens that share logic but change active blocks depending on data and scenario.

For example, a detail page can be a family rather than a single page. For a route, it shows an itinerary, stop cards, and a map. For a commercial venue, it shows offer groups, BookingWidget, policies, and reviews. For a geographic location, it shows a map, related places, and recommendations. At the same time, the basic structure, navigation, grid, and responsive behavior remain recognizable.

This approach helps the team avoid creating every new screen from scratch. New entities are connected through clear composition rules, while the product remains coherent.

Layers of a Product Design System

In complex products, a design system should be more than a button library. It should explain how product logic becomes an interface.

I separate the system into several levels.

Foundations

Tokens, colors, typography, spacing, radius, shadows, surface rules, and basic visual principles.

Product UI Kit

Base interface elements: buttons, inputs, badges, chips, selects, overlays, menus, tabs, feedback states, navigation primitives. This lower layer should not know the product’s business logic.

Product Components

Components that already carry product meaning: cards, offer rows, reservation rows, notification rows, payment method rows, filter units, account tiles.

Product Component Blocks

Large reusable sections: search toolbar, filter panel, hero media header, detail support blocks, BookingWidget, account sections, recommendation rails.

Product Page Layouts

Page assembly rules: section order, grid, responsive behavior, sticky zones, mobile stacking, sidebar behavior, and conditions for showing blocks.

Runtime adapters / View-model layer

The layer that prepares data and state for the UI: routes, filters, selected offer, map/list state, booking draft, source-backed labels, callbacks. It helps avoid mixing visual anatomy with business logic.

Reference Surfaces

Separate surfaces for validating components, states, and layout families outside the user journey. They show the system separately from the “beautiful final screen.”

Component Boundaries

A component should have a clear role and responsibility boundary.

A button should not know business logic. A card should not decide routing and application state by itself. A detail block should not own source data. A page layout should not turn into a random set of local divs. A runtime adapter should not become a design system.

When these boundaries are not defined, the product quickly starts to fall apart: one-off components, page-local styles, repeated states, and hidden logic inside visual elements appear.

When boundaries are described, design and development start speaking the same language: what is a primitive, what is a product component, where a block begins, where layout logic lives, and where runtime state is located.

Example of Component Discipline: Divider

A good example is even a small divider.

In a weak system, it often remains a random border-top inside a specific screen. After some time, different shades, different spacing, different thicknesses, and different mobile behavior rules appear.

In a mature system, even this element has a place:

  • in Figma anatomy;
  • in tokens or visual rules;
  • in the Product UI Kit as a primitive / wrapper;
  • in code as a component with a clear API;
  • in a reference surface;
  • in documentation;
  • in usage rules inside cards, detail pages, and layout blocks.

This is not complexity for the sake of complexity. It is a way to prevent small local decisions from accumulating into system debt.

Runtime-first Validation

A runtime-first approach does not mean “writing production code immediately.” In the context of a portfolio and design system, this can be a Live Demo, showcase app, reference surface, or local component assembly.

The purpose of this layer is to check how the interface behaves outside an ideal mockup:

  • how cards work with different data density;
  • how sections turn on and off;
  • how a detail page adapts on desktop and mobile;
  • how map/list sync is connected to cards;
  • how selected offer gets into the BookingWidget;
  • how empty, no-photo, and no-results states look without manual adjustment;
  • where a component boundary is needed and where a data adapter is enough.

This validation helps make decisions not only at the level of “looks good,” but also at the level of “this can be maintained.”

Frontend-aware Workflow

A frontend-aware approach helps design interfaces without separating them from implementation.

In my practice, React, TypeScript, Next.js, and Vite are used as a working environment for validating a product system: portfolio site, Live Demo, showcase surfaces, component layers, and runtime adapters.

This is not positioning as a full-stack engineer. It is a way to better understand how the interface will live in the product:

  • which props a component needs;
  • which states should be first-class;
  • which variants should be described in advance;
  • where the boundary between layout and data is;
  • which responsive rules need to be checked;
  • where Figma and code may diverge;
  • what needs to be handed over to the development team.

Reference Surfaces and Inspection Layer

Reference surfaces are not user-facing pages. They are surfaces for validating the system.

They help review:

  • all card variants;
  • component states;
  • filters;
  • offer cards;
  • booking components;
  • account components;
  • page layouts;
  • responsive frames;
  • fallback states.

This inspection layer makes it possible to evaluate the system not by one polished screen, but by how well it handles different data, states, and use cases.

Handoff

In a design engineering approach, handoff is not just a link to a mockup.

A good handoff should explain:

  • screen family;
  • component map;
  • variants and states;
  • data dependencies;
  • runtime boundaries;
  • responsive behavior;
  • known limitations;
  • validation notes;
  • visual QA expectations.

This way, development receives not just a picture, but also the logic of how the interface should work and evolve.

What This Approach Provides

Design engineering helps turn an interface into a system that can be explained, validated, assembled, and handed over.

It reduces the risk that:

  • identical patterns will be solved differently;
  • Figma and code will diverge;
  • components will start owning someone else’s logic;
  • a temporary solution will become permanent;
  • a page layout will turn into local composition;
  • edge cases will appear only after development;
  • handoff will require constant guesswork.

The main result is a more resilient interface: it is understandable for the user, predictable for the team, and better prepared for product growth.