The most complete color system for SwiftUI. By designers, for everyone, and readable by the AI agent that writes your code.
📘 Full documentation: colortokenskit.com
- 740 colors. 37 themes (36 hues, one every 10° around the color wheel, plus gray) with 20 stops each, in Display P3.
- 20 semantic tokens per theme for text, backgrounds, surfaces and outlines. Each one has a light stop and a dark stop, so dark mode works with no extra code.
- Contrast you can count on. Every hue has the same lightness at each stop, so every text token passes WCAG AA on its page background in both modes, and
outlinePrimaryreaches 3:1 on every background. - A theme from your brand color in one line:
ProTheme(hex: "#00B386"). - Color functions, harmonies and smooth gradients that stay correct in light and dark mode.
- Docs made for agents too. Every page on colortokenskit.com has a markdown version, and llms.txt lists them all.
- Pure Swift. No dependencies,
Sendable, and it runs on iOS 16, macOS 13, tvOS 16, watchOS 9 and visionOS 1 or later.
struct TripCard: View {
let theme: ProTheme // Color.proBlue, or your brand: ProTheme(hex: "#00B386")
var body: some View {
VStack(alignment: .leading) {
Text("Lisbon")
.foregroundStyle(theme.foregroundPrimary) // dark mode included
Text("3 nights from October 12")
.foregroundStyle(theme.foregroundSecondary.soften()) // one stop quieter, in both modes
}
.padding()
.background(theme.backgroundSecondary.proGradient()) // a gentle gradient from one color
}
}Everything hands back a plain SwiftUI Color or gradient, so it drops into code you already have. Using your first tokens walks through a real screen.
In Xcode, choose File > Add Package Dependencies, paste this URL, and keep the rule at Up to Next Major Version:
https://github.com/metasidd/ColorTokensKit-Swift.git
In a Swift package:
.package(url: "https://github.com/metasidd/ColorTokensKit-Swift.git", from: "3.0.0"),Then add .product(name: "ColorTokensKit", package: "ColorTokensKit-Swift") to your target.
import ColorTokensKitin your files.- Copy ColorTokens.swift into your project. It defines the semantic tokens, and you can edit them for your app.
- Use them:
Color.proBlue.backgroundPrimary,Color.foregroundPrimaryand the rest.
Installing ColorTokensKit covers each step, and replacing your app colors moves an existing app over one screen at a time.
import ColorTokensKit
extension Color {
static let brandColor = ProTheme(hex: "#00B386") // Your brand's hex, or a preset like Color.proBlue
}The theme takes your hex's hue at the palette's lightness for every stop, so it has the same contrast as the built-in themes, and brandColor.toColor() is your exact hex. You can also start from any hue with .primary(forHue: 210), or from exact OKLCH numbers. ProTheme has every way to make one. ProTheme was called ProColor before 3.0; the old name still works, and Xcode offers to rename it.
Gray and 36 hues, one every 10° around the OKLCH wheel, so neighbors are equally far apart:
Color.proGray Color.proPink Color.proRuby Color.proRed
Color.proTomato Color.proCoral Color.proOrange Color.proBrown
Color.proAmber Color.proGold Color.proMustard Color.proYellow
Color.proOlive Color.proChartreuse Color.proLime Color.proGrass
Color.proGreen Color.proJade Color.proEmerald Color.proMint
Color.proTeal Color.proTurquoise Color.proCyan Color.proCerulean
Color.proSky Color.proAzure Color.proBlue Color.proCobalt
Color.proIndigo Color.proIris Color.proViolet Color.proGrape
Color.proPurple Color.proOrchid Color.proPlum Color.proMagenta
Color.proRoseEach one is a ProTheme with 20 stops (_50 to _1000) and every semantic token. Ready-made themes shows them all, and what the library offers shows every stop.
Pass any ProTheme to a view, and the whole component gets a coherent, accessible set of colors:
struct CardView: View {
let theme: ProTheme
var body: some View {
VStack {
Text("Title")
.foregroundStyle(theme.foregroundPrimary)
Text("Subtitle")
.foregroundStyle(theme.foregroundSecondary)
}
.background(theme.backgroundPrimary)
.overlay(
RoundedRectangle(cornerRadius: 16)
.stroke(theme.outlineTertiary, lineWidth: 1)
)
}
}
// Swap the theme, and everything updates
CardView(theme: Color.proBlue)
CardView(theme: Color.proGold)
CardView(theme: .primary(forHue: 173)) // any hueSetting up themes covers theming a view, a screen or a whole app, and components and examples has 30 ready-made components to copy.
Every ProTheme has these tokens, and each resolves to its light or dark stop on its own:
| Kind | Tokens |
|---|---|
| Foreground | foregroundPrimary, foregroundSecondary, foregroundTertiary |
| Inverted foreground | invertedForegroundPrimary, invertedForegroundSecondary, invertedForegroundTertiary |
| Background | backgroundPrimary, backgroundSecondary, backgroundTertiary |
| Inverted background | invertedBackgroundPrimary, invertedBackgroundSecondary, invertedBackgroundTertiary |
| Surface | surfacePrimary (50% opacity), surfaceSecondary (30%), surfaceTertiary (10%) |
| Inverted surface | invertedSurfacePrimary (40%), invertedSurfaceSecondary (20%) |
| Outline | outlinePrimary (edges of controls: 3:1 on every background), outlineSecondary and outlineTertiary (decorative dividers and hairlines) |
Understanding semantic tokens explains each kind with an annotated example, and managing dark mode shows how they switch.
ColorTokensKit builds a 20-stop ramp for any OKLCH hue, from near-white (_50) to near-black (_1000). Every hue shares the same lightness and the same chroma at each stop. Lightness is CIELab L*, so a stop has the same WCAG contrast whatever the hue. Chroma is the most that 29 of the 36 named hues can show in Display P3, the gamut of every iPhone since the iPhone 7, so the palette is as vivid as it can be while the hues stay even. On an sRGB-only screen, such as many external monitors, the system clips these colors, so they look a little less vivid there.
OKLCH is Björn Ottosson's perceptually uniform color space, the one CSS Color 4 and Tailwind v4 use. Blues stay blue as they get lighter, instead of drifting toward purple the way they do in CIELab LCH.
Here is the palette itself, with one row per hue. Each column is a stop, and every hue has the same lightness (L) at each stop:
How the colors were made tells the story with interactive charts, and under the hood has the math.
Generate a gradient from one color, or pass the colors you want. Colors travel around the color wheel in OKLCH, so blue to yellow stays vivid instead of passing through gray, and a gradient between tokens is right in both light and dark mode:
card.proGradient() // a touch lighter at the top
glow.proGradient(.fade) // fades out, keeping its color
[Color.blue, .yellow].proGradient(from: .leading, to: .trailing) // stays vivid all the way acrossGradient theory explains the blends, .proGradient() covers easing and every option, and ProGradient recipes makes gradients from a single color.
Contrast is built in: every stop has the same lightness in every hue, so swapping a theme never breaks contrast. You can also check contrast in code with WCAG 2.x or APCA:
let background = RGBColor(r: 1, g: 1, b: 1, alpha: 1)
let text = RGBColor(r: 0.1, g: 0.1, b: 0.1, alpha: 1)
background.contrastRatio(to: text) // about 17.5 (WCAG 2, range 1 to 21)
background.contrastRatio(to: text, method: .apca) // about 104 (APCA Lc, positive for dark on light)
Color.white.contrastRatio(to: Color.black) // 21.0How accessible is it? lists what's guaranteed, .contrastRatio(to:method:) covers checking pairs in tests, and high contrast modes handles Increase Contrast.
- Color functions:
lighten,darken,soften,strengthen,saturate,desaturate,rotateHue,blendandinverton anyColor, correct in both modes. Start with.lighten(by:)or building for interaction states. - Harmonies:
complement,triad,analogous(),tints()and more, at the same lightness as the original. See color theory and.triad. - Charts: series colors that keep their contrast. See using tokens in charts.
- Conversions and interpolation: RGB, OKLCH, OKLab, CIELab, LCH, XYZ and hex. See
.toOKLCH(),Color(hex:)and.lerp(_:t:). - UIKit, AppKit, watchOS and visionOS: see platforms.
- Architecture: how the ramps are built and fitted into Display P3, in under the hood. CLAUDE.md maps the code.
- Something not working? See troubleshooting and the changelog.
Got an idea or found a bug? Open an issue.
See CONTRIBUTING.md for building and testing, updating the README images, keeping the repository small, and releasing.
MIT License. See LICENSE for details.






