The most powerful particle system for SwiftUI
GPU-accelerated • 25+ Presets • Interactive • 3D Ready • VisionOS Native
Installation • Quick Start • Presets • Features • Docs
| Feature | SwiftParticles | Vortex | SpriteKit |
|---|---|---|---|
| SwiftUI Native | ✅ | ✅ | ❌ |
| Metal GPU | ✅ | ❌ | ✅ |
| Preset Count | 25+ | 12 | N/A |
| Interactive Particles | ✅ | ❌ | ❌ |
| 3D Particles | ✅ | ❌ | ❌ |
| VisionOS Support | ✅ | ✅ | ❌ |
| Real-time Editor | ✅ | ❌ | ❌ |
| Particle Trails | ✅ | ❌ | ✅ |
| Physics Collision | ✅ | ❌ | ✅ |
| Performance Profiler | ✅ | ❌ | ❌ |
dependencies: [
.package(url: "https://github.com/muhittincamdali/SwiftParticles.git", from: "1.0.0")
]- File → Add Packages
- Enter:
https://github.com/muhittincamdali/SwiftParticles.git - Click Add Package
import SwiftParticles
struct ContentView: View {
var body: some View {
ParticleView(preset: .confetti)
}
}InteractiveParticleView(preset: MagicPreset.configuration)
.interactionMode(.attract)
.interactionRadius(100)Text("🎉 Celebration!")
.confetti(isActive: $showConfetti)| Preset | Preview | Usage |
|---|---|---|
| Confetti | 🎊 Rainbow celebration | ParticleView(preset: .confetti) |
| Fireworks | 🎆 Multi-stage explosions | ParticleView(preset: .fireworks) |
| Sparkle | ✨ Twinkling stars | ParticleView(preset: .sparkle) |
| Preset | Preview | Usage |
|---|---|---|
| Fire | 🔥 Realistic flames | ParticleView(preset: .fire) |
| Smoke | 💨 Rising smoke | ParticleView(preset: .smoke) |
| Rain | 🌧️ Rain drops | ParticleView(preset: .rain) |
| Snow | ❄️ Gentle snowfall | ParticleView(preset: .snow) |
| Preset | Preview | Usage |
|---|---|---|
| Fairy Dust | 🧚 Magical trail | MagicPreset.fairyDust() |
| Spell Cast | ⚡ Magic burst | MagicPreset.spellCast() |
| Healing Aura | 💚 Green glow | MagicPreset.healing() |
| Lightning | ⚡ Electric sparks | MagicPreset.lightning() |
| Preset | Preview | Usage |
|---|---|---|
| Autumn Leaves | 🍂 Falling leaves | NaturePreset.autumnLeaves() |
| Cherry Blossoms | 🌸 Pink petals | NaturePreset.cherryBlossoms() |
| Bubbles | 🫧 Underwater bubbles | NaturePreset.bubbles() |
| Fireflies | ✨ Glowing insects | NaturePreset.fireflies() |
| Preset | Preview | Usage |
|---|---|---|
| Starfield | ⭐ Twinkling stars | SpacePreset.starfield() |
| Meteor Shower | ☄️ Shooting stars | SpacePreset.meteorShower() |
| Warp Speed | 🚀 Hyperspace | SpacePreset.warpSpeed() |
| Nebula | 🌌 Cosmic clouds | SpacePreset.nebula() |
| Preset | Preview | Usage |
|---|---|---|
| Storm Rain | ⛈️ Heavy rain | WeatherPreset.stormRain() |
| Blizzard | 🌨️ Snow storm | WeatherPreset.blizzard() |
| Fog | 🌫️ Mist effect | WeatherPreset.fog() |
| Dust Storm | 🏜️ Desert wind | WeatherPreset.dustStorm() |
| Preset | Preview | Usage |
|---|---|---|
| Explosion | 💥 Fiery burst | GameEffectsPreset.explosion() |
| Power Up | ⬆️ Collection glow | GameEffectsPreset.powerUp() |
| Damage Hit | ❤️ Red particles | GameEffectsPreset.damageHit() |
| Level Up | 🎊 Celebration | GameEffectsPreset.levelUp() |
100,000+ particles at 60 FPS:
let renderer = MetalParticleRenderer(maxParticles: 100_000)
renderer.render(to: metalView, particles: system.particles)Touch to attract, repel, or create turbulence:
InteractiveParticleView(preset: MagicPreset.configuration)
.interactionMode(.attract) // or .repel, .turbulence, .trail
.interactionRadius(120)
.interactionStrength(500)
.burstOnTap(true)
.burstCount(50)Beautiful motion trails:
var config = ParticleConfiguration()
config.trailEnabled = true
config.trailLength = 15
config.trailFadeRate = 0.2Full 3D particle systems:
let system = Particle3DSystem(configuration: .init())
system.configuration.emissionShape = .sphere(radius: 100)
system.configuration.gravity = Vector3D(x: 0, y: -98, z: 0)Native spatial particles:
#if os(visionOS)
VisionParticleView(configuration: VisionParticlePresets.magic3D)
.enableHandTracking()
.spatialAudio(true)
#endifBuild effects visually:
ParticleEditorView()
.onExport { configuration in
saveConfiguration(configuration)
}Monitor and optimize:
let profiler = PerformanceProfiler()
profiler.attach(to: particleSystem)
// Show debug overlay
PerformanceOverlayView(profiler: profiler)var config = ParticleConfiguration()
// Emission
config.emissionRate = 100
config.maxParticles = 500
config.emissionShape = .circle(radius: 50)
// Lifetime
config.lifetimeRange = 1.0...3.0
// Velocity
config.speedRange = 50...200
config.emissionAngle = -.pi / 2 // Upward
config.spreadAngle = .pi / 4
// Visual
config.sizeRange = 5...15
config.colorPalette = [.red, .orange, .yellow]
config.blendMode = .additive
// Physics
config.gravity = Vector2D(x: 0, y: 98)
config.turbulence = 30
config.drag = 0.02
// Size over lifetime
config.sizeOverLifetime = [
0.0: 0.5,
0.3: 1.0,
1.0: 0.0
]
// Color over lifetime
config.colorOverLifetime = [
0.0: ParticleColor(red: 1, green: 1, blue: 0.8),
0.5: ParticleColor(red: 1, green: 0.5, blue: 0.1),
1.0: ParticleColor(red: 0.3, green: 0.1, blue: 0.1, alpha: 0)
]
ParticleView(configuration: config)SwiftParticles/
├── Core/
│ ├── ParticleSystem # Main coordinator
│ ├── ParticleEmitter # Particle spawning
│ ├── ParticleConfiguration # All settings
│ └── Particle # Individual particle
├── Presets/
│ ├── ConfettiPreset
│ ├── FirePreset
│ ├── FireworksPreset
│ ├── MagicPreset
│ ├── NaturePreset
│ ├── SpacePreset
│ ├── WeatherPreset
│ └── GameEffectsPreset
├── Metal/
│ ├── MetalParticleRenderer # GPU rendering
│ └── ParticleShaders.metal # Compute shaders
├── Interactive/
│ └── InteractiveParticleView # Touch interaction
├── 3D/
│ └── Particle3D # 3D support
├── VisionOS/
│ └── VisionParticleView # visionOS native
├── Editor/
│ └── ParticleEditorView # Visual editor
├── Trails/
│ └── ParticleTrail # Motion trails
└── Performance/
└── PerformanceProfiler # Optimization
| Configuration | Particles | FPS | Device |
|---|---|---|---|
| Default (Canvas) | 1,000 | 60 | iPhone 12 |
| Default (Canvas) | 5,000 | 60 | iPhone 14 Pro |
| Metal GPU | 50,000 | 60 | iPhone 14 Pro |
| Metal GPU | 100,000 | 45 | iPhone 14 Pro |
| Metal GPU | 100,000 | 60 | M1 Mac |
| Platform | Minimum Version |
|---|---|
| iOS | 16.0+ |
| macOS | 13.0+ |
| tvOS | 16.0+ |
| watchOS | 9.0+ |
| visionOS | 1.0+ |
struct CelebrationView: View {
@State private var showConfetti = false
var body: some View {
ZStack {
Button("Celebrate! 🎉") {
showConfetti = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
showConfetti = false
}
}
.buttonStyle(.borderedProminent)
if showConfetti {
ParticleView(preset: .confetti)
.allowsHitTesting(false)
}
}
}
}func triggerExplosion(at position: CGPoint) {
var config = GameEffectsPreset.explosion()
config.emissionShape = .point
let system = ParticleSystem()
system.burst(at: position, count: 80)
}struct WeatherBackground: View {
let condition: WeatherCondition
var body: some View {
Group {
switch condition {
case .rain:
ParticleView(configuration: WeatherPreset.stormRain())
case .snow:
ParticleView(configuration: WeatherPreset.gentleSnow())
case .fog:
ParticleView(configuration: WeatherPreset.fog())
}
}
.ignoresSafeArea()
}
}MIT License - Use freely in personal and commercial projects.
Contributions welcome! Please read our Contributing Guide.
If you find this useful, please star the repo! It helps others discover it.
Made with ❤️ for the Swift community