Liquid Glass logo

Liquid Glass

Community
rshankras
liquid-glass

Implement Liquid Glass design using .glassEffect() API for iOS/macOS 26+. Covers SwiftUI, AppKit, UIKit, and WidgetKit. Use when creating modern glass-based UI effects.

Overview

Publisherrshankras
Repositoryclaude-code-apple-skills
Skill nameliquid-glass
Stars
744
Forks
70
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by rshankras on GitHub. Read the source before you install it.

Installation

Install the Liquid Glass AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/rshankras/claude-code-apple-skills.git /tmp/claude-code-apple-skills
mkdir -p .claude/skills
cp -r /tmp/claude-code-apple-skills/skills/design/liquid-glass .claude/skills/liquid-glass
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Liquid Glass in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Liquid Glass on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Liquid Glass is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Liquid Glass Design

Implement Apple's Liquid Glass design language across all Apple UI frameworks. Covers SwiftUI (.glassEffect()), AppKit (NSGlassEffectView), UIKit (UIGlassEffect + UIVisualEffectView), and WidgetKit (rendering modes, accented content, glass elements in widgets).

When This Skill Activates

  • User wants glass/blur effects on views
  • User asks about Liquid Glass or modern Apple design
  • User needs transparent, interactive UI elements
  • User wants morphing transitions between views
  • User is implementing glass effects in UIKit with UIVisualEffectView
  • User needs UIGlassEffect or UIGlassContainerEffect
  • User asks about scroll view edge effects in UIKit
  • User wants Liquid Glass in widgets (WidgetKit)
  • User needs to support accented rendering mode in widgets
  • User asks about widget textures or mounting styles on visionOS

Design Rules (WWDC25)

Liquid Glass is the material of the navigation layer — bars, toolbars, floating controls — never the content layer (tables, lists, rows in a scroll view).

RuleDetail
Never glass on glassDon't stack glass. Elements sitting ON glass don't get the material again — style them with fills and vibrancy.
Two variants — never mix themRegular (default): works at any size, over anything, with adaptive legibility. Clear: only when ALL three hold — media-rich content underneath, a dimming layer is acceptable, and bold bright content sits above. Clear has no adaptive behaviors. One variant per interface.
Tint only primary actions"When every element is tinted, nothing stands out."
No steady-state intersectionsIn resting layouts, content shouldn't sit half-under a glass element — reposition or scale the content instead.
Strip decorated barsRemove customized bar backgrounds and borders; build hierarchy through layout and grouping, not decoration. Never group a symbol with a text label in one toolbar group. Action sheets spring from their source element.

Scroll edge effects keep floating elements separated from scrolling content: soft (gradual fade — the iOS default) vs hard (denser, with a dividing line — mostly macOS). One per view edge, and they're not decorative — don't add one where no floating UI elements exist.

Shape system — let containers do the math:

ShapeRadiusUse
FixedConstantStandalone elements
CapsuleHalf the element heightPhone-scale controls — add extra margin from the screen edge
ConcentricParent radius minus paddingNested containers (inner radii auto-calculate); iPad/Mac elements concentric with the window edge

Accessibility comes free at the system level: Reduced Motion decreases lensing and elastic effects; Increased Contrast renders glass elements black/white with a contrasting border. (Lensing is how glass appears — it materializes by modulating how it bends light, and adaptive shadows flip small elements light/dark for legibility over any content.)

Quick Start (SwiftUI)

Basic Glass Effect

swift
import SwiftUI

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // Capsule shape by default

Custom Shape

swift
Text("Hello")
    .padding()
    .glassEffect(in: .rect(cornerRadius: 16))

// Available shapes:
// .capsule (default)
// .rect(cornerRadius: CGFloat)
// .rect(corner: .containerConcentric) — radius derived from the container, keeps nested shapes concentric
// .circle

Interactive Glass

swift
Button("Tap Me") {
    // action
}
.padding()
.glassEffect(.regular.interactive())

Tinted Glass

swift
Text("Important")
    .padding()
    .glassEffect(.regular.tint(.blue))

Glass Configuration Options

OptionDescriptionExample
.regularStandard glass effect.glassEffect(.regular)
.tint(Color)Add color tint.glassEffect(.regular.tint(.orange))
.interactive()Scale, bounce, and shimmer on touch/hover.glassEffect(.regular.interactive())

Multiple Glass Effects

GlassEffectContainer

When using multiple glass elements, wrap them in GlassEffectContainer for:

  • Better rendering performance
  • Proper blending between effects
  • Morphing transitions

This is correctness, not just performance: glass can not sample other glass, so nearby glass elements must share ONE container to render and blend correctly.

swift
GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "star.fill")
            .frame(width: 80, height: 80)
            .font(.system(size: 36))
            .glassEffect()

        Image(systemName: "heart.fill")
            .frame(width: 80, height: 80)
            .font(.system(size: 36))
            .glassEffect()
    }
}

Spacing Parameter:

  • Controls when effects merge
  • Smaller spacing = views must be closer to merge
  • Larger spacing = effects merge at greater distances

Uniting Glass Effects

Combine views into a single glass effect using glassEffectUnion:

swift
@Namespace private var namespace

GlassEffectContainer(spacing: 20.0) {
    HStack(spacing: 20.0) {
        ForEach(items.indices, id: \.self) { index in
            Image(systemName: items[index])
                .frame(width: 60, height: 60)
                .glassEffect()
                .glassEffectUnion(
                    id: index < 2 ? "group1" : "group2",
                    namespace: namespace
                )
        }
    }
}

Morphing Transitions

Create fluid morphing effects when views appear/disappear.

Setup

  1. Create a namespace
  2. Assign glass effect IDs
  3. Use animations on state changes
swift
struct MorphingToolbar: View {
    @State private var isExpanded = false
    @Namespace private var namespace

    var body: some View {
        GlassEffectContainer(spacing: 40.0) {
            HStack(spacing: 40.0) {
                // Always visible
                Image(systemName: "pencil")
                    .frame(width: 60, height: 60)
                    .glassEffect()
                    .glassEffectID("pencil", in: namespace)

                // Conditionally visible - will morph in/out
                if isExpanded {
                    Image(systemName: "eraser")
                        .frame(width: 60, height: 60)
                        .glassEffect()
                        .glassEffectID("eraser", in: namespace)

                    Image(systemName: "ruler")
                        .frame(width: 60, height: 60)
                        .glassEffect()
                        .glassEffectID("ruler", in: namespace)
                }
            }
        }

        Button("Toggle") {
            withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) {
                isExpanded.toggle()
            }
        }
        .buttonStyle(.glass)
    }
}

Button Styles

Glass Button

swift
Button("Standard") {
    // action
}
.buttonStyle(.glass)

Glass Prominent Button

swift
Button("Primary Action") {
    // action
}
.buttonStyle(.glassProminent)

Advanced Techniques

Background Extension

Extend a hero image beyond the safe area — the system mirrors and blurs it under bars and sidebars:

swift
Image("hero")
    .backgroundExtensionEffect()

Or stretch content under sidebar or inspector:

swift
NavigationSplitView {
    SidebarView()
} detail: {
    DetailView()
        .background {
            Image("wallpaper")
                .resizable()
                .ignoresSafeArea()
        }
}

Horizontal Scroll Under Sidebar

swift
ScrollView(.horizontal) {
    HStack {
        ForEach(items) { item in
            ItemView(item: item)
        }
    }
}
.scrollExtensionMode(.underSidebar)

Tab Bar Behaviors

swift
TabView {
    // tabs
}
.tabBarMinimizeBehavior(.onScrollDown)  // Tab bar recedes while scrolling content
.tabViewBottomAccessory {               // Persistent control docked above the tab bar
    MiniPlayerView()
}

Toolbar Spacers

Split toolbar items into separate glass groups instead of customizing bar backgrounds:

swift
.toolbar {
    ToolbarItem { editButton }
    ToolbarSpacer(.fixed)      // Visual break — starts a new glass group
    ToolbarItem { shareButton }
    ToolbarSpacer(.flexible)   // Pushes the following group apart
    ToolbarItem { doneButton }
}

Scroll Edge Effect Style

swift
ScrollView { content }
    .scrollEdgeEffectStyle(.hard, for: .top)  // Hard style for dense UI, mostly macOS

Sheets

Remove custom presentationBackground modifiers — they interfere with the sheet's glass material and its morphing behavior.

AppKit Implementation

NSGlassEffectView

swift
import AppKit

// Create glass effect view
let glassView = NSGlassEffectView(frame: NSRect(x: 20, y: 20, width: 200, height: 100))
glassView.cornerRadius = 16.0
glassView.tintColor = NSColor.systemBlue.withAlphaComponent(0.3)

// Create content
let label = NSTextField(labelWithString: "Glass Content")
label.translatesAutoresizingMaskIntoConstraints = false

// Set content view
glassView.contentView = label

// Add constraints
if let contentView = glassView.contentView {
    NSLayoutConstraint.activate([
        label.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
        label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
    ])
}

NSGlassEffectContainerView

swift
// Create container
let container = NSGlassEffectContainerView(frame: bounds)
container.spacing = 40.0

// Create content view
let contentView = NSView(frame: container.bounds)
container.contentView = contentView

// Add glass views to content
let glass1 = NSGlassEffectView(frame: NSRect(x: 20, y: 50, width: 150, height: 100))
let glass2 = NSGlassEffectView(frame: NSRect(x: 190, y: 50, width: 150, height: 100))

contentView.addSubview(glass1)
contentView.addSubview(glass2)

Interactive AppKit Glass

swift
class InteractiveGlassView: NSGlassEffectView {
    override init(frame: NSRect) {
        super.init(frame: frame)
        setupTracking()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupTracking()
    }

    private func setupTracking() {
        let options: NSTrackingArea.Options = [
            .mouseEnteredAndExited,
            .activeInActiveApp
        ]
        let trackingArea = NSTrackingArea(
            rect: bounds,
            options: options,
            owner: self,
            userInfo: nil
        )
        addTrackingArea(trackingArea)
    }

    override func mouseEntered(with event: NSEvent) {
        super.mouseEntered(with: event)
        NSAnimationContext.runAnimationGroup { context in
            context.duration = 0.2
            animator().tintColor = NSColor.systemBlue.withAlphaComponent(0.2)
        }
    }

    override func mouseExited(with event: NSEvent) {
        super.mouseExited(with: event)
        NSAnimationContext.runAnimationGroup { context in
            context.duration = 0.2
            animator().tintColor = nil
        }
    }
}

Common Patterns

Floating Action Bar

swift
struct FloatingActionBar: View {
    @Namespace private var namespace

    var body: some View {
        GlassEffectContainer(spacing: 20) {
            HStack(spacing: 16) {
                ForEach(actions) { action in
                    Button {
                        action.perform()
                    } label: {
                        Image(systemName: action.icon)
                            .font(.title2)
                    }
                    .frame(width: 44, height: 44)
                    .glassEffect(.regular.interactive())
                    .glassEffectID(action.id, in: namespace)
                }
            }
            .padding(.horizontal, 8)
            .padding(.vertical, 4)
        }
    }
}

Card with Glass Effect

For a card floating above content (e.g. overlaid on a map). Cards inside a scrolling list are content-layer — don't use glass there. Note the icon uses a fill, not a second glassEffect: elements on glass never get glass again.

swift
struct GlassCard: View {
    let title: String
    let subtitle: String
    let icon: String

    var body: some View {
        HStack(spacing: 16) {
            Image(systemName: icon)
                .font(.title)
                .frame(width: 50, height: 50)
                .background(.blue.opacity(0.15), in: .rect(cornerRadius: 12))

            VStack(alignment: .leading) {
                Text(title)
                    .font(.headline)
                Text(subtitle)
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
            }

            Spacer()
        }
        .padding()
        .glassEffect(in: .rect(cornerRadius: 16))
    }
}

Tab Bar with Morphing

swift
struct GlassTabBar: View {
    @Binding var selection: Int
    @Namespace private var namespace

    let tabs = [
        ("house", "Home"),
        ("magnifyingglass", "Search"),
        ("person", "Profile")
    ]

    var body: some View {
        GlassEffectContainer(spacing: 30) {
            HStack(spacing: 30) {
                ForEach(tabs.indices, id: \.self) { index in
                    Button {
                        withAnimation(.spring(response: 0.35, dampingFraction: 0.8)) {
                            selection = index
                        }
                    } label: {
                        VStack(spacing: 4) {
                            Image(systemName: tabs[index].0)
                                .font(.title2)
                            Text(tabs[index].1)
                                .font(.caption)
                        }
                        .frame(width: 70, height: 60)
                    }
                    .glassEffect(
                        selection == index
                            ? .regular.tint(.blue).interactive()
                            : .regular.interactive()
                    )
                    .glassEffectID("tab\(index)", in: namespace)
                }
            }
        }
    }
}

Migration from Old API

Before (Old Approach)

swift
// Old: Using materials directly
VStack {
    Text("Content")
}
.padding()
.background(.ultraThinMaterial)
.cornerRadius(16)

After (New API)

swift
// New: Using glassEffect modifier
VStack {
    Text("Content")
}
.padding()
.glassEffect(in: .rect(cornerRadius: 16))

Key Differences

Old ApproachNew API
.background(.material).glassEffect()
Manual corner radiusShape parameter
No interactivity.interactive() modifier
Manual tinting.tint(Color) modifier
No morphingglassEffectID + @Namespace
No container groupingGlassEffectContainer

UIKit Implementation

UIGlassEffect

Use UIVisualEffectView with a UIGlassEffect to create glass surfaces in UIKit:

swift
import UIKit

let glassEffect = UIGlassEffect()
let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.frame = CGRect(x: 50, y: 100, width: 300, height: 200)
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true

let label = UILabel()
label.text = "Liquid Glass"
label.textAlignment = .center
label.frame = visualEffectView.bounds
visualEffectView.contentView.addSubview(label)
view.addSubview(visualEffectView)
Customizing the Glass Effect
swift
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true

Interactive Glass in UIKit

Set isInteractive = true on a UIGlassEffect to make it respond to touch:

swift
let interactiveGlassEffect = UIGlassEffect()
interactiveGlassEffect.isInteractive = true

let glassButton = UIButton(frame: CGRect(x: 50, y: 300, width: 200, height: 50))
glassButton.setTitle("Glass Button", for: .normal)
glassButton.setTitleColor(.white, for: .normal)

let buttonEffectView = UIVisualEffectView(effect: interactiveGlassEffect)
buttonEffectView.frame = glassButton.bounds
buttonEffectView.layer.cornerRadius = 15
buttonEffectView.clipsToBounds = true

glassButton.insertSubview(buttonEffectView, at: 0)
view.addSubview(glassButton)

UIGlassContainerEffect

Use UIGlassContainerEffect when combining multiple glass elements. This is the UIKit equivalent of SwiftUI's GlassEffectContainer -- it enables proper blending and morphing between glass views:

swift
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0

let containerView = UIVisualEffectView(effect: containerEffect)
containerView.frame = CGRect(x: 50, y: 400, width: 300, height: 200)

let firstGlassEffect = UIGlassEffect()
let firstGlassView = UIVisualEffectView(effect: firstGlassEffect)
firstGlassView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
firstGlassView.layer.cornerRadius = 20
firstGlassView.clipsToBounds = true

let secondGlassEffect = UIGlassEffect()
secondGlassEffect.tintColor = UIColor.systemPink.withAlphaComponent(0.3)
let secondGlassView = UIVisualEffectView(effect: secondGlassEffect)
secondGlassView.frame = CGRect(x: 80, y: 60, width: 100, height: 100)
secondGlassView.layer.cornerRadius = 20
secondGlassView.clipsToBounds = true

containerView.contentView.addSubview(firstGlassView)
containerView.contentView.addSubview(secondGlassView)
view.addSubview(containerView)

Scroll View Edge Effects

UIKit scroll views now support configurable edge effects for Liquid Glass integration:

swift
let scrollView = UIScrollView(frame: view.bounds)
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
scrollView.rightEdgeEffect.isHidden = true

Available Edge Effect Styles:

StyleDescription
.automaticSystem determines style based on context
.hardHard cutoff with a dividing line

UIScrollEdgeElementContainerInteraction

Coordinates glass elements (such as bottom toolbars) with scroll edge behavior:

swift
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = scrollView
interaction.edge = .bottom
buttonContainer.addInteraction(interaction)

Toolbar Integration

UIKit navigation bar items integrate with Liquid Glass automatically; hidesSharedBackground opts an item out of the shared glass bar:

swift
let shareButton = UIBarButtonItem(
    barButtonSystemItem: .action,
    target: self,
    action: #selector(shareAction)
)
let favoriteButton = UIBarButtonItem(
    image: UIImage(systemName: "heart"),
    style: .plain,
    target: self,
    action: #selector(favoriteAction)
)
favoriteButton.hidesSharedBackground = true
navigationItem.rightBarButtonItems = [shareButton, favoriteButton]

UIKit vs SwiftUI Comparison

SwiftUIUIKit
.glassEffect()UIVisualEffectView(effect: UIGlassEffect())
.glassEffect(.regular.interactive())UIGlassEffect() with isInteractive = true
.glassEffect(.regular.tint(.blue))UIGlassEffect() with tintColor = ...
GlassEffectContainer(spacing:)UIGlassContainerEffect() with spacing
.buttonStyle(.glass)Insert UIVisualEffectView as button subview

WidgetKit Implementation

Rendering Modes

Widgets support two rendering modes that affect how Liquid Glass is displayed:

ModeDescription
Full ColorDefault mode. Displays all colors, images, and transparency as designed.
AccentedUsed when tinted or clear appearance is chosen. Primary and accented content tinted white (iOS and macOS). Background replaced with themed glass or tinted color effect.

Accented Mode

Detect the rendering mode and adapt layout accordingly. Use .widgetAccentable() to mark views that should be tinted in accented mode:

swift
struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // Layout optimized for accented mode
            AccentedWidgetLayout()
        } else {
            // Standard full-color layout
            FullColorWidgetLayout()
        }
    }
}
Grouping Accent Content
swift
HStack(alignment: .center, spacing: 0) {
    VStack(alignment: .leading) {
        Text("Widget Title")
            .font(.headline)
            .widgetAccentable()
        Text("Widget Subtitle")
    }
    Image(systemName: "star.fill")
        .widgetAccentable()
}
Image Rendering in Accented Mode
swift
Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)

Container Backgrounds

Define a container background for your widget content:

swift
var body: some View {
    VStack {
        // Widget content
    }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }
}

Background Removal

Prevent the system from removing the widget background. Note that marking a background as non-removable excludes the widget from contexts that require removable backgrounds (iPad Lock Screen, StandBy):

swift
var body: some WidgetConfiguration {
    StaticConfiguration(kind: "MyWidget", provider: Provider()) { entry in
        MyWidgetView(entry: entry)
    }
    .containerBackgroundRemovable(false)
}

visionOS Textures and Mounting Styles

Widget Textures
swift
// Default glass texture
.widgetTexture(.glass)

// Paper-like texture
.widgetTexture(.paper)
Mounting Styles
swift
.supportedMountingStyles([.recessed, .elevated])
StyleDescription
.recessedWidget appears embedded into a vertical surface
.elevatedWidget appears on top of a surface

Custom Glass Elements in Widgets

Apply .glassEffect() and .buttonStyle(.glass) directly within widget views:

swift
// Glass text element
Text("Custom Element")
    .padding()
    .glassEffect()

// Glass image element
Image(systemName: "star.fill")
    .frame(width: 60, height: 60)
    .glassEffect(.regular, in: .rect(cornerRadius: 12))

// Glass button in widget
Button("Action") { }
    .buttonStyle(.glass)

Best Practices

  1. Use GlassEffectContainer for multiple glass views

    • Improves rendering performance
    • Enables morphing transitions
  2. Apply glass effect last in modifier chain

    • After frame, padding, and content modifiers
  3. Choose appropriate spacing in containers

    • Controls when effects blend together
  4. Use animations for state changes

    • Enables smooth morphing transitions
  5. Add interactivity for touchable elements

    • .interactive() for buttons and controls
  6. Tint sparingly — reserve tint for the primary action

    • See Design Rules: tinting everything makes nothing stand out
  7. Consistent shapes across your app

    • Establish a shape language (all capsules, or all rounded rects)

Checklist

SwiftUI

  • Use .glassEffect() instead of .background(.material)
  • Wrap multiple glass views in GlassEffectContainer
  • Add @Namespace for morphing transitions
  • Use .glassEffectID() on views that appear/disappear
  • Add .interactive() for touchable elements
  • Use .buttonStyle(.glass) for glass buttons
  • Test animations for smooth morphing

UIKit

  • Use UIVisualEffectView with UIGlassEffect for glass surfaces
  • Set isInteractive = true on glass effects for touchable elements
  • Wrap multiple glass views in UIGlassContainerEffect
  • Configure scroll view edge effects (.automatic or .hard)
  • Use UIScrollEdgeElementContainerInteraction for scroll-coordinated toolbars
  • Use hidesSharedBackground for toolbar items that need independent glass

WidgetKit

  • Detect widgetRenderingMode and adapt layout for accented mode
  • Mark accent content with .widgetAccentable()
  • Set .widgetAccentedRenderingMode() on images
  • Define .containerBackground(for: .widget) for backgrounds
  • Use .containerBackgroundRemovable(false) only when necessary
  • Apply .glassEffect() and .buttonStyle(.glass) in widget views
  • Configure .widgetTexture() and .supportedMountingStyles() for visionOS

General

  • Glass only on the navigation layer — never on content (tables, lists)
  • No glass stacked on glass; one variant (Regular or Clear) per interface
  • Only the primary action is tinted
  • Consider performance with many glass effects
  • Support both light and dark appearances

References

SwiftUI

AppKit

UIKit

WidgetKit

Frequently asked questions

What does the Liquid Glass AI skill do?

Implement Liquid Glass design using .glassEffect() API for iOS/macOS 26+. Covers SwiftUI, AppKit, UIKit, and WidgetKit. Use when creating modern glass-based UI effects.

Why use Liquid Glass on TypingMind?

Because you install it once and use it with any model. Liquid Glass is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Liquid Glass in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/rshankras/claude-code-apple-skills/tree/main/skills/design/liquid-glass. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Liquid Glass?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Liquid Glass?

As many as you like. As long as a model supports skills, you can use Liquid Glass with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Liquid Glass AI skill free?

Yes. It is published on GitHub by rshankras under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇