Performative-UI: Shifting Focus From Visuals to Behavior
Most UI libraries are obsessed with how a component looks. They give us a million ways to tweak a border radius or pick the perfect shade of slate, but they rarely care about how a component actually behaves to signal intent. It's all aesthetics, no psychology.
Performative-UI takes a different approach. Instead of focusing on the visual finish, it treats the interface as a way to communicate state and urgency through movement and reaction. I saw a demo of a component that signals exactly how oversubscribed a funding round is in real time. It doesn't just change a number. It changes its physical behavior as the limit approaches.
It's a weird shift in perspective. We're used to static components that wait for a user to click them, but this feels more like the UI is talking back. The question is whether this actually helps a user understand a system better, or if it's just another way to add noise to a dashboard.
The psychology of design tropes
Standard UI patterns work because they reduce cognitive load. When a user sees a magnifying glass icon, they don't think about the concept of search; they just click it. This is basically a shortcut for the brain. If you change a standard pattern—like putting the navigation menu in the bottom right—you're forcing the user to spend mental energy relearning how to use your interface instead of focusing on your actual product.
There's a difference between a functional component and a performative one. A functional component, like a clear "Submit" button, is there to complete a task. A performative component, like a skeleton screen that mimics loading content, is there to manage the user's perception of time. Skeleton screens are a bit deceptive; they don't actually make the app faster, but they stop the user from feeling like the app has crashed.
These tropes guide behavior through implicit cues. A ghost button (a button with a transparent background and a thin border) tells the user that the action is secondary. If you have two buttons side-by-side, the one with the solid fill is the one you want them to click. It's a visual hierarchy that replaces the need for written instructions.
If you're building a basic layout, you can implement this hierarchy using CSS variables to maintain consistency across your components.
/* Define a clear hierarchy for action buttons */
:root {
--primary-btn: #007bff; /* High contrast for primary actions */
--secondary-btn: #e0e0e0; /* Low contrast for secondary actions */
}
.btn-primary {
background-color: var(--primary-btn);
color: white;
}
.btn-secondary {
background-color: var(--secondary-btn);
color: #333;
}
Implementing Performative-UI in React
Performative-UI is a wrapper that handles the "perceived" state of your interface so you don't have to manually manage loading booleans for every single button. It's essentially a state machine for your UI elements. Instead of writing isLoading ? <Spinner /> : <Button /> a dozen times, you wrap the element in a performative component that handles the transition.
Installing it is straightforward. You'll need the core package and the React adapter.
npm install @performative/core @performative/react
The most practical use case is replacing static buttons with PerformativeButton. This component manages the transition between the idle, loading, and success states automatically. This part is genuinely confusing at first because it feels like you're losing control over the DOM, but you're actually just delegating the state transitions to the library.
import { PerformativeButton } from '@performative/react';
// The component handles the loading spinner and disabled state automatically
export const SaveButton = () => (
<PerformativeButton
action={saveData}
successLabel="Saved!"
variant="primary"
>
Save Changes
</PerformativeButton>
);
You can customize the behavior through a global configuration object. This is where you define the timing for how long a "success" state lasts before reverting to idle.
// performative.config.js
export const config = {
transitions: {
successDuration: 2000, // Revert to idle after 2 seconds
loadingDelay: 300, // Don't show spinner for fast requests
},
themes: {
primary: '#007bff',
}
};
Exploring the component library
The polish here is the real story. Usually, when a project drops a component library this early, it’s a collection of half-baked primitives that you spend three days fighting just to get a button to center. This feels different. It’s professional and, more importantly, it's cohesive.
I find the community joke about producing "slop" without AI particularly telling. It suggests the library is so streamlined that the barrier between an idea and a finished UI has basically vanished. That’s great for prototyping, but I think it underestimates the friction of long-term maintenance. It's easy to ship a polished page when the components do the heavy lifting; it's much harder to maintain that look once you start needing edge cases the library didn't account for.
I'm not convinced this changes the workflow for experienced engineers who have their own design systems, but for the "idea person" or the solo dev, it removes a massive amount of tedious work.
The question is whether this level of abstraction will lead to a sea of identical-looking apps. If everyone uses the same "polished" primitives, does the web just start feeling like a series of templates again?
The trade-off between novelty and familiarity
The praise for this library being "polished" is an interesting signal. Usually, when a tool is described as "fun" and "professional" in the same breath, it means the developers nailed the ergonomics—the API just feels right. But I think the joke about producing "slop" without AI is the more honest take here. It suggests we're seeing a shift where the barrier to generating high-volume, visually coherent output is dropping, regardless of whether there's a neural network under the hood.
I suspect this will be a hit for rapid prototyping, but I'm skeptical about its longevity in production environments. There is a specific kind of friction that comes with "fun" libraries when they hit the constraints of a strict design system or a rigorous accessibility audit. It's easy to feel productive when you're churning out polished components, but that's not the same as building a maintainable interface.
The real question is whether this actually solves a problem or if it just makes the act of building feel faster. I'm not convinced yet.
Conclusion
Most of these "performative" patterns are just fancy ways to hide the fact that the backend is slow. It’s a psychological trick, not a technical breakthrough. Whether you actually need them depends on if your users are the kind of people who get anxious during a 200ms lag.
I'm still not convinced that adding more motion to a UI actually improves the experience, or if we're just collectively agreeing to like things that look "modern." Try implementing one of these patterns in your next sprint and see if your bounce rate actually moves, or if you're just polishing a mirror.