Why Don't You Provide a styled API?

Long story short: it's unnecessary.

cva encourages you to think of components as traditional CSS classes:

  • Less JavaScript is better
  • They're framework agnostic; truly reusable
  • Polymorphism is free; just apply the class to your preferred HTML element
  • Less opinionated; you're free to build components with cva however you'd like
Example: Polymorphic Components

There's no as prop in cva, because HTML is free:

-- // A familiar `styled` button as a link
-- <Button as="a" href="#" variant="primary">Button as a link</Button>
++ // A `cva` button as a link
++ <a href="#" class={button({variant: "primary"})}>Button as a link</a>

How Can I Create Responsive Variants like Stitches.js (opens in a new tab)?

You can't.

cva doesn't know about how you choose to apply CSS classes, and it doesn't want to.

We recommend either:

  • Showing/hiding elements with different variants, based on your preferred breakpoint.
Example: With Tailwind
export const Example = () => (
    <div className="hidden sm:inline-flex">
      <button className={button({ intent: "primary" })}>Hidden until sm</button>
    <div className="inline-flex sm:hidden">
      <button className={button({ intent: "secondary" })}>
        Hidden after sm
  • Create a bespoke variant that changes based on the breakpoint.

    e.g. button({ intent: "primaryUntilMd" })

This is something I've been thinking about since the project's inception, and I've gone back and forth many times on the idea of building it. It's a large undertaking and brings all the complexity of supporting many different build tools and frameworks.

In my experience, "responsive variants" are typically rare, and hiding/showing different elements is usually good enough to get by.

To be frank, I'm probably not going to build/maintain a solution unless someone periodically gives me a thick wad of cash to do so, and even then I'd probably rather spend my free time living my life.