Liquid Glass Widgets
A comprehensive Flutter package implementing Apple's Liquid Glass design system with 26 beautiful, composable glass-morphic widgets.
Features
- 26 Widgets organized into five categories
- Two Quality Modes for performance optimization
- Flexible Layer System for efficient rendering
- Highly Customizable appearance with extensive glass settings
- Apple Design Guidelines faithful implementation
- Fully Tested with widget tests and golden visual regression tests
Widget Categories
Containers
Foundation primitives for content layout:
GlassContainer- Base primitive with configurable dimensions and shapeGlassCard- Elevated card with shadow for content groupingGlassPanel- Larger surface for major UI sections
Interactive
User interaction components:
GlassButton- Primary action buttonGlassIconButton- Icon-based buttonGlassChip- Tag/category indicatorGlassSwitch- Toggle controlGlassSlider- Range selectionGlassSegmentedControl- Multi-option selectorGlassPullDownButton- Menu trigger button with dropdownGlassButtonGroup- Container for grouping related buttons
Input
Text input components:
GlassTextField- Text input fieldGlassTextArea- Multi-line text input areaGlassPasswordField- Secure text input with visibility toggleGlassSearchBar- Search-specific inputGlassPicker- Scrollable item selectorGlassFormField- Form field wrapper for validation
Overlays
Modal and floating UI:
GlassDialog- Modal dialogGlassSheet- Bottom sheet / modal sheetGlassMenu- iOS 26 morphing context menuGlassMenuItem- Individual menu action item
Surfaces
Navigation and app structure:
GlassAppBar- Top app barGlassBottomBar- Bottom navigation barGlassTabBar- Tab navigation barGlassSideBar- Vertical navigation sidebarGlassToolbar- Action toolbar for tools and controls
Installation
Add to your pubspec.yaml:
dependencies:
liquid_glass_widgets: ^0.2.1-dev.2
Then run:
flutter pub get
Quick Start
Preventing White Flash (Important!)
To eliminate the brief white flash when glass widgets first appear, precache the lightweight shader at app startup:
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LiquidGlassWidgets.initialize();
runApp(const MyApp());
}
Basic Usage
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: GlassContainer(
width: 200,
height: 100,
child: Text('Hello, Glass!'),
),
),
),
);
}
}
Grouped Widgets (Recommended for Multiple Glass Elements)
When you have multiple glass widgets, wrap them in an AdaptiveLiquidGlassLayer for better performance:
AdaptiveLiquidGlassLayer(
settings: LiquidGlassSettings(
thickness: 0.8,
blur: 12.0,
glassColor: Colors.white.withOpacity(0.1),
),
child: Column(
children: [
GlassContainer(
child: Text('First glass widget'),
),
GlassButton(
onPressed: () {},
child: Text('Click me'),
),
GlassCard(
child: Text('Another glass widget'),
),
],
),
)
Standalone Widget (For Single Glass Elements)
For a single glass widget or when you need different settings per widget:
GlassContainer(
useOwnLayer: true,
settings: LiquidGlassSettings(
thickness: 1.0,
blur: 15.0,
),
child: Text('Standalone glass widget'),
)
Platform Support
This package works seamlessly across all Flutter platforms with optimized rendering:
- ✅ iOS (Native Impeller & Skia)
- ✅ Android (Native Impeller & Skia)
- ✅ macOS (Native Impeller & Skia)
- ✅ Web (CanvasKit with per-widget shader instances)
- ✅ Windows (Skia)
- ✅ Linux (Skia)
Adaptive Rendering:
- Impeller (iOS/Android): Full shader pipeline with texture capture and chromatic aberration
- Skia & Web: High-performance lightweight fragment shader
- Platform detection is automatic—no configuration needed
Glass Quality Modes
The package provides two quality modes optimized for different use cases:
Standard Quality (Default, Recommended)
GlassContainer(
quality: GlassQuality.standard,
child: Text('Great for scrollable content'),
)
- Uses lightweight fragment shader for iOS 26 accurate glass effects
- Works universally across all platforms (native, Skia, web)
- Use for: Lists, forms, scrollable content, interactive widgets
- Recommended default for 95% of use cases
Premium Quality (Static Layouts Only)
GlassAppBar(
quality: GlassQuality.premium,
title: Text('Static header with premium quality'),
)
- Impeller (iOS/macOS native): Full shader pipeline with texture capture and chromatic aberration
- Skia/Web: Automatically falls back to lightweight shader (same as standard quality)
- Higher visual quality on capable platforms
- Use only for: Static, non-scrollable layouts (app bars, bottom bars, hero sections)
- Warning: May not render correctly in scrollable contexts on Impeller
Customization
All glass widgets accept a settings parameter (in standalone mode) or inherit from parent LiquidGlassLayer:
LiquidGlassSettings(
thickness: 0.8, // Material thickness (0.0-1.0)
blur: 12.0, // Blur radius
refractiveIndex: 1.5, // Light refraction (1.0-2.0)
glassColor: Colors.white.withOpacity(0.1), // Tint color
lightAngle: 45.0, // Directional lighting angle
lightIntensity: 0.8, // Lighting strength
ambientStrength: 0.3, // Ambient light contribution
saturation: 1.2, // Color saturation multiplier
chromaticAberration: 0.002, // Color separation effect
)
Widget Examples
Button with Action
GlassButton(
onPressed: () {
print('Button pressed!');
},
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
child: Text('Click Me'),
)
Text Input Field
GlassTextField(
hintText: 'Enter your name',
onChanged: (value) {
print('Text changed: $value');
},
)
Modal Dialog
showDialog(
context: context,
builder: (context) => GlassDialog(
title: Text('Confirm'),
content: Text('Are you sure?'),
actions: [
GlassButton(
onPressed: () => Navigator.pop(context),
child: Text('Cancel'),
),
GlassButton(
onPressed: () {
// Handle confirm
Navigator.pop(context);
},
child: Text('OK'),
),
],
),
);
Bottom Sheet
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (context) => GlassSheet(
child: Column(
children: [
ListTile(title: Text('Option 1')),
ListTile(title: Text('Option 2')),
ListTile(title: Text('Option 3')),
],
),
),
);
Segmented Control
GlassSegmentedControl(
segments: ['Day', 'Week', 'Month'],
selectedIndex: 0,
onChanged: (index) {
print('Selected segment: $index');
},
)
Complete Example
See the example directory for a full showcase app demonstrating all widgets. Run it with:
cd example
flutter run
Architecture
Layer System
All widgets support two rendering modes:
-
Grouped Mode (
useOwnLayer: false, default): Multiple widgets share the same rendering context via parentAdaptiveLiquidGlassLayer. More performant for many glass elements. -
Standalone Mode (
useOwnLayer: true): Each widget creates its own independent rendering context. Use for single widgets or different settings per widget.
Shape System
Widgets use LiquidShape for customizable shapes, with LiquidRoundedSuperellipse (16px radius) as the default for a smooth, modern appearance.
Performance Tips
- Precache the shader at app startup with
await LiquidGlassWidgets.initialize();to eliminate loading flash - Use Grouped Mode when you have multiple glass widgets - wrap them in
AdaptiveLiquidGlassLayer - Use Standard Quality for scrollable content and interactive widgets (it's already very high quality!)
- Reserve Premium Quality for static elements like app bars where you want Impeller's advanced features
- Limit glass widget depth - avoid deeply nesting glass effects
Custom Refraction for Interactive Indicators
Interactive widgets like GlassSegmentedControl can have true liquid glass refraction (background visible through the indicator with edge distortion) on all platforms including Web and Skia.
How It Works
The refraction effect requires capturing the background content. Wrap your content with LiquidGlassScope and LiquidGlassBackground:
LiquidGlassScope(
child: Stack(
children: [
// 1. Mark the background for capture
LiquidGlassBackground(
child: Image.asset('assets/wallpaper.jpg', fit: BoxFit.cover),
),
// 2. Glass widgets will refract through the background
Center(
child: GlassSegmentedControl(
segments: ['Option A', 'Option B', 'Option C'],
selectedIndex: 0,
onSegmentSelected: (index) => print('Selected: $index'),
quality: GlassQuality.standard, // Uses custom shader
),
),
],
),
)
Key Points
LiquidGlassScope- Creates the infrastructure for background captureLiquidGlassBackground- Marks which content should be visible through the glass- Nested Scopes - Inner scopes override outer scopes (useful for isolated demos)
- Automatic on Impeller - On iOS/macOS with Impeller,
GlassQuality.premiumuses native scene graph instead - One Background Per Scope - Each
LiquidGlassScopeshould contain only oneLiquidGlassBackground
When to Use
| Scenario | Recommendation |
|---|---|
| Web / Skia platforms | ✅ Use LiquidGlassScope for refraction |
| iOS / macOS with Impeller | ⚡ Use GlassQuality.premium for native scene graph |
| Multiple isolated demo sections | 🔄 Use separate scopes for each |
| App-wide fallback | 🏠 Wrap root with scope + background |
💡 Tip: Run the example app on an Impeller device (iOS/macOS) to see a side-by-side comparison of Impeller vs Custom Shader rendering in the "Shader Comparison" section of the Interactive page for
GlassSegmentedControl.
Dependencies
This package builds on the excellent work of:
liquid_glass_renderer
Powers the Impeller integration for native scene graph rendering on iOS/Android/macOS with GlassQuality.premium. This sophisticated renderer provides texture capture and advanced chromatic aberration effects through Impeller's native pipeline.
For Skia and Web platforms, this package uses custom fragment shaders (lightweight_glass.frag, interactive_indicator.frag) to deliver iOS 26-accurate glass effects universally.
- Package:
liquid_glass_renderer - Repository: flutter_liquid_glass
- Author: whynotmake-it
A huge thank you to the whynotmake-it team for creating the Impeller integration that makes premium-quality glass rendering possible on native platforms.
Other Dependencies
motor- Animation utilities
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Testing
# Run all tests
flutter test
# Run excluding golden tests
flutter test --exclude-tags golden
# Run golden tests only (macOS)
flutter test --tags golden
License
This project is licensed under the MIT License - see the LICENSE file for details.
Credits
This package implements Apple's Liquid Glass design guidelines as a high-level widget library.
Special Thanks:
- The whynotmake-it team for creating the
liquid_glass_rendererpackage, which provides the sophisticated shader-based rendering engine that powers all the glass effects in this library. Their work on custom shaders, texture capture, and advanced glass rendering techniques made this widget library possible.
Links
Libraries
- liquid_glass_setup
- liquid_glass_widgets
- Liquid Glass Implementation according to Apple's Guidelines
- types/glass_quality
- utils/draggable_indicator_physics
- widgets/containers/glass_card
- widgets/containers/glass_container
- widgets/containers/glass_panel
- widgets/input/glass_form_field
- widgets/input/glass_password_field
- widgets/input/glass_picker
- widgets/input/glass_search_bar
- widgets/input/glass_text_area
- widgets/input/glass_text_field
- widgets/interactive/glass_chip
- widgets/interactive/glass_segmented_control
- widgets/interactive/glass_slider
- widgets/interactive/glass_switch
- widgets/interactive/liquid_glass_scope
- widgets/overlays/glass_dialog
- widgets/overlays/glass_sheet
- widgets/shared/adaptive_glass
- widgets/shared/adaptive_liquid_glass_layer
- widgets/shared/glass_interactive_indicator
- widgets/shared/inherited_liquid_glass
- widgets/shared/interactive_indicator_glass
- widgets/shared/lightweight_liquid_glass
- widgets/surfaces/glass_app_bar
- widgets/surfaces/glass_bottom_bar
- widgets/surfaces/glass_side_bar
- widgets/surfaces/glass_tab_bar
- widgets/surfaces/glass_toolbar