Presentational vs Feature Components After the OnPush Default In short: The smart/dumb split used to be sold as a performance technique. Angular 22 gives you that performance for free. The split is still worth doing — for reuse, testing, and knowing where a bug lives. We have organised our files by feature. There is still a trap inside that feature folder: if every component injects services, fetches data, and manages state, nothing in it can be reused or tested cheaply. The classic answer is the smart vs dumb split — also called container vs presentational. It is still the right answer. But the reason changed, and teaching the old reason now leads people astray. The smart component A smart component is the brain. It talks to services, holds state, and arranges children. Its template is mostly a wiring diagram: Characteristics: injects services, holds the signals, has almost no CSS, and its template is mostly child components. The presentational component A presentational component receives data, renders it, and reports events. Nothing else. Notice what is missing: no . No HTTP. The only writable state is , which is pure UI trivia. Characteristics: no business services injected, business data arrives via , communication out via , owns its markup and styles. What the split is worth now Here is where this lesson differs from older material, including the previous version of this course. For years the headline benefit was: presentational components take only inputs, so you can mark them and skip most change detection. That was true and it was a real win. In Angular 22, is the default for every component. Your smart components are too. You do not get a change detection advantage from making a component dumb, because you already had it. So does the split still matter? Yes — for three reasons that were always the better ones. 1. Reuse across applications The business asks for the tanker log form in the Farmer Portal, a separate application with a different backend. If injected , it would be unusable — the Farmer Portal has no such service. Because it only takes an input and emits an output, you drop it in, wrap it in a different smart component, and it works. This is the mechanism that makes Chapter 7 possible at all. 2. Tests that cost nothing Testing the log form means: render it, click a button, assert an event. No HTTP mock, no store fake, no router. Compare that to testing the same logic embedded in a component that also fetches deliveries: you now need an HTTP mock and a store double before you can assert anything about a button. 3. You know where the bug is A tanker's volume is wrong on screen. Which of the fifteen components on this page changed it? If the presentational ones structurally cannot — they have read-only inputs and no store access — you go straight to the smart component and its store. The split turns a search into a lookup. Where the change detection benefit actually comes from now Since is free, the thing you control is what each component depends on . That is the argument from Chapter 1's second lesson, and it applies here. In the first version, any change to the tank object gives the card a new reference and it re-renders. In the second, changing leaves and untouched, so only the bindings that actually changed do work. Making a component "dumb" does not do this for you. Narrowing its inputs does. "But I thought presentational components should never have any state" This rule gets stated absolutely — dumb components are stateless — and it makes people do awkward things. The reasonable version underneath it is: a presentational component should not own business state. The tanker's volume is not its business. The list of deliveries is not its business. But is a different animal entirely. It is: invisible to the rest of the system, meaningless outside this component, and it disappears when the component does. Pushing it up to the parent makes things worse, not better. Watch what happens when you obey the absolute rule: Three bindings and two outputs to express "this form can open". The parent — whose job is coordinating business data — is now the state manager for four dropdowns. And every one of those signals is a new reason for the parent to re-render. The workable line is about who else cares : State Where it goes Why --- --- --- Is this form expanded? Local in the child Nobody else cares Which accordion panel is open? Local Nobody else cares Text typed but not submitted Local Nobody else cares The tanker's current volume Parent or store The dashboard, header, and API all care Which tanker is selected Parent — it drives other components Siblings need it Is the save request in flight? Store Multiple screens show it If lifting the state would let something else react to it, lift it. If lifting it just adds an input and two outputs so the parent can hold a boolean it never reads, leave it alone. Cheat sheet for code review The red flag to look for: a component with substantial markup and styl…