accessibility
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions, reduced motion, or target sizes;…
Use when preloading fonts, asset/network images, Lottie/Rive animations, local JSON/config, warming initial API data, or optimizing Flutter Web startup.
$ npx -y skills add evanca/flutter-ai-rules --skill flutter-pre-caching --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/flutter-pre-cachingContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when preloading fonts, asset/network images, Lottie/Rive animations, local JSON/config, warming initial API data, or optimizing Flutter Web startup.
name: flutter-pre-caching description: "Use when preloading fonts, asset/network images, Lottie/Rive animations, local JSON/config, warming initial API data, or optimizing Flutter Web startup." license: MIT
Pre-caching helps avoid jank, loading flashes, font swaps, and delayed first renders.
The key rule:
> Pre-cache only what the user will likely see in the next 1 to 2 screens.
Do not pre-cache the whole app. That can slow startup and waste memory.
---
Use `GoogleFonts.pendingFonts()` to load the font variants before showing text.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class ExampleSimple extends StatefulWidget {
const ExampleSimple({super.key});
@override
State<ExampleSimple> createState() => _ExampleSimpleState();
}
class _ExampleSimpleState extends State<ExampleSimple> {
late final Future<List<void>> googleFontsPending;
@override
void initState() {
super.initState();
googleFontsPending = GoogleFonts.pendingFonts([
GoogleFonts.poppins(),
GoogleFonts.montserrat(fontStyle: FontStyle.italic),
]);
}
@override
Widget build(BuildContext context) {
final pushButtonTextStyle = GoogleFonts.poppins(
textStyle: Theme.of(context).textTheme.headlineMedium,
);
final counterTextStyle = GoogleFonts.montserrat(
fontStyle: FontStyle.italic,
textStyle: Theme.of(context).textTheme.displayLarge,
);
return FutureBuilder<List<void>>(
future: googleFontsPending,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox();
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
style: pushButtonTextStyle,
),
Text(
'0',
style: counterTextStyle,
),
],
);
},
);
}
}For production and offline support, prefer bundling critical fonts as assets.
flutter:
fonts:
- family: AppFont
fonts:
- asset: assets/fonts/AppFont-Regular.ttf
- asset: assets/fonts/AppFont-Bold.ttf
weight: 700Use it in the app theme:
MaterialApp(
theme: ThemeData(
fontFamily: 'AppFont',
),
)---
Use `precacheImage` for images that appear soon.
@override
void didChangeDependencies() {
super.didChangeDependencies();
precacheImage(
const AssetImage('assets/images/header.png'),
context,
);
}Then use the image normally:
Image.asset('assets/images/header.png')---
Use `precacheImage` with `NetworkImage`.
@override
void didChangeDependencies() {
super.didChangeDependencies();
precacheImage(
const NetworkImage('https://example.com/image.png'),
context,
);
}Then use it normally:
Image.network('https://example.com/image.png')**Important:** `precacheImage` warms Flutter’s in-memory image cache. It does not provide long-term offline caching.
For disk caching, use a package like `cached_network_image`:
dependencies: cached_network_image: ^latest
Example:
CachedNetworkImage( imageUrl: 'https://example.com/image.png', )
---
@override
void didChangeDependencies() {
super.didChangeDependencies();
final images = <ImageProvider>[
const AssetImage('assets/images/header.png'),
const AssetImage('assets/images/avatar.png'),
const NetworkImage('https://example.com/banner.png'),
];
for (final image in images) {
precacheImage(image, context);
}
}---
`precacheImage` returns a `Future<void>`, so you can wait before rendering the real UI.
late Future<void> _preloadImagesFuture;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_preloadImagesFuture = Future.wait([
precacheImage(
const AssetImage('assets/images/header.png'),
context,
),
precacheImage(
const NetworkImage('https://example.com/banner.png'),
context,
),
]);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _preloadImagesFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const CircularProgressIndicator();
}
return Column(
children: [
Image.asset('assets/images/header.png'),
Image.network('https://example.com/banner.png'),
],
);
},
);
}> [!NOTE] > Use `didChangeDependencies`, not `initState`, when you need `context` for `precacheImage`.
---
**Good candidates:**
**Bad candidates:**
---
class AppPreloader {
const AppPreloader();
Future<void> preload(BuildContext context) async {
await Future.wait([
_precacheImages(context),
_loadCriticalAssets(),
_warmUpInitialData(),
]);
}
Future<void> _precacheImages(BuildContext context) {
return Future.wait([
precacheImage(
const AssetImage('assets/images/home_hero.png'),36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions, reduced motion, or target sizes;…
Use when creating a feature, designing folder structure, adding repositories/services/view models, wiring dependency injection, or deciding which layer owns…
Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring BlocBuilder/BlocListener/BlocProvider, writing bloc tests, or…
Use when asked to review a PR, MR, branch, or diff, audit changed files, or check code quality.
Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing…
Use when building AI agents in Dart, implementing Genkit flows or tools, integrating LLMs into Dart or Flutter applications, or using Genkit Dart plugins.