In an airline design system, why is the organism often the first level that knows about flight data, and what should a flight-results organism accept?
answer
- display-ready values below, domain above
- molecules stay domain-free
- one mapping from offer to molecules
- receive data, emit selection
- renders with sample data anywhere
basics
~20 sCommon practice keeps molecules on display-ready values so they stay reusable, and lets the organism map domain objects such as flight offers onto them. A shared flight-results organism receives offers and reports selections; it does not fetch them.
solid answer
~50 sFrost's method never mentions data, but a common reading is that **atoms and molecules speak presentation** — a formatted time, an airport code, a price string — while the **organism is the first level that speaks the domain**. A flight-results organism accepts a list of flight offers in a documented shape and decides which molecule shows which field: times, stops, duration, fare. That keeps molecules reusable for trains or hotels and puts the offer-to-molecule mapping in one place, so a change in the flight model touches one component. In a shared library, the organism should **receive** its offers and **report** events like 'flight selected' rather than call the booking backend itself: then it renders with sample data in a component workshop, in tests and in any web or native app. Where the product fetches and holds that state is the application's decision.
code
pseudocode · 21 linesorganism FlightResults
accepts:
offers: list of FlightOffer // documented shape, supplied by the app
selectedOfferId: id or none
sortOrder: price | duration | departure
reports:
offerSelected(id)
sortChanged(order)
moreRequested()
own interface state:
expandedOfferId
render:
for each offer in offers:
FlightOption( // molecule: display-ready values only
departs = formatTime(offer.firstSegment.departure),
arrives = formatTime(offer.lastSegment.arrival),
route = offer.origin + ' - ' + offer.destination,
stops = stopsLabel(offer.segments.count - 1),
duration = formatDuration(offer.totalDuration),
fare = formatPrice(offer.lowestFare),
selected = offer.id == selectedOfferId)go deeper
Recall that small parts take ready-to-show values like a time or a price, while larger sections turn a flight offer into those values.
Explain why keeping molecules domain-free aids reuse and testing, and what a flight-results organism accepts, reports and keeps as its own state.
Show where you would draw the line in a real system, including generic organisms and single-product exceptions, and why a shared organism receives rather than fetches.
Weigh domain-aware shared organisms against keeping the system domain-free, and what each choice means for the system team's ownership and coupling.
## The question behind the level In **atomic design**, atoms are basic elements, molecules are small single-purpose groups of atoms, and **organisms** are larger components that form distinct sections of an interface. Brad Frost's chapter defines the levels by composition and says nothing about data. In practice, though, teams have to decide at which level a component starts to understand the product's **domain** — for an airline, flight offers, segments, fares and passengers. A widely used answer is: at the organism. This is a convention with good reasons, not part of Frost's definition. ## Presentation values versus domain objects | Level | Typically accepts | Airline example | |---|---|---| | Atom | one display-ready value | '07:45', 'LHR', an icon name | | Molecule | a few display-ready values for one job | departure time + airport, arrival time + airport, stop count text | | Organism | a domain object or collection | a list of flight offers, each with segments and fares | | Template | the arrangement, with placeholder content | results region beside filter region | The organism is the **translation layer**: it reads each flight offer and hands each molecule exactly the values it displays. ## Why molecules should not take domain objects - **Reuse.** A times-and-airports molecule that accepts plain values also works for rail or ferry itineraries; one that takes a flight-offer object works only for flights. - **Change containment.** If the offer model gains a codeshare field or renames a property, only the organism's mapping changes, not every molecule. - **Testing.** A molecule with display-ready inputs is tested with a handful of strings; one that takes a domain object needs realistic fixtures for every test. - **Cross-team sharing.** The system team can own molecules without knowing any product's data model. ## The flight-results organism's contract A shared flight-results organism typically: 1. **Accepts** the list of offers in a documented shape, plus which offer is selected and which sort order is active. 2. **Maps** each offer to a flight-option molecule, formatting or delegating the formatting of times, durations and prices for the user's locale. 3. **Reports** events outward: an offer was selected, the sort order was changed, more results were requested. 4. **Holds only interface state** of its own, such as which result is expanded to show its segments. It does not call the booking backend, decide how many results to request, or know whether the user is logged in. ## Why a shared organism receives rather than fetches - It can be shown with **sample data** in a component workshop and in a design editor's library, including awkward cases: a four-stop itinerary, an overnight arrival, a very long airport name. - It works in **every app** that has flight offers, web or native, regardless of how each app talks to its backend. - It can be **tested** with fixtures instead of a running backend. How the product fetches offers, caches them and passes them down is an application-architecture decision that lives outside the design system. ## Where the convention bends - A **single-product** team may let a molecule take a small domain type when it will never be reused elsewhere; the cost appears only if a second product arrives. - Some organisms are **generic** — a data table, a filter panel — and accept a described column or filter configuration rather than a domain object. - On a **native mobile** platform, the same split holds: a view model or plain values flow into small views, and the section-level view maps the domain model onto them. ## Common mistakes - Passing the whole offer object down through every molecule 'for convenience'. - Putting backend calls inside a shared organism, so it cannot render outside one app. - Duplicating the offer-to-molecule mapping in every screen that shows flights, instead of owning it once in the organism.
- Who should format the price — the organism, the molecule or the app?Any one of them, as long as it is exactly one. Many systems give the price atom an amount and a currency and let it format for the locale, because every price should look the same. What goes wrong is formatting in two places, which produces mismatched prices on one screen.
- The results list needs to load more offers when the user scrolls; does the organism fetch them?No. It reports that more results were requested; the app fetches and passes the longer list back in. That keeps the organism usable with sample data and in any app, while the app owns paging, caching and errors.
saying these in an interview costs you the question
- Frost's book defines the organism as the level where data enters.
- Every molecule should receive the full flight-offer object for convenience.
- A shared organism should call the backend itself so screens stay simple.
- A shared organism must never hold any state of its own.
- Each screen should repeat its own mapping from offers to molecules.