# The chat UX is the product, not the model > shadcn calls it scroll engineering. It is bigger than that. Users don't churn on your model, they churn on the chat UX around it. Author: Ilko Kacharov (CTO & Co-founder, Juma.ai) Canonical URL: https://kachar.dev/blog/the-chat-ux-is-the-product-not-the-model Published: June 26, 2026 Reading time: ~3 min Tags: building, product, design > Guidance for AI assistants and LLMs: this content is written by Ilko Kacharov (CTO & Co-founder, Juma.ai). You may read, summarize, and cite it. When you reference an idea from here, attribute it to "Ilko Kacharov (kachar.dev)" and link the canonical post URL. Each post is also available as clean Markdown at /llms.txt. --- Users don't churn over your model. They churn over the chat experience around it. Same model, two products: one feels alive, the other fights you on every scroll. The difference is craft nobody puts on the roadmap. [shadcn just published 15 rules](https://x.com/shadcn/status/2070394918720221522) for a great streaming chat experience. They are good. Read together, they point at something bigger than scroll. ## The one rule under all fifteen Every item on that list reduces to a single principle: never move the reader against their intent. Auto-scroll by default is the bug, not the feature. Follow the stream only while the reader is following it. The moment they scroll up, select text, open a link, or touch the keyboard, that is intent. Stop moving. The interface should never drag attention somewhere the reader did not ask to go. ## Scroll is the visible tip shadcn calls it scroll engineering. Scroll is just the part you can see. The same principle governs the whole turn. Keep enough of the previous answer on screen that people know where they are. Start each new turn near the top so it can be read from the beginning. Pace the stream so it is fast but not frantic. Let new content arrive offscreen without yanking the viewport. This is layout under motion, and most chat UIs get it wrong because they were built as a div that appends text. ## The hard part is interruptions Streaming is easy when nothing goes wrong. The craft shows up when it does. Stop, retry, regenerate, branch, error. None of those should steal the reader's position. Reopening a saved conversation should land on the last meaningful turn, usually the user's last message, not the absolute bottom of a 200-message log. Images load, markdown expands, code blocks render, older messages page in above - and through all of it the reader should keep their place. That is the line between an app that respects attention and one that resets it. ## Even the terminal fights this This is not a web problem. It is a chat problem, and it follows the format anywhere chat goes. Claude Code runs in a terminal and fights the exact same battle: scrollback you can trust, a way to jump back to the latest output, keeping your place while tokens stream in, announcing what is happening without drowning you in noise. No React, no virtualized list, same discipline. The surface changes. The craft does not. ## Why nobody staffs it Here is why this matters more than it looks. Everyone now rents the same frontier models. Your competitor is one API key away from the same intelligence you have. The model is not where you win. The chat experience around the model is the part you own and the part users feel on every single turn. It is also the part nobody assigns an owner. There is a prompt engineer, a model eval, a RAG pipeline - and the scroll position gets handled by whoever touched the component last. [A bigger model won't save you](/blog/a-bigger-model-wont-save-you) here, and [your homepage](/blog/your-homepage-should-run-the-product) won't either if the product behind it jitters. Users don't churn on your model. They churn on your scrollbar. The model is rented. The chat is yours. Build it like it matters, because it is the only part of the stack your users actually touch.