Why I Stopped Putting Database Queries in Components
Direct database access inside UI components feels convenient until the same content is needed in five different places.
The starting point
There is a seductive simplicity in putting a database query next to the JSX that consumes it. The code is close together and the first feature ships quickly. The cost appears later. A second page needs the same data, an admin screen needs a different version, a security rule changes, or the database schema evolves. Suddenly presentation components are coupled to persistence details everywhere.
Coupling is the real problem
The issue is not that a SQL query inside a server component is inherently slow or technically impossible. The issue is that it gives the component two jobs. It must understand both how the interface should look and how the application's data is stored. Those concerns change for different reasons.
When a query boundary exists, the component can instead receive data that describes its needs. The query layer can join tables, apply status rules, order records, and select only the fields required by the page. That makes the persistence decision local to one part of the system.
A small boundary beats a giant repository
I do not think every application needs a giant repository pattern. For a portfolio, a handful of focused query modules is enough. getPublishedArticles can own public article retrieval while getArticleForAdmin can own the richer shape required by the admin interface. The names communicate intent without pretending the database does not exist.
The practical benefit shows up during change. If the media relationship changes, the query boundary changes. If the card design changes, the component changes. The blast radius is smaller because the responsibilities are separated.


OPEN
Thoughts on the article.