Media
Images, video, galleries and device frames.
Image #
Images, figures and background images.
Image #
Responsive image: lazy-loaded by default, with fit, radius, srcset and sizes support.
<Image
src="/images/photo.jpg"
alt="Placeholder photo"
width={320}
radius={8}
/>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
src | string | yes | Image URL. | |
alt | string | "" | Alternative text; leave empty only for decorative images. | |
decoding | "auto" | "async" | "sync" | "async" | Native decoding hint. | |
fit | "cover" | "contain" | How the image fills its box when both width and height are set. | ||
fullwidth | boolean | Full width of the container (default true). | ||
height | string | number | Height (pixels or any CSS length); also reserves space before loading. | ||
loading | "lazy" | "eager" | "lazy" | Native lazy loading (default lazy); use eager for above-the-fold media. | |
radius | string | number | Corner radius (pixels or any CSS length). | ||
rounded | boolean | Fully round (for avatars and logos). | ||
sizes | string | Display sizes for srcset (native sizes). | ||
srcset | string | Responsive image candidates (native srcset). | ||
width | string | number | Width (pixels or any CSS length); also reserves space before loading. |
Figure #
Figure with an optional caption.
<Figure caption="Build times dropped 40% after caching dependencies.">
<img src="/images/chart.jpg" alt="Build time chart" width="480" height="240" />
</Figure>Slots: root caption
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
caption | content | Caption under the content (<figcaption>). | ||
children | content | The image or other figure content. |
BackgroundImage #
No description.
<BackgroundImage src="/images/background.jpg" radius>
<Box style={{ margin: "2rem", "max-width": "18rem" }}>Content over a background image.</Box>
</BackgroundImage>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
src | string | yes | Image URL (data URIs work too). | |
children | content | Content drawn over the image. | ||
radius | boolean | Round the corners (theme radius). |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
VideoFrame #
Responsive iframe embed.
<VideoFrame title="Product tour" src="about:blank" ratio={16 / 9} />Slots: root frame
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
src | string | yes | Embed URL (YouTube, Vimeo, or any page that can be framed). | |
ratio | number | 16 | Width divided by height, e.g. 16 / 9. | |
title | string | "Video" | Accessible title of the embedded frame. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Galleries #
Carousels, thumbnails and image grids.
Carousel #
Previous/next carousel; controlled when value is set. ← → switch slides.
<Carousel
label="Highlights"
slides={[
{
id: "s1",
content: (
<img src="/images/signals.jpg" alt="Signals" width="640" height="280" />
),
},
{
id: "s2",
content: <img src="/images/ssr.jpg" alt="SSR" width="640" height="280" />,
},
{
id: "s3",
content: (
<img src="/images/theming.jpg" alt="Theming" width="640" height="280" />
),
},
]}
/>Slots: root control controls slide status viewport
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
slides | CarouselSlide[] | yes | The slides, in order. | |
label | string | "Carousel" | Accessible name (default "Carousel"). | |
onChange | (id: string) => void | Called with the id of the slide being shown. | ||
value | string | Id of the shown slide (controlled); uncontrolled when unset. |
CarouselSlide
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Slide id, passed to onChange and matched against value. |
content | content | yes | Slide content. |
Thumbnav #
Thumbnail picker.
function Example() {
const photos = [
{ id: "lake", src: "/images/lake.jpg", alt: "Lake at dawn" },
{ id: "forest", src: "/images/forest.jpg", alt: "Forest trail" },
{ id: "desert", src: "/images/desert.jpg", alt: "Desert dunes" },
{ id: "city", src: "/images/city.jpg", alt: "City at night" },
];
const photo = signal("forest");
const current = () => photos.find((ph) => ph.id === photo()) ?? photos[0];
return (
<Stack gap="0.75rem" style={{ "max-width": "24rem" }}>
<img
src={current()?.src}
alt={current()?.alt}
width="640"
height="400"
style={{ width: "100%", height: "auto", "border-radius": "var(--a-radius)" }}
/>
<Thumbnav label="Photos" items={photos} value={photo()} onChange={photo.set} />
</Stack>
);
}Slots: root image item
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
items | ThumbnavItem[] | yes | The thumbnails, in order. | |
onChange | (id: string) => void | yes | Called with the id the user picks. | |
value | string | yes | Id of the selected thumbnail. | |
label | string | "Thumbnails" | Accessible name (default "Thumbnails"). |
ThumbnavItem
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Thumbnail id, passed to onChange and matched against value. |
src | string | yes | Thumbnail image URL. |
alt | string | Alternative text (the button's accessible name). |
GalleryGrid #
Image grid.
<GalleryGrid columns={3}>
<img src="/images/a.jpg" alt="Gallery A" width="320" height="240" />
<img src="/images/b.jpg" alt="Gallery B" width="320" height="240" />
<img src="/images/c.jpg" alt="Gallery C" width="320" height="240" />
</GalleryGrid>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Images or tiles. | ||
columns | 2 | 3 | 4 | 3 | Number of columns. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
BeforeAfter #
Image compare slider.
<BeforeAfter
label="Compare designs"
before="/images/before.jpg"
beforeAlt="Before redesign"
after="/images/after.jpg"
afterAlt="After redesign"
initial={50}
/>Slots: root handle image overlay range
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
after | string | yes | Image URL for the "after" state. | |
before | string | yes | Image URL for the "before" state. | |
afterAlt | string | "After" | Alternative text for the "after" image. | |
beforeAlt | string | "Before" | Alternative text for the "before" image. | |
initial | number | 50 | Starting divider position in percent. | |
label | string | "Compare" | Accessible name for the slider (default "Compare"). |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Logo cloud & marquee #
Rows of logos and scrolling tickers.
LogoCloud #
Row of partner logos / names.
<LogoCloud items={["Acme", "Globex", "Initech", "Umbrella"]} />Slots: root item
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
items | unknown[] | yes | Logos: names or content (images). |
Marquee #
Seamless ticker: content is rendered twice so the −50% keyframe loops without a gap; the copy is hidden from assistive tech.
<Stack gap="0.75rem">
<Marquee pauseOnHover>
Arachne 2.4 · dark theme · 330+ components · SSR & hydration · full customization
</Marquee>
<Marquee variant="plain" speed="slow">
Acme · Globex · Initech · Umbrella · Hooli · Stark Industries
</Marquee>
</Stack>Slots: root group track
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content to scroll (rendered twice for a seamless loop). | ||
pauseOnHover | boolean | Pause scrolling while hovered or focused (default true). | ||
speed | "normal" | "slow" | "fast" | "normal" | Scroll speed. | |
variant | "soft" | "plain" | "soft" | "soft" (default) sits on a tinted, bordered strip; "plain" has no background or border. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Device frames #
Browser and phone mock-ups.
BrowserFrame #
Browser chrome mock-up.
<BrowserFrame url="https://acme.arachne.app">
<img src="/images/preview.jpg" alt="Site preview" width="640" height="300" />
</BrowserFrame>Slots: root bar body url
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Page content (a screenshot fills the frame). | ||
url | string | "https://example.com" | Address shown in the bar. |
PhoneFrame #
Phone mock-up.
<PhoneFrame>
<img src="/images/app.jpg" alt="App screen" width="300" height="600" />
</PhoneFrame>Slots: root body notch
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Screen content (a screenshot fills the screen). |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.