Flutter App
ccplugins/awesome-claude-code-plugins
Bootstrap a new Flutter mobile app with clean architecture, Riverpod, FVM-pinned SDK, current packages, and no deprecated APIs.
Build production Flutter apps with Clean Architecture, Riverpod (preferred over Bloc/Provider), GoRouter navigation, Impeller rendering engine, Dart 3.7+ patterns, platform channels via Pigeon, and…
$ npx skills add EliasOulkadi/shokunin --skill flutter -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install EliasOulkadi/shokunin flutter --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.pack/skills/flutter .claude/skills/flutter && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .claude/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutterType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add EliasOulkadi/shokunin --skill flutter -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install EliasOulkadi/shokunin flutter --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.pack/skills/flutter .agents/skills/flutter && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .agents/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add EliasOulkadi/shokunin --skill flutter -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install EliasOulkadi/shokunin flutter --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.pack/skills/flutter .cursor/skills/flutter && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .cursor/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/EliasOulkadi/shokunin.git --path .pack/skills/flutter--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add EliasOulkadi/shokunin --skill flutter -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install EliasOulkadi/shokunin flutter --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.pack/skills/flutter .gemini/skills/flutter && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .gemini/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install EliasOulkadi/shokunin flutterInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add EliasOulkadi/shokunin --skill flutter -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .github/skills && cp -r skills-src/.pack/skills/flutter .github/skills/flutter && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .github/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add EliasOulkadi/shokunin --skill flutter -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install EliasOulkadi/shokunin flutter --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/EliasOulkadi/shokunin.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.pack/skills/flutter .opencode/skills/flutter && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "flutter" agent skill from https://github.com/EliasOulkadi/shokunin/tree/master/.pack/skills/flutter into .opencode/skills/flutter/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flutter", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
flutterBuild production Flutter apps with Clean Architecture, Riverpod (preferred over Bloc/Provider), GoRouter navigation, Impeller rendering engine, Dart 3.7+ patterns, platform channels via Pigeon, and…
Flutter is an agent skill from EliasOulkadi/shokunin. Build production Flutter apps with Clean Architecture, Riverpod (preferred over Bloc/Provider), GoRouter navigation, Impeller rendering engine, Dart 3.7+ patterns, platform channels via Pigeon, and App Store/Play Store deployment.
Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts. Compatibility notes: opencode
It sits in Mobile, covering Cross-platform mobile apps and App store release. It works with Flutter and Dart. The repository describes itself as: 職人 Shokunin 62 AI agent skills for OpenCode, Claude Code, Cursor, Windsurf. ChromaDB memory, MCP servers, declarative self-updates. Multi-model, open source, zero cost. The licence is MIT.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 4c68e5b. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
flutterdartFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
opencode
From compatibility in the SKILL.md frontmatter.
Flutter loads about 3.2k tokens when it runs. Until then it costs about 60 tokens; SKILL.md has 1,079 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from EliasOulkadi/shokunin at commit 4c68e5b, republished under its MIT licence (© EliasOulkadi). 1,079 words, ~3,176 tokens.
.claude/skills/flutter/SKILL.md (or your agent's skills folder).Widgets are functions of state. Keep them pure. Compose, don't inherit.
Production Flutter apps with Clean Architecture, Riverpod, GoRouter, Impeller, and platform channels. Based on Flutter docs, Riverpod patterns, and production experience.
Before writing Flutter code, answer:
dart run flutter_skeleton or create lib/core, lib/features/*/domain|data|presentation by hand. Add Riverpod + GoRouter + Freezed deps in pubspec.yaml.freezed for sealed unions.json_serializable, and data sources. Wire up in Riverpod with Provider<AuthRepository>.ConsumerWidget/ConsumerStatefulWidget. Wire NotifierProvider for each feature. Keep ref.watch at leaf level.redirect guard), nested routes per feature, and deep link patterns.flutter build appbundle / flutter build ipa → deploy via Codemagic or GitHub Actions. Enable Impeller on Android in build.gradle.| Command | Description |
|---|---|
scaffold | Create project with folder structure and dependencies |
feature | Design a feature with domain/data/presentation layers |
state | Set up Riverpod providers for a feature |
route | Configure GoRouter with auth guard and deep links |
test | Write unit + widget + integration tests |
ship | Build and deploy to App Store + Play Store |
lib/
├ core/
│ ├ theme/ # Material 3 theming
│ ├ constants/ # App-wide constants
│ └ network/ # Dio + interceptors
├ features/
│ ├ auth/
│ │ ├ domain/ # Pure Dart — entities, use cases, contracts
│ │ ├ data/ # Repo impl, API, DTOs, data sources
│ │ └ presentation/ # Riverpod providers + screens + widgets
│ ├ home/
│ └ profile/
└ main.dartclass User {
final String id;
final String email;
const User({required this.id, required this.email});
}
abstract class AuthRepository {
Future<User> login(String email, String password);
Stream<User?> authStateChanges();
}
class Login {
final AuthRepository repository;
const Login(this.repository);
Future<User> call(String email, String password) => repository.login(email, password);
}| Scenario | Provider |
|---|---|
| Most apps | Riverpod (async-first, testable, DI built-in) |
| Large team, strict unidirectional | Bloc (explicit events/states) |
| Legacy or tiny | Provider (simple, context-coupled) |
final authStateProvider = StreamProvider<User?>((ref) {
return ref.watch(authRepositoryProvider).authStateChanges();
});
final loginProvider = NotifierProvider<LoginNotifier, AsyncValue<void>>((ref) {
return LoginNotifier(ref.watch(loginUseCaseProvider));
});
class LoginScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final status = ref.watch(loginProvider);
return status.when(
loading: () => const CircularProgressIndicator(),
error: (e, _) => ErrorWidget(message: e.toString()),
data: (_) => const LoginForm(),
);
}
}final router = GoRouter(
redirect: (context, state) {
final isAuth = ref.read(authStateProvider).value != null;
final isLogin = state.matchedLocation.startsWith('/login');
if (!isAuth && !isLogin) return '/login';
if (isAuth && isLogin) return '/';
return null;
},
routes: [
GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
GoRoute(path: '/login', builder: (_, __) => const LoginScreen()),
],
);Since Flutter 3.24+, Impeller is default on iOS. On Android, opt in:
// android/app/build.gradle
renderingEngine = "impeller"Eliminates first-frame jank. Faster frame rendering. Better memory on low-end devices.
// battery.dart (Pigeon input)
@HostApi()
abstract class BatteryApi {
int getBatteryLevel();
}Run: dart run pigeon --input battery.dart --dart_out lib/battery.dart
const constructors everywhereConsumer at leaf level (not entire screen)ListView.builder / GridView.builder (lazy)cached_network_imageflutter run --profile, DevToolsRepaintBoundary overuseFlutter renders at 60fps on most devices and 120fps on ProMotion displays. Performance perception differs:
| Technique | Perception impact | Implementation |
|---|---|---|
| Skeleton loaders | Feels faster than spinners. Shows structure immediately. | shimmer package with matching layout shape |
const constructors | Widgets that never change skip rebuild entirely. Cumulative gain on deep trees. | const Text('...'), const SizedBox(...), const Icon(...) |
extent estimation on scrollables | Eliminates jank from recalculating item sizes during scroll. | ListView.builder(itemExtent: 56.0, ...) |
AnimatedSwitcher vs Visibility | Fade transitions feel smoother than instant appear/disappear. | Wrap changing content in AnimatedSwitcher(duration: 200ms) |
RepaintBoundary | Isolates repaint of frequently-changing widgets (timers, animations) from rest of tree. | Wrap animated clock/progress bar in RepaintBoundary |
| Scenario | Cause | Fix |
|---|---|---|
Bad state: No element | Empty stream/iterable accessed without check | Guard with .isEmpty or use .firstOrNull |
LateInitializationError | late variable accessed before init | Use nullable T? or StateNotifier with initial value |
Platform channel: MissingPluginException | Method not implemented on native side | Verify Pigeon codegen ran, check method name matches both sides |
ConcurrentModificationError | Modifying list while iterating | Use .toList() to copy before mutation, or use List.unmodifiable |
type 'Null' is not a subtype of type 'String' | JSON null from API not handled in DTO | Add @JsonKey(defaultValue: '') or make fields nullable, run codegen |
GoRouter: GoError: no routes for location | Deep link path not registered | Add fallback redirect to / or register catch-all /* route |
| Riverpod: provider not disposed | Circular dependency between providers | Use ref.watch in build methods only, never in constructors. Break cycles with Provider.autoDispose |
Build failed: Could not resolve all files (Android) | Gradle dependency conflict or outdated plugin | Run ./gradlew --refresh-dependencies, check build.gradle versions match AGP requirements |
const constructors everywhere| Anti-pattern | Fix |
|---|---|
| Business logic in widgets | Extract to Riverpod notifiers / use cases |
ref.watch inside callbacks | ref.read for one-time reads |
| Giant widgets > 200 lines | Extract into smaller widgets |
| Manual MethodChannel | Pigeon for type-safe channels |
| No error handling in AsyncValue | Handle loading/error/data explicitly |
| One giant GoRouter file | Split routes into feature modules |
When reviewing Flutter code, use Before | After | Why format:
| Before | After | Why |
|---|---|---|
setState(() { count++; }) in large widget | ref.watch(counterProvider.notifier).increment() | setState triggers full widget rebuild; Riverpod isolates state changes |
ListView(children: items.map((e) => Widget(e)).toList()) | ListView.builder(itemCount: items.length, itemBuilder: (_, i) => Widget(items[i])) | Builder lazily constructs only visible items; map builds all upfront |
Navigator.push(context, MaterialPageRoute(builder: (_) => Screen())) | context.go('/route/${id}') | GoRouter enables deep linking, typed params, and auth guards |
Flutter renders at 60fps on most devices, 120fps on ProMotion displays.
| Technique | Perception | Implementation |
|---|---|---|
const constructors | Widgets that never change skip rebuild entirely | const Text(...), const SizedBox(...) |
RepaintBoundary | Isolates frequently-changing widgets (timers, animations) | Wrap clock/progress bar in RepaintBoundary |
| Skeleton loaders | Shows structure immediately (feels faster than spinners) | shimmer package with matching layout |
itemExtent on lists | Eliminates jank from recalculating sizes during scroll | ListView.builder(itemExtent: 56.0) |
AnimatedSwitcher | Fade transitions feel smoother than instant appear/disappear | Wrap changing content, set duration: 200ms |
| Hero animations | Create continuity between screens | Hero(tag: 'avatar', child: ...) on source and destination |
| Pre-cache images | Eliminates flash-of-placeholder on revisit | precacheImage(NetworkImage(url), context) in initState |
Rule: The user feels the slowest frame. Optimize for worst case, not average.
Before submitting Flutter code:
const constructors where possible (check with dart analyze)ListView.builder or SliverList.builder, never ListView(children: [...])ref.watch only in build methods; ref.read only in callbacks.when(data:, loading:, error:) — all three branches coveredandroid/app/build.gradle has renderingEngine = "impeller" (Android 14+)console.log or print() statements in production codeflutter analyze passes with zero errors or warningsMediaQuery.of(context).padding or SafeArea widget© EliasOulkadi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .pack/skills/flutter of EliasOulkadi/shokunin.
Open the folder on GitHubat commit 4c68e5b
Flutter next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Flutter this skillEliasOulkadi/shokunin | 114 | — | ~3.2k | Automated safety check: Pass | MIT | |
| Flutter Appccplugins/awesome-claude-code-plugins | 970 | — | ~1.1k | Automated safety check: Notes | Apache-2.0 | |
| Mobile Developeraiskillstore/marketplace | 433 | 7 repos | ~2.3k | Automated safety check: Pass | None | |
| Flutter SecurityHoangNguyen0403/agent-skills-standard | 572 | — | ~576 | Automated safety check: Notes | MIT | |
| Engine Whats Newflutter/flutter | 179k | — | ~978 | Automated safety check: Pass | BSD-3-Clause | |
| Flutter Cherry Pickflutter/flutter | 179k | — | ~1.8k | Automated safety check: Pass | BSD-3-Clause |
ccplugins/awesome-claude-code-plugins
Bootstrap a new Flutter mobile app with clean architecture, Riverpod, FVM-pinned SDK, current packages, and no deprecated APIs.
aiskillstore/marketplace
Develop React Native, Flutter, or native mobile apps with modern architecture patterns.
HoangNguyen0403/agent-skills-standard
Secure Flutter token/PII storage, build-time secrets, network trust, and release hardening using OWASP Mobile practices.
flutter/flutter
Generates the "what's new" release summary and diff file for changes in the Flutter engine (//engine/src/flutter) between two releases (e.g., 3.47 vs 3.44).
flutter/flutter
How to land a formal cherry-pick of a merged PR for the flutter/flutter repo stable or beta channel.
flutter/flutter
Upgrade browser versions (Chrome or Firefox) in the Flutter Web Engine and/or Framework tests.
EliasOulkadi/shokunin
Design CI/CD pipelines for GitHub Actions, GitLab CI, and CircleCI with matrix builds, test sharding, caching, Docker layer caching, OIDC auth, deployment strategies (rolling, blue-green, canary)…
EliasOulkadi/shokunin
Build production-grade components for React, Vue 3, and Svelte 5 with all states (loading, empty, error, success, idle), TypeScript strict, WCAG 2.2 accessibility, server components (RSC), and…
EliasOulkadi/shokunin
PostgreSQL database administration — backup/restore (pgdump, PITR, WAL archiving), health monitoring (connections, bloat, cache hit ratio, dead tuples), connection pooling (PgBouncer), replication…
EliasOulkadi/shokunin
Design database schemas with Prisma/Drizzle, PostgreSQL index strategy (B-tree, GIN, GiST, BRIN, Hash), query optimization (EXPLAIN ANALYZE), migration safety (expand/contract, zero-downtime), and…
EliasOulkadi/shokunin
Optimize Docker images with multi-stage builds, distroless bases, BuildKit cache mounts, multi-arch builds, compose watch, security hardening (non-root, seccomp, capabilities drop), and…
EliasOulkadi/shokunin
Design error handling, structured logging, and observability with OpenTelemetry (traces, metrics, logs), error classification, recovery patterns (retry with jitter, circuit breaker, bulkhead…
Categories
Build production Flutter apps with Clean Architecture, Riverpod (preferred over Bloc/Provider), GoRouter navigation, Impeller rendering engine, Dart 3.7+ patterns, platform channels via Pigeon, and…. Flutter is an agent skill from EliasOulkadi/shokunin.7+ patterns, platform channels via Pigeon, and App Store/Play Store deployment.
Flutter fits situations like: tasks that involve Cross-platform mobile apps; tasks that involve App store release.
Run `npx skills add EliasOulkadi/shokunin --skill flutter -a claude-code`. Or copy the skill folder (.pack/skills/flutter in EliasOulkadi/shokunin) into .claude/skills/flutter in your project. Claude Code loads it when a task matches its description.
Run `npx skills add EliasOulkadi/shokunin --skill flutter -a codex`. Or copy the skill folder (.pack/skills/flutter in EliasOulkadi/shokunin) into .agents/skills/flutter in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add EliasOulkadi/shokunin --skill flutter -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/flutter, .gemini/skills/flutter, .github/skills/flutter and .opencode/skills/flutter in your project.
Going by SKILL.md and its folder, Flutter needs the command-line tools its instructions call (flutter and dart). Compatibility (from SKILL.md): opencode.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Flutter is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Flutter: Flutter App (ccplugins/awesome-claude-code-plugins, 970 stars), Mobile Developer (aiskillstore/marketplace, 433 stars), Flutter Security (HoangNguyen0403/agent-skills-standard, 572 stars) and Engine Whats New (flutter/flutter, 179k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
EliasOulkadi (a GitHub user) maintains it in EliasOulkadi/shokunin, which has 114 GitHub stars. The repository holds 49 skills in this directory. The repository was last updated on October 5, 2026.
Source: EliasOulkadi/shokunin on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.