Open-source project
cruisediary/Pastel avatar
cruisediary/Pastel

Pastel for iOS: Animating Instagram-Style Gradients in SwiftUI and UIKit

🎨 Gradient animation effect like Instagram

3,516 stars186 forksSwiftMIT

At a glance

What is it?
Pastel is a Swift package that animates multi-colour gradient backgrounds, text and views on iOS 16 and later. It ships 30 presets, a shared animation state object, and two APIs, one for SwiftUI and one for UIKit.
Who is it for?
Adopt Pastel if you are building an iOS 16 or later app in Swift 5.9 and want an animated gradient behind a login screen, a splash view or a title without writing Core Animation code yourself. Skip it if you target iOS 15 or earlier, if your gradients must run on Android and web from a shared asset, or if you need server-driven gradient definitions, since the README documents presets and colour arrays but no remote configuration.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Pastel solves for iOS interface work

A moving gradient looks simple and is not. In UIKit you build a CAGradientLayer, animate its locations or colors, keep the layer in step with frame changes and rotation, and decide what happens when the view leaves the screen. In SwiftUI you reach for an animated LinearGradient driven by a timer or a phase animator, and then discover the same gradient needs to sit behind text, inside a button, or across two views that should stay in sync. Pastel packages that work into a small set of types so the call site is one line. The audience is iOS developers who want the Instagram-style animated gradient, the kind behind a story or a profile header, without maintaining the layer code. The README states the requirements plainly: iOS 16.0 or later, Swift 5.9 or later, Xcode 15 or later. That floor is the first thing to check, because it excludes a large amount of shipped code. Pastel is a rendering component, not a design system. It does not generate palettes, does not read a design token file, and does not ship a colour picker. You bring the colours; it moves them.

How the animation works: views, state and shared coordination

The library exposes two layers of API. The low-level one is PastelView in UIKit, with properties for direction (startPastelPoint and endPastelPoint), animationDuration and a setColors call, followed by startAnimation. The SwiftUI side wraps the same idea in modifiers and views: pastelBackground for a background, PastelGradientView for a standalone animated view, and PastelText for animated gradient type. Above both sits PastelAnimationState, a value object holding colors, duration, timingCurve, repeatBehavior and autoreverses. The point of that object is coordination. The README shows one state instance passed to a PastelGradientView and a PastelText, which means a background and a title can share a single animation clock instead of drifting apart. That is the design decision worth noting: Pastel treats animation timing as shared state rather than a per-view property, so two views fed the same state should move together. The presets come from PastelGradient, with 30 built-in options; the README credits the preset designs to Alexander Zaytsev and shows them as a single gallery image rather than a list of names, so you will need to browse that image or the source to find the identifier you want. The README does not document what happens when a view is backgrounded, whether animations pause, or how the animation interacts with reduced-motion accessibility settings. Those are real gaps if your app has to respect system motion preferences.

Installing Pastel and animating your first gradient

Pastel installs through Swift Package Manager or CocoaPods. For SPM, the README gives this dependency line, which you add to your Package.swift; note the from: "1.0.0" version requirement, since 1.0.0 is the current release and 0.6.0 dates from 2019.

swift
dependencies: [
    .package(url: "https://github.com/cruisediary/Pastel.git", from: "1.0.0")
]

In Xcode you can instead use File, then Add Package Dependencies, and enter the repository URL. The CocoaPods route is a single pod line in your Podfile.

ruby
pod 'Pastel', '~> 1.0.0'

Once the package resolves, the shortest SwiftUI use is the preset background modifier. Import both SwiftUI and Pastel, then attach pastelBackground to any view; the README example applies it to a Text view with the .instagram preset.

swift
import SwiftUI
import Pastel

struct ContentView: View {
    var body: some View {
        Text("Hello")
            .pastelBackground(.instagram)
    }
}

If you want your own palette, pass a colour array and a duration in seconds. The README uses three UIColors built from RGB components divided by 255, with duration 3.0.

swift
Text("Hello")
    .pastelBackground(colors: [
        UIColor(red: 156/255, green: 39/255, blue: 176/255, alpha: 1),
        UIColor(red: 255/255, green: 64/255, blue: 129/255, alpha: 1),
        UIColor(red: 32/255, green: 76/255, blue: 255/255, alpha: 1)
    ], duration: 3.0)

On the UIKit side the README shows a PastelView created with the view's bounds, configured with startPastelPoint, endPastelPoint, animationDuration and setColors, then startAnimation, with the view inserted at index 0 so it sits behind the other subviews.

swift
let pastelView = PastelView(frame: view.bounds)
pastelView.startPastelPoint = .bottomLeft
pastelView.endPastelPoint = .topRight
pastelView.animationDuration = 3.0
pastelView.setColors([
    UIColor(red: 156/255, green: 39/255, blue: 176/255, alpha: 1),
    UIColor(red: 255/255, green: 64/255, blue: 129/255, alpha: 1),
    UIColor(red: 32/255, green: 76/255, blue: 255/255, alpha: 1)
])
pastelView.startAnimation()
view.insertSubview(pastelView, at: 0)

To see the presets before writing code, the README points at the example project: clone the repository and open Example/Pastel.xcodeproj. It states no additional setup is needed because Pastel is linked through SPM automatically.

Where Pastel stops being the right tool

The iOS 16 and Xcode 15 floor is the hardest constraint. If your deployment target is iOS 15 or lower, Pastel 1.0.0 is simply unavailable to you, and the older 0.6.0 release from 2019 predates the SwiftUI surface described in the README, so you would be adopting a different, older library in practice. The second limitation is scope. Pastel animates gradients. It does not animate shapes, masks, blurs or transitions, and there is no documented way to drive the animation from a scroll offset or a gesture; the state object exposes duration, timing curve, repeat behaviour and autoreverses, and that is the documented control surface. Third, the README is silent on accessibility. There is no mention of pausing the animation when Reduce Motion is enabled, and a continuously animating full-screen gradient is exactly the kind of effect that setting exists to suppress. You can handle that yourself by not calling startAnimation or by not applying the modifier, but the library does not do it for you. Finally, if your gradients are defined once in a design tool and reused across iOS, Android and web, Pastel only covers the iOS end; the colour values would still have to be duplicated into each platform's own animation code.

Pastel against building the gradient yourself or using a broader animation library

The realistic alternative is not another gradient package; it is writing the CAGradientLayer or SwiftUI animation yourself, or pulling in a general animation framework. Rolling your own means you own the layer lifecycle, the frame updates and the colour interpolation, and you get exactly the behaviour you specify, including reduced-motion handling, at the cost of that code and its edge cases. A general-purpose animation library covers far more ground than gradients but gives you a lower-level vocabulary, so the animated background becomes something you assemble rather than something you call. Pastel sits between those: it is narrower than an animation framework and more opinionated than hand-written Core Animation, and its distinguishing feature is the shared PastelAnimationState object that keeps multiple views on one clock. If you only ever animate a single background view, that coordination buys you nothing and the library is mostly a convenience wrapper. If you have a gradient behind text that must move in step, the shared state is the reason to pick it.

Maintenance, release history and the MIT licence

The repository is not archived, and the last push was on 2026-03-24, the same day release 1.0.0 was published. The release history shows the shape of the project clearly: 0.5.1 in September 2018, 0.6.0 in July 2019, and then a gap of roughly six and a half years before 1.0.0 in March 2026. That is not a project with a steady release cadence, and the jump to 1.0.0, together with the iOS 16 floor and the SwiftUI API, reads as a modernisation rather than continuous iteration. Treat upgrade cost accordingly: pin to 1.0.0 and expect the surface described in the README to be stable, but do not assume frequent patch releases. The repository still carries a .travis.yml file, which suggests CI configuration that has not been revisited. Pastel is MIT licensed, which in practice means you can use it in closed-source apps and modify it, provided the copyright notice and permission notice are retained; the README points to the LICENSE file for the exact text. This is a description of the licence, not legal advice, and if your organisation has rules about third-party dependencies you should route the LICENSE file through whoever reviews them.

Editorial conclusion

Adopt Pastel if you are building an iOS 16 or later app in Swift 5.9 and want an animated gradient behind a login screen, a splash view or a title without writing Core Animation code yourself. Skip it if you target iOS 15 or earlier, if your gradients must run on Android and web from a shared asset, or if you need server-driven gradient definitions, since the README documents presets and colour arrays but no remote configuration. Before adding it, verify that your Xcode version satisfies the Xcode 15 requirement, that the 1.0.0 tag resolves through Swift Package Manager or CocoaPods, and that the preset you want looks right on your own screens, because the README shows the preset gallery as a single image rather than per-preset code.

Frequently asked questions

How do I install Pastel in an iOS project?

Add the package through Swift Package Manager using the repository URL with from: "1.0.0", or add pod 'Pastel', '~> 1.0.0' to your Podfile. In Xcode you can also use File, then Add Package Dependencies, and enter the repository URL.

What iOS and Swift versions does Pastel require?

The README lists iOS 16.0 or later, Swift 5.9 or later, and Xcode 15 or later. Anything below those versions cannot use the 1.0.0 release.

How do I use Pastel with custom colours instead of a preset?

In SwiftUI, pass a colors array of UIColors and a duration to pastelBackground. In UIKit, call setColors on a PastelView and then startAnimation, as shown in the README.

Can two Pastel views share the same animation timing?

Yes. The README shows a PastelAnimationState instance holding colors, duration, timingCurve, repeatBehavior and autoreverses being passed to both a PastelGradientView and a PastelText so they animate together.

Official sources

  1. cruisediary/Pastel on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cruisediary-pastel.svg)](https://hysenlabs.com/projects/cruisediary-pastel)