Write SwiftUI. Press play.
On your phone.

PulseBadge
DotWave
RingSpinner
TwinOrbitLoader
Equalizer
ProgressArc
BouncyToggle

A canvas for postcard-sized components. Type one, watch it run for real, copy source that compiles in Xcode — then post it or record it.

Start here What plays

iPhone · iOS 17 and later · free.

Everything here is running. None of it is a screenshot.

RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
RingSpinner
PulseBadge
DotWave
Equalizer
ProgressArc
BreathingPill
SquareSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton
TwinOrbitLoader
BouncingBall
FadeGrid
BouncyToggle
OrbitDot
GradientSweep
DashSpinner
LikeButton

Type it, run it, take it with you.

Your source drives the stage. What you copy is what you typed.

RingSpinner.swiftplays as written
import SwiftUI

struct RingSpinner: View {
    @State private var turning = false

    var body: some View {
        Circle()
            .trim(from: 0, to: 0.72)
            .stroke(.orange, lineWidth: 5)
            .frame(width: 46, height: 46)
            .rotationEffect(.degrees(turning ? 360 : 0))
            .animation(.linear(duration: 1).repeatForever(autoreverses: false),
                       value: turning)
            .onAppear { turning = true }
    }
}

It runs, it doesn’t mime

Springs, TimelineView and trigonometry are computed on the device, at the frame rate you feel.

Copy compiles

Plain SwiftUI. No package to install, nothing to import beyond SwiftUI.

Fails closed, with a line number

If Swoop can’t play something exactly the way Xcode would, it refuses and points at the line rather than guessing.

Post it. Record it. Keep it yours.

Making the thing is half of it. The other half is showing someone.

Publish to the community

Put a component on Home and anyone can play it and take the source. Publishing is free — taxing the thing that fills a feed is how a feed dies before it starts.

Record it

Three seconds, square, straight to the share sheet. Captured from the running component, so it is the real animation rather than a still.

Your files stay yours

Everything you write is saved on the phone. Not uploaded, not read by us, not used to train anything. It leaves only when you publish or share it.

An account is optional

Writing, playing and copying never need one. Sign in with Apple or Google only when you want to publish or like — and you can delete your account from inside the app.

Animation, worked through.

Every example is a complete file, and every one of them runs on the page you’re reading.

All posts →

Views

Text, Image, Button, Toggle, Spacer, Divider, VStack, HStack, ZStack, ForEach, TimelineView, Circle, Capsule, Rectangle, RoundedRectangle.

Modifiers

frame, padding, offset, foregroundStyle, fill, stroke, trim, background, overlay, opacity, scaleEffect, rotationEffect, zIndex, clipShape, shadow, animation, onAppear.

Swift

@State, let, var, parameters with defaults, computed some View properties, helper funcs, if/else, ranges, arithmetic, and sin, cos, sqrt, pow, min, max, .pi.

Deliberately not here

No ScrollView, List, NavigationStack, GeometryReader or TextField. Swoop is for one component at postcard size, not for building screens on a phone.