A lightweight, customizable shimmer effect for SwiftUI that adds elegant loading animations to your iOS, macOS, tvOS, and watchOS apps.
A shimmer effect is a subtle, animated gradient that sweeps across UI elements to indicate loading states or placeholder content. Instead of showing a static "Loading..." message or a spinner, shimmer creates a polished, modern experience that suggests content is on its way.
Common use cases:
- Skeleton screens while fetching data
- Placeholder cards in feed layouts
- Loading states for images, text, or profiles
- Any situation where you want to show "something is happening"
┌─────────────────────────┐
│ SwiftUI Shimmer ✨ │ ← Gradient sweeps left to right
└─────────────────────────┘
┌─────────────────────────┐
│ ┌───┐ │
│ │ ○ │ ▓▓▓▓▓▓▓▓▓▓ │ ← Avatar + text placeholders
│ └───┘ ▓▓▓▓▓▓▓ │ with shimmer animation
│ ▓▓▓▓▓▓▓▓▓▓▓▓ │
└─────────────────────────┘
Add the package to your Xcode project or include the Shimmer.swift file directly.
import SwiftUI
import Shimmer
// Simply add .shimmering() to any view
Text("Loading...")
.shimmering()
// Or apply to placeholder content
Rectangle()
.fill(Color.gray.opacity(0.3))
.frame(height: 20)
.shimmering()That's it! One line of code adds a professional shimmer effect.
| Parameter | What it does | Default | Range |
|---|---|---|---|
| Duration | How long one shimmer cycle takes | 1.5 seconds | 0.5s - 5s recommended |
| Delay | Pause between shimmer cycles | 0.25 seconds | 0s - 2s |
| Bounce | Should the shimmer reverse direction? | No (one-way) | Yes/No |
| Band Size | Width of the shimmer "light band" | 0.3 (30% of view) | 0.1 - 1.0 |
| Opacity | Transparency of gradient edges vs center | Start: 0.3, Mid: 1.0, End: 0.3 | 0.0 - 1.0 |
| Colors | Custom gradient colors | Black with varying opacity | Any colors |
| Mode | How shimmer applies to content | Mask | Mask, Overlay, Background |
Band Size - Controls the width of the "shine"
Small (0.1): ░░▓░░░░░░░ ← Thin, sharp highlight
Medium (0.3): ░░▓▓▓░░░░░ ← Balanced, natural look
Large (0.7): ░▓▓▓▓▓▓▓░░ ← Wide, soft glow
Duration - Controls animation speed
- 0.5s = Fast, energetic (good for small elements)
- 1.5s = Balanced, professional (recommended default)
- 3.0s+ = Slow, calm (good for large surfaces)
Bounce vs No Bounce
- No bounce: → → → (continuous forward motion)
- Bounce: → ← → ← (back-and-forth, feels more "alive")
The shimmer reveals/hides the content underneath.
- Best for: Text, icons, solid-colored shapes
- Creates: Classic "loading text" effect
The shimmer gradient sits on top of content.
- Best for: Images, complex content you want to show through
- Creates: Glossy, reflective highlight effect
- Supports different blend modes (multiply, screen, etc.)
The shimmer appears behind the content.
- Best for: Transparent or semi-transparent content
- Creates: Glowing background effect
Text("Loading your profile...")
.font(.headline)
.shimmering()Text("Fetching data")
.shimmering(
animation: .linear(duration: 2.0)
.delay(0.5)
.repeatForever(autoreverses: true)
)VStack(alignment: .leading, spacing: 12) {
// Profile image placeholder
Circle()
.fill(Color.gray.opacity(0.3))
.frame(width: 60, height: 60)
// Name placeholder
Rectangle()
.fill(Color.gray.opacity(0.3))
.frame(height: 20)
// Bio placeholder
Rectangle()
.fill(Color.gray.opacity(0.3))
.frame(height: 14)
}
.shimmering()Text("Premium Feature")
.font(.title)
.bold()
.shimmering(
gradient: Gradient(colors: [
.purple.opacity(0.3),
.white,
.purple.opacity(0.3)
]),
bandSize: 0.4
)@State private var isLoading = true
Text("Content")
.shimmering(active: isLoading)Image("photo")
.shimmering(
gradient: Gradient(colors: [.clear, .white.opacity(0.8), .clear]),
bandSize: 0.5,
mode: .overlay(blendMode: .plusLighter)
)The project includes ShimmerShowcase.swift, a fully interactive demo that lets you:
- Adjust all parameters with sliders in real-time
- Preview changes instantly
- Experiment with different modes and colors
- See how settings affect multiple sample views
Perfect for:
- Designers exploring visual options
- Developers finding the right settings
- Demonstrating capabilities to stakeholders
- Duration: 1.5s (not too fast, not too slow)
- Band Size: 0.3 (standard)
- Bounce: Off (continuous motion feels like progress)
- Duration: 2.0-3.0s (slower, more elegant)
- Band Size: 0.4-0.5 (wider, more noticeable)
- Mode: Overlay with light colors
- Bounce: On (creates a "breathing" effect)
- Duration: 3.0s+ (very slow)
- Opacity: Lower values (0.1-0.2)
- Mode: Background or Overlay
- Respect user's "Reduce Motion" settings
- Provide alternative loading indicators
- Don't rely solely on shimmer to convey information
- Consider users with vestibular disorders
The shimmer automatically adjusts direction for RTL languages (Arabic, Hebrew, etc.), ensuring a natural visual flow that matches reading direction.
Text("مرحبًا")
.shimmering()
.environment(\.layoutDirection, .rightToLeft)
// Shimmer will sweep right-to-left- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
- Swift 5.0+
- SwiftUI
- Creates a linear gradient with customizable colors and opacity
- Animates the gradient's position from one side to the other
- Applies the gradient as a mask, overlay, or background
- Repeats the animation indefinitely (or until disabled)
- Lightweight: Uses native SwiftUI animations
- GPU-accelerated gradient rendering
- Minimal memory footprint
- Can be disabled dynamically without layout changes
SwiftUI-Shimmer/
├── Shimmer.swift # Core shimmer modifier (< 150 lines)
└── ShimmerShowcase.swift # Interactive demo app
- Match your brand: Use subtle variations of your brand colors for a cohesive look
- Keep it simple: The default settings work great for most cases
- Be consistent: Use the same shimmer settings throughout your app
- Don't overdo it: Shimmer is for loading states, not decoration
- Test on device: Animations look different on real hardware vs simulator
Replace your entire content view with placeholder shapes that shimmer while data loads.
Text("Real content here")
.redacted(reason: .placeholder)
.shimmering()ForEach(0..<5) { _ in
SkeletonRow()
.shimmering()
}This project is available under the MIT License.
Created by Vikram Kriplaney. Contributions welcome!
- Check the
ShimmerShowcase.swiftfor interactive examples - Review the code comments in
Shimmer.swift - Experiment with the showcase app to find your perfect settings