Getting Started
Install
pnpm add @squircle-js/vue# ornpm install @squircle-js/vue
Requires Vue 3.3 or later. Nuxt 3 is supported out of the box — the library has no Nuxt-specific configuration.
Basic usage
<script setup>import { Squircle } from "@squircle-js/vue";</script><template><Squircle :corner-radius="24" :corner-smoothing="0.6" class="bg-indigo-500 p-6"><h2 class="text-white font-semibold text-lg">Hello, squircle</h2></Squircle></template>
Squircle renders a <div> that auto-measures itself with a ResizeObserver and applies a computed SVG clip-path for the smooth-corner effect.
The directive alternative
Vue's asChild equivalent is a directive — apply the squircle clip-path directly to any element without a wrapper:
<script setup>import { squircleDirective as vSquircle } from "@squircle-js/vue";</script><template><buttonv-squircle="{ cornerRadius: 12, cornerSmoothing: 0.6 }"class="bg-blue-600 px-4 py-2 text-white">Click me</button></template>
See The Directive Pattern for the full story.
Global registration (optional)
For larger apps, register the components and directives globally:
// main.tsimport { createApp } from "vue";import { SquirclePlugin } from "@squircle-js/vue";import App from "./App.vue";createApp(App).use(SquirclePlugin).mount("#app");
After app.use(SquirclePlugin), <Squircle>, <StaticSquircle>, <SquircleNoScript>, v-squircle, and v-static-squircle are available in every template with no imports.
Composable API
For programmatic use — especially when options need to react to other state:
<script setup>import { ref } from "vue";import { useSquircle } from "@squircle-js/vue";const el = ref<HTMLElement | null>(null);useSquircle(el, { cornerRadius: 16 });</script><template><div ref="el" class="bg-emerald-500 p-6">Content</div></template>
See The Composable API.
Nuxt SSR
Everything works with Nuxt 3 SSR and static generation. The composable and directive only run on the client, so the initial server-rendered HTML omits the clip-path unless you pass defaultWidth / defaultHeight (or use StaticSquircle for fixed-size elements).
See No-JavaScript Fallback for progressive enhancement details.
Coming from React, Solid, or Svelte?
The component API is nearly identical across frameworks:
Squircle,StaticSquircle,SquircleNoScript— same names, same propscornerRadius,cornerSmoothing,width,height,defaultWidth,defaultHeight— same semanticsasChild→ replaced byv-squircledirective (idiomatic Vue)
The one deviation: Vue uses kebab-case attributes in templates (:corner-radius), and props are passed with the : prefix for reactive bindings.