Squircle Component

Overview

Squircle is the primary component in @squircle-js/react. It wraps a div (or any element via asChild) and applies a smooth squircle clip-path that automatically updates whenever the element changes size.

import { Squircle } from "@squircle-js/react";

Props

PropTypeDefaultDescription
cornerRadiusnumberCorner radius in pixels. Required for a visible squircle effect.
cornerSmoothingnumber0.6Smoothing intensity from 0 (circle arcs) to 1 (maximum superellipse).
asChildbooleanfalseMerges squircle props onto the immediate child element instead of rendering a div.
widthnumberOverride the measured width. Use when you know the exact size.
heightnumberOverride the measured height. Use when you know the exact size.
defaultWidthnumberInitial width used before the ResizeObserver fires. Prevents a flash of unstyled content on first render.
defaultHeightnumberInitial height used before the ResizeObserver fires.

All standard HTML div props (className, style, onClick, data-*, etc.) are also accepted and forwarded to the rendered element.

How ResizeObserver works

Internally, Squircle attaches a ResizeObserver to its DOM node. Whenever the element's size changes — due to CSS, layout shifts, viewport resizing, or content changes — the observer fires, the component recomputes the SVG path, and updates the clip-path style.

This means Squircle works correctly without any manual size management:

// This works even as the container resizes
<Squircle cornerRadius={16} className="w-full max-w-sm bg-gray-100 p-6">
<p>Responsive squircle container</p>
</Squircle>

The SVG path is computed using figma-squircle's getSvgPath function and applied as clip-path: path('...') on the element's inline style.

Usage examples

Simple card

<Squircle
cornerRadius={20}
cornerSmoothing={0.6}
className="bg-white shadow-lg p-6"
>
<h2>Card title</h2>
<p>Card content goes here.</p>
</Squircle>

Fixed size with default dimensions

Supply defaultWidth and defaultHeight to avoid a flash of the uncliped shape on first render when the size is known ahead of time:

<Squircle
cornerRadius={32}
defaultWidth={128}
defaultHeight={128}
className="w-32 h-32 bg-indigo-500"
/>

Overriding measured size

Pass width and height directly to skip ResizeObserver measurement entirely for that render:

<Squircle
cornerRadius={16}
width={200}
height={100}
className="bg-emerald-400"
>
Fixed dimensions
</Squircle>

When both width/height props and a measured size are available, the explicit props take precedence. If you always know the size, consider StaticSquircle for better performance.

CSS fallback

The component always sets border-radius and data-squircle on the rendered element so that browsers without clip-path: path() support still get rounded corners. See No-JavaScript Fallback for the noscript case.