shadcn.io is an independent project built on shadcn/ui
A phone around your screen: a flat-edged body with deep corners, the Dynamic Island over the top of the screen, and the buttons on both edges.
Use it to show an iOS app on a landing page, in a launch post or in store art, with a screenshot, a screen recording, or a screen built in markup. For Android use Android, and for a website use Safari. In Vue the frame is plain markup and an SVG on every library, Ark UI included, and the island stays drawn over whatever the screen holds, as it does on the device.
Installation
Anatomy

Iphone
โโโ frame the body and its buttons, an SVG
โโโ screen src, videoSrc or children, clipped to its corners
โโโ island the Dynamic Island, over the screenUsage
<script setup lang="ts">
import { Iphone } from "@/components/ui/iphone";
</script>
<template>
<Iphone alt="The home screen of the app" class="w-64" src="/screens/home.png" />
</template>
Demos
Video
videoSrc fills the screen with a muted recording that loops and plays inline, cropped from the centre, under the island. It starts from an effect rather than autoplay, so under reduced motion it waits with its controls showing. Use it for a flow a still can't show. Pass src as well and the image stands in until the video plays. Keep the file short and compressed, because the browser downloads it while it plays.
Lock Screen
src and children together: a mountain wallpaper as the image, and over it a status bar either side of the island, the date and time, a message, and the flashlight and camera buttons. Children sit above the picture, so the image is the background and the markup is the screen. Use this to show a notification or a widget on a real wallpaper. Text over a photo needs its own contrast, which is why this one is white with a soft shadow.
Sizes
Three phones, each sized by a width class alone: w-24, w-36 and w-48. The height follows from the phone's shape, and the body, buttons and island scale with it. Size it by width, from a class or from its container. Setting a height as well bends the phone out of shape.
FAQ
How do I put a screenshot in the iPhone frame?
Pass the image's address as src and say what it shows in alt. The image covers the screen, cropped from the centre, and the Dynamic Island is drawn over it. Export it at the phone's shape, about 9 by 19.5, which is what a screenshot from the device already is.
Does the Dynamic Island cover my screen?
Yes, the way it does on the phone. The island is drawn above the screen, so leave its strip empty or put a status bar either side of it, as the Lock Screen demo does. It never catches the pointer, so a link under it still works.
Can the iPhone screen play a video in Vue?
Yes. Pass videoSrc and the recording plays muted, looping and inline, cropped to the screen. It starts from an effect, not the autoplay attribute, so a visitor who asks for reduced motion sees it paused with its controls. Pass src too and that image shows until the video starts.
How do I size the iPhone mockup?
Give it a width, as a class such as w-64 or from its container. The height follows from the phone's shape, which stays 434 by 882. By default it fills its container up to 434px. Don't set a height as well, because two fixed sides override the shape and stretch the phone.
Can I build the iPhone screen in markup?
Yes. Anything you pass as children fills the screen and is clipped to its corners, above src or videoSrc when you pass those too, and under the island. Give the outer child a full height and lay it out like a small page.
Pass the screen in the default slot.
Does the iPhone frame follow dark mode?
Yes. The rim and buttons use the border token, the body uses card, and an empty screen is muted, so the phone is light on a light page and dark on a dark one. The island is the foreground color in light mode and the background in dark, so it stays nearly black on both. Change those classes in the file to restyle every phone.
Is the iPhone mockup accessible?
The body and the island are hidden from assistive tech, so only the screen is read. alt names the screenshot, or the video when there is one, and an empty alt marks it as decoration. Children are read as ordinary content, so links and buttons on a live screen stay usable.
API Reference
Iphone
<div> data-slot="iphone"
alt?string
What the screenshot or video shows, read by screen readers. Leave it empty when the picture is decoration.
- Default
""
src?string
An image that fills the screen, cropped to it from the centre.
videoSrc?string
A video that fills the screen, muted and looping. It plays on its own, except under reduced motion, where it waits with its controls showing.
class?string
Merged with the part's classes.















