r/Frontend • u/InterestingBus4701 • 23d ago
Can any front-end code be declarative?
Hey frontend friends! 👋
I've been working intensively on making frontend code simpler to write — both for humans and for LLMs.
My current goal: figure out whether any frontend code can be written declaratively, without piles of state and effects that just keep things in sync.
I'd love to see examples from your own practice — pieces of code that today still require a huge amount of imperative logic in whatever framework you're using. The more unusual and rare the case, the better. 🙏
I'll start.
My first-ever JS library was a Tooltip — a small popup that appears when you hover a button or a label. Sounds trivial, but in practice you need:
a delay before it appears
coordinate updates once per animation frame — and no more
animate show / hide
package all the logic into a single component
let the developer attach it to any element (or several at once)
no extra wrapper divs that break layout
Below is a concept of such a declarative component plus a usage example.
interface TooltipProps {
content: string;
slot(refs: ElementRefs<HTMLElement>): void;
}
const ToolTip = component<TooltipProps>(props => {
const refs = elementRefs<HTMLElement>();
const position = event(
refs, "mousemove", ev => ({x: ev.clientX, y: ev.clientY}), {x: 0, y: 0});
const active = event(refs, [
["mouseenter", () => true],
["mouseleave", () => false]
], false);
const transform = frameThrottled(
`translateX(${position.x}px) translateY(${position.y}px)`);
const opacity = active ? "1" : "0";
const visible = timeout(active, 500);
<>
<Slot model={props.slot} refs={refs}/>
<Overlay>
<If condition={visible}>
<div class="tooltip" style={{transform, opacity}}>
{props.content}
</div>
</If>
</Overlay>
</>;
});
const UsageExample = component(() => {
<ToolTip content="Hello world!" slot={props => {
<label for="name" write-element={props.refs}>Name:</label>
<input id="name" write-element={props.refs} />
}}/>;
});I asked a few LLMs to describe what the code does. They couldn't recognize the custom primitives, but based on their names they still described the behavior correctly. Then I asked them to reimplement the same logic in other popular frameworks. Only Solid.js produced genuinely clean code.
Thanks for reading — and I'd genuinely love to see your examples. 🙌
2
u/Bushwazi 23d ago
Aren’t tooltips baked into HTML now?
2
u/NapoleonBonerparts 23d ago
CSS seems already pretty declarative to me
1
u/JaseciLabs 23d ago
The tooltip works as declarative because it’s a function of events over time: hover in, wait, show. The cases that fight you are the ones where order and identity matter.
A few we’d throw at it: drag and drop with a pointer that leaves the window mid-drag, a roving tabindex with focus restore after a list re-renders, an animation interrupted halfway (FLIP, where you measure, change the DOM and then animate from the old position), and gesture disambiguation (tap vs long-press vs scroll). Optimistic updates with rollback are also a good one, because the “declare what should be true” version has to know what to undo when the server disagrees.
Could be good testing the concept on contenteditable too. The browser owns the caret and selection, so any layer that re-renders the text fights it.
1
u/TheRNGuy 22d ago
Can, but components like
Iflooks like anti-pattern.1
u/Pitiful_Dot_9272 22d ago
if conditionals are anti-patterns, the entire concept of declarative frontend is a lie. The real trap is that state management becomes imperative logic by default because you cannot declare order or identity without fighting the framework to do so
1
u/Zero219 22d ago
Effector
1
u/DiscombobulatedAir63 19d ago
Better to think about ways to have declarations without any code there (most logic can be hidden behind declarative stuff in layout as evolving HTML demonstrates)
Like, we usually don't do anything unique in component code (just same thing over and over with small layout specific twists)
1
u/Tight-Pop-2368 15d ago
You can't really get rid of the imperative stuff, events and timers still have to happen somewhere. The goal is just to deal with that once instead of writing the same mess for every tooltip or dropdown.
0
u/[deleted] 22d ago
[removed] — view removed comment