description: liquiglass, Liquid Glass for Flutter: GlassSurface refracts the live backdrop on Impeller with the shader measured against iOS recordings.¶
Flutter¶
liquiglass, liquidglass for Flutter, puts the Compose library's material over the live backdrop.
GlassSurface refracts whatever Flutter paints behind it, every frame: lists scrolling under it,
images, video. No snapshot is involved. It runs on Impeller, Flutter's renderer on Android. iOS is
not a target; on iOS 26 the system's own glass is the native choice.

Our capture: the example on the Android 17 emulator, Impeller (OpenGL ES), at rest and scrolled.
The name
pub.dev refuses liquidglass as too close to the existing liquid_glass, so the Flutter package
is liquiglass (pub.dev/packages/liquiglass). It follows
the library's version (1.1.0-SNAPSHOT on main is 1.1.0-dev); to try main, depend on it by
path: liquiglass: {path: ../path/to/liquidglass/ports/flutter}.
import 'package:liquiglass/liquiglass.dart';
Stack(children: [
ListView(children: rows),
Positioned(
left: 24, right: 24, bottom: 24, height: 72,
child: GlassSurface(radius: 36, dark: true, child: Row(children: icons)),
),
])
GlassSurface takes the material's options:
radius;dark,tintAmountandtint;light(Offset(0, -1)is iOS 27's overhead light);materialize;reducedTransparencyandincreasedContrast.
Call LiquidGlass.ensureInitialized() in main so the shader is ready for the first frame. Where
Impeller is unavailable, glass draws a frosted stand-in. The
package README has
every option.
How it works¶
The shader is generated, not rewritten. tool/generate_shader.mjs translates the material shader's
SkSL export (ports/skia/shaders/material.sksl) into the GLSL Flutter compiles. The translation
changes the types, the two texture reads and the entry point; --check fails when the copy drifts.
Each GlassSurface paints a backdrop filter whose filter is ImageFilter.shader running that
shader over the live backdrop.
One part is approximated. Compose and the CanvasKit port read the wide tone kernel from a quarter-scale, Gaussian-blurred copy of the backdrop. A backdrop filter has a single input, so Flutter uses thirteen taps of a Gaussian with the same sigma instead. It sets the material's tone, never its detail.
How it is checked¶
flutter test checks three things:
- the generated shader compiles with Flutter's shader compiler and loads;
- the Dart material's uniforms equal the CanvasKit port's for three surfaces, to 1e-6;
- the widget lays out and paints where shader filters are unavailable.
CI runs this on Linux. The example app runs on the Android 17 emulator on Impeller's OpenGL ES backend, and on a Pixel 7 on Impeller's Vulkan backend, which most phones use. See the evidence.
Limits¶
- Rounded rectangles only. There is no lens or navigation bar yet, and no touch response.
- The wide tone kernel is approximated (above).
- Impeller only, checked on one phone (Pixel 7, Vulkan) and the emulator (OpenGL ES). Frame timing is not measured yet.