本文へ移動
cccskills
無料GitHub で公開

flutter

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.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md12.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Flutter Architect

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.

Decision Framework

Before writing Flutter code, answer:

  • Is native performance critical? (animations, camera, maps) → Flutter is a strong fit
  • Is the team already experienced with Dart? → Proceed. If React/TypeScript, consider react-native skill
  • Is the app content-heavy with standard platform UI? → Consider native or react-native
  • Does the app need platform-specific features not available in packages? → Verify pub.dev coverage first

Workflow

  1. Scaffold: dart run flutter_skeleton or create lib/core, lib/features/*/domain|data|presentation by hand. Add Riverpod + GoRouter + Freezed deps in pubspec.yaml.
  2. Domain first: Define entities, repository contracts, and use cases. Zero Flutter imports. Pure Dart with freezed for sealed unions.
  3. Data layer: Implement repositories with Dio/retrofit, DTOs with json_serializable, and data sources. Wire up in Riverpod with Provider<AuthRepository>.
  4. Presentation: Build screens and widgets with ConsumerWidget/ConsumerStatefulWidget. Wire NotifierProvider for each feature. Keep ref.watch at leaf level.
  5. Routing: Configure GoRouter with auth redirect (redirect guard), nested routes per feature, and deep link patterns.
  6. Ship: Run tests → flutter build appbundle / flutter build ipa → deploy via Codemagic or GitHub Actions. Enable Impeller on Android in build.gradle.

Sub-Commands

CommandDescription
scaffoldCreate project with folder structure and dependencies
featureDesign a feature with domain/data/presentation layers
stateSet up Riverpod providers for a feature
routeConfigure GoRouter with auth guard and deep links
testWrite unit + widget + integration tests
shipBuild and deploy to App Store + Play Store

Architecture

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.dart

Domain Layer (zero Flutter imports)

class 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);
}

Riverpod State Management

ScenarioProvider
Most appsRiverpod (async-first, testable, DI built-in)
Large team, strict unidirectionalBloc (explicit events/states)
Legacy or tinyProvider (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(),
    );
  }
}

GoRouter with Auth Guard

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()),
  ],
);

Impeller

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.

Platform Channels via Pigeon

// battery.dart (Pigeon input)
@HostApi()
abstract class BatteryApi {
  int getBatteryLevel();
}

Run: dart run pigeon --input battery.dart --dart_out lib/battery.dart

Performance Rules

  • const constructors everywhere
  • Consumer at leaf level (not entire screen)
  • ListView.builder / GridView.builder (lazy)
  • cached_network_image
  • Profile: flutter run --profile, DevTools
  • Avoid RepaintBoundary overuse

Perceived Performance

Flutter renders at 60fps on most devices and 120fps on ProMotion displays. Performance perception differs:

TechniquePerception impactImplementation
Skeleton loadersFeels faster than spinners. Shows structure immediately.shimmer package with matching layout shape
const constructorsWidgets that never change skip rebuild entirely. Cumulative gain on deep trees.const Text('...'), const SizedBox(...), const Icon(...)
extent estimation on scrollablesEliminates jank from recalculating item sizes during scroll.ListView.builder(itemExtent: 56.0, ...)
AnimatedSwitcher vs VisibilityFade transitions feel smoother than instant appear/disappear.Wrap changing content in AnimatedSwitcher(duration: 200ms)
RepaintBoundaryIsolates repaint of frequently-changing widgets (timers, animations) from rest of tree.Wrap animated clock/progress bar in RepaintBoundary

Error Handling

ScenarioCauseFix
Bad state: No elementEmpty stream/iterable accessed without checkGuard with .isEmpty or use .firstOrNull
LateInitializationErrorlate variable accessed before initUse nullable T? or StateNotifier with initial value
Platform channel: MissingPluginExceptionMethod not implemented on native sideVerify Pigeon codegen ran, check method name matches both sides
ConcurrentModificationErrorModifying list while iteratingUse .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 DTOAdd @JsonKey(defaultValue: '') or make fields nullable, run codegen
GoRouter: GoError: no routes for locationDeep link path not registeredAdd fallback redirect to / or register catch-all /* route
Riverpod: provider not disposedCircular dependency between providersUse 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 pluginRun ./gradlew --refresh-dependencies, check build.gradle versions match AGP requirements

Production Checklist

  • Riverpod providers: domain → data → presentation layers
  • Domain layer: zero Flutter imports
  • GoRouter: auth redirect + deep linking
  • Impeller enabled on Android
  • const constructors everywhere
  • Platform channels via Pigeon (not manual MethodChannel)
  • Unit tests for domain layer
  • Widget tests for critical screens
  • CI/CD: Codemagic / GitHub Actions
  • ErrorWidget.builder + PlatformDispatcher.onError
  • Retry logic on network failures
  • Freezed / sealed classes for state unions

Anti-Patterns

Anti-patternFix
Business logic in widgetsExtract to Riverpod notifiers / use cases
ref.watch inside callbacksref.read for one-time reads
Giant widgets > 200 linesExtract into smaller widgets
Manual MethodChannelPigeon for type-safe channels
No error handling in AsyncValueHandle loading/error/data explicitly
One giant GoRouter fileSplit routes into feature modules

Review Format (Required)

When reviewing Flutter code, use Before | After | Why format:

BeforeAfterWhy
setState(() { count++; }) in large widgetref.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

Perceived Performance (Extended)

Flutter renders at 60fps on most devices, 120fps on ProMotion displays.

TechniquePerceptionImplementation
const constructorsWidgets that never change skip rebuild entirelyconst Text(...), const SizedBox(...)
RepaintBoundaryIsolates frequently-changing widgets (timers, animations)Wrap clock/progress bar in RepaintBoundary
Skeleton loadersShows structure immediately (feels faster than spinners)shimmer package with matching layout
itemExtent on listsEliminates jank from recalculating sizes during scrollListView.builder(itemExtent: 56.0)
AnimatedSwitcherFade transitions feel smoother than instant appear/disappearWrap changing content, set duration: 200ms
Hero animationsCreate continuity between screensHero(tag: 'avatar', child: ...) on source and destination
Pre-cache imagesEliminates flash-of-placeholder on revisitprecacheImage(NetworkImage(url), context) in initState

Rule: The user feels the slowest frame. Optimize for worst case, not average.

Sources

  • Flutter Documentation (flutter.dev)
  • Dart 3.7 Language Tour (dart.dev)
  • Riverpod Documentation (riverpod.dev)
  • GoRouter Documentation
  • Impeller Rendering Engine
  • Pigeon Plugin

Pre-Flight Checklist

Before submitting Flutter code:

  • All widgets use const constructors where possible (check with dart analyze)
  • Long lists use ListView.builder or SliverList.builder, never ListView(children: [...])
  • ref.watch only in build methods; ref.read only in callbacks
  • Routes use GoRouter typed parameters, not manual string parsing
  • AsyncValue has .when(data:, loading:, error:) — all three branches covered
  • Platform channels use Pigeon-generated code, never manual MethodChannel
  • android/app/build.gradle has renderingEngine = "impeller" (Android 14+)
  • No console.log or print() statements in production code
  • flutter analyze passes with zero errors or warnings
  • Tested on real Android device (not just iOS simulator or vice versa)
  • App works correctly when process is killed and restarted (state restoration)
  • Safe areas respected: MediaQuery.of(context).padding or SafeArea widget

Checklist

  • Skill loads without errors in the AI agent
  • YAML frontmatter is valid (description, compatibility, audience)
  • Workflow section provides clear step-by-step instructions
  • Error handling section covers common failure modes
  • All referenced files (references/, scripts/, assets/) exist
  • Skill triggers correctly for intended use cases
  • No broken links or missing resources

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Apply professional, premium UI/UX design standards when building or styling web interfaces. Use this skill when the user asks to create a website, landing page, web app, dashboard, UI component, or any visual interface — or when they ask to make something look better, more professional, or more beautiful. Covers visual hierarchy, typography, color systems, layout, spacing, motion, dark mode, responsive design, and conversion patterns. Activate even when the user doesn't say "design" — if they're building a web frontend, these standards apply.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Run 150+ AI apps via inference.sh CLI - image generation, video creation, LLMs, search, 3D, Twitter automation. Models: FLUX, Veo, Gemini, Grok, Claude, Seedance, OmniHuman, Tavily, Exa, OpenRouter, and many more. Use when running AI apps, generating images/videos, calling LLMs, web search, or automating Twitter. Triggers: inference.sh, infsh, ai model, run ai, serverless ai, ai api, flux, veo, claude api, image generation, video generation, openrouter, tavily, exa search, twitter api, grok

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

api-forge

無料

Design REST/GraphQL APIs with OpenAPI 3.1, error handling, pagination, rate limiting, webhooks, and idempotency. Use when user asks to design an API, create endpoints, define REST/GraphQL schema, or generate OpenAPI spec. Do NOT use for database schema design, frontend API integration, or non-HTTP protocols (gRPC, WebSocket, MQTT).

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Implement authentication and authorization with OWASP Top 10 standards, OAuth 2.0 + OIDC, WebAuthn/Passkeys, session management, and RBAC/ABAC. Use when user asks to implement login, signup, authentication, authorization, JWT, OAuth, SSO, passkeys, MFA, or role-based access. Do NOT use for API key management (use api-forge), encryption at rest, or network-level security (firewalls, WAF).

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Generate brand guidelines, design systems with design tokens (W3C format), creative direction (SCAMPER, Design Thinking, TRIZ), and design briefs with scope and success criteria.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

EliasOulkadi のスキルをすべて見る

このスキルの問題を報告する