Friction as a feature
Emil Kowalski’s short essay Friction as a Feature begins with the consensus: “We treat friction as something bad. It makes us slow, inefficient, messy. Products brag about removing friction.”
Friction in the act of building#
His argument is that friction was doing a second job all along: “it made us think before we built.” Before AI, code was expensive, so the cost of building set a threshold on which ideas survived. AI removed that cost, and the bar dropped with it.
He is fair to the other side. Building A and B and comparing them often validates better than theorising, and “Prototyping is thinking.” But only if you validate, and with no friction nothing stops you shipping both. That is why people dislike the flood of vibe-coded apps and UI libraries: no friction forced a thought, so “They don’t feel designed, they just exist.” Friction forces judgement and filters the ideas that do not deserve to be built: “It’s a feature, not a bug.” He credits the framing to tweets by Swami and Drazen.
Friction in gestures#
The same idea runs through the interfaces he builds, the one place in this chapter where motion slows someone down on purpose. In Building a Toast Component he describes dragging a Sonner toast the wrong way: “you can still drag it, but it will slow down and eventually stop. It’s nicer than just stopping the toast immediately.” Vaul does the same at the top of a drawer: the drag is damped, so the more you pull the less it moves, because “things in real life don’t suddenly stop, they slow down first.” The skill file names the pattern in two lines, friction instead of hard stops and damping at boundaries; Rauno Freiberg’s Control Centre example is the same physics on iOS.
Friction can also be the whole interaction. The skill file’s hold-to-delete pattern, also a course exercise, makes a deletion cost two seconds of sustained pressure: the fill transitions to inset(0 0 0 0) over 2s with linear timing, and if you let go early it snaps back in 200ms with ease-out. The slow fill gives the person time to notice and a cheap way out.
.fill { transition: clip-path 200ms ease-out;}.delete:active .fill { clip-path: inset(0 0 0 0); transition: clip-path 2s linear;}Press and hold the Delete button below, and let go early on at least one try to feel the fill reverse instead of finishing. Then switch on instant delete and notice how little the deletion costs once the two seconds of resistance are gone. The Last attempt line under the button records whether you released early, held it out, or skipped the friction entirely.
Friction only in front of decisions#
Most of the time you are removing friction, and Emil is the first to say so. Raycast gets no animation in 2.1 because he wants to work “with no unnecessary friction.” Sonner’s swipe is momentum-based, so a fast flick dismisses even a short drag. Vaul lets you flick a drawer shut and skip snap points. Subsequent tooltips open instantly.
const timeTaken = new Date().getTime() - dragStartTime.current.getTime();const velocity = Math.abs(swipeAmount) / timeTaken;if (Math.abs(swipeAmount) >= SWIPE_THRESHOLD || velocity > 0.11) { removeToast(toast);}The skill file’s asymmetric timing rule is the same judgement in one sentence: slow where the user is deciding, fast where the system is responding. Friction belongs in front of decisions, never in front of work.
That is also the shape of the chapter. Animate less, and when something earns motion, mean it: an ease-out that lands gently, a duration that respects distance, a spring that survives interruption, a clip that reveals without shifting layout, a sequence that tells the user which layer they are touching, and a little friction exactly where a decision lives. Emil’s line from the toast post is the standard: the less users notice, the better, because it means the thing is intuitive.