Claude-skill-registry developing-with-flutter
Flutter SDK for cross-platform development targeting iOS, Android, and Web. Use for widget architecture, state management, platform channels, and multi-platform deployment.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/developing-with-flutter" ~/.claude/skills/majiayu000-claude-skill-registry-developing-with-flutter && rm -rf "$T"
skills/data/developing-with-flutter/SKILL.mdFlutter SDK Skill
Quick Reference
Flutter is Google's UI toolkit for building natively compiled applications for mobile (iOS, Android), web, and desktop from a single Dart codebase.
Table of Contents
- Critical: Avoiding Interactive Mode
- Prerequisites
- CLI Decision Tree
- Project Structure
- State Management
- Widget Patterns
- Navigation (GoRouter)
- Platform-Specific Code
- Web-Specific Considerations
- Testing
- Error Handling
- CI/CD Integration
- Auto-Detection Triggers
- Agent Integration
- Sources
Critical: Avoiding Interactive Mode
Flutter CLI can enter interactive mode which will hang Claude Code. Always use flags to bypass prompts:
| Command | WRONG (Interactive) | CORRECT (Non-Interactive) |
|---|---|---|
| Create project | (prompts) | |
| Run app | (prompts for device) | |
| Build | (may prompt) | |
| Emulators | | |
Always include:
for device selection (use-d <device_id>
to list)flutter devices- Explicit build targets (
,apk
,appbundle
,ios
)web
when pub get is not needed--no-pub
in CI/CD environments--suppress-analytics
Never use in Claude Code:
- Commands that open GUI (Android Studio, Xcode)
- Interactive device selection prompts
- Commands without explicit targets
Prerequisites
flutter --version # Expected: Flutter 3.x.x flutter doctor # Check all requirements flutter devices # List available devices flutter emulators # List available emulators
CLI Decision Tree
Project Setup
├── Create new project ────────────────► flutter create <name> --org <org> ├── Get dependencies ──────────────────► flutter pub get ├── Upgrade dependencies ──────────────► flutter pub upgrade ├── Clean build artifacts ─────────────► flutter clean └── Check project health ──────────────► flutter doctor
Development
├── Run on device ─────────────────────► flutter run -d <device_id> ├── Run in release mode ───────────────► flutter run --release -d <device_id> ├── Attach to running app ─────────────► flutter attach -d <device_id> └── View logs ─────────────────────────► flutter logs -d <device_id>
Building
├── Build Android APK ─────────────────► flutter build apk --release ├── Build Android App Bundle ──────────► flutter build appbundle --release ├── Build iOS ─────────────────────────► flutter build ios --release ├── Build iOS (no codesign) ───────────► flutter build ios --release --no-codesign └── Build Web ─────────────────────────► flutter build web --release
Testing
├── Run all tests ─────────────────────► flutter test ├── Run specific test file ────────────► flutter test test/widget_test.dart ├── Run with coverage ─────────────────► flutter test --coverage └── Run integration tests ─────────────► flutter test integration_test/
Code Quality
├── Analyze code ──────────────────────► flutter analyze ├── Format code ───────────────────────► dart format . └── Fix lint issues ───────────────────► dart fix --apply
See REFERENCE.md for complete CLI options, flavors, and advanced build configurations.
Project Structure
my_app/ ├── lib/ │ ├── main.dart # Entry point │ ├── app.dart # App widget │ ├── features/ # Feature modules │ │ └── auth/ │ │ ├── data/ # Repositories, data sources │ │ ├── domain/ # Entities, use cases │ │ └── presentation/ # Widgets, providers │ ├── core/ # Shared utilities │ └── l10n/ # Localization ├── test/ # Unit and widget tests ├── integration_test/ # Integration tests ├── android/ # Android platform code ├── ios/ # iOS platform code ├── web/ # Web platform code ├── pubspec.yaml # Dependencies └── analysis_options.yaml # Lint rules
See REFERENCE.md for complete pubspec.yaml and analysis_options.yaml configurations.
State Management
Riverpod (Recommended)
// Provider definition @riverpod class Counter extends _$Counter { @override int build() => 0; void increment() => state++; void decrement() => state--; } // Usage in widget class CounterWidget extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return Text('Count: $count'); } }
Provider (Simple apps)
class CartNotifier extends ChangeNotifier { final List<Item> _items = []; List<Item> get items => List.unmodifiable(_items); void addItem(Item item) { _items.add(item); notifyListeners(); } } // Usage final cart = context.watch<CartNotifier>();
Bloc (Enterprise apps)
// Events and States sealed class AuthEvent {} class LoginRequested extends AuthEvent { final String email, password; LoginRequested(this.email, this.password); } sealed class AuthState {} class AuthLoading extends AuthState {} class AuthSuccess extends AuthState { final User user; AuthSuccess(this.user); } // Bloc class AuthBloc extends Bloc<AuthEvent, AuthState> { AuthBloc() : super(AuthInitial()) { on<LoginRequested>(_onLoginRequested); } }
See REFERENCE.md for complete Riverpod architecture, Bloc patterns, and provider types.
Widget Patterns
StatelessWidget
class UserCard extends StatelessWidget { final User user; final VoidCallback? onTap; const UserCard({required this.user, this.onTap, super.key}); @override Widget build(BuildContext context) { return Card( child: ListTile( leading: CircleAvatar(backgroundImage: NetworkImage(user.avatarUrl)), title: Text(user.name), subtitle: Text(user.email), onTap: onTap, ), ); } }
StatefulWidget
class SearchField extends StatefulWidget { final ValueChanged<String> onChanged; const SearchField({required this.onChanged, super.key}); @override State<SearchField> createState() => _SearchFieldState(); } class _SearchFieldState extends State<SearchField> { final _controller = TextEditingController(); Timer? _debounce; @override void dispose() { _debounce?.cancel(); _controller.dispose(); super.dispose(); } void _onSearchChanged(String value) { _debounce?.cancel(); _debounce = Timer(const Duration(milliseconds: 300), () { widget.onChanged(value); }); } @override Widget build(BuildContext context) { return TextField(controller: _controller, onChanged: _onSearchChanged); } }
See REFERENCE.md for compound widgets, builder patterns, and hook widgets.
Navigation (GoRouter)
final router = GoRouter( initialLocation: '/', routes: [ GoRoute( path: '/', builder: (context, state) => const HomeScreen(), routes: [ GoRoute( path: 'user/:id', builder: (context, state) { final id = state.pathParameters['id']!; return UserScreen(userId: id); }, ), ], ), ], errorBuilder: (context, state) => ErrorScreen(error: state.error), ); // Usage context.go('/user/123'); context.push('/user/123'); context.pop();
See REFERENCE.md for deep linking, shell routes, and platform-specific configuration.
Platform-Specific Code
Platform Checks
import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; Widget build(BuildContext context) { if (kIsWeb) return WebSpecificWidget(); if (Platform.isIOS) return CupertinoWidget(); if (Platform.isAndroid) return MaterialWidget(); return DefaultWidget(); }
Platform Channels (Native Integration)
class BatteryLevel { static const platform = MethodChannel('com.example.app/battery'); Future<int> getBatteryLevel() async { try { return await platform.invokeMethod('getBatteryLevel'); } on PlatformException catch (e) { throw Exception('Failed: ${e.message}'); } } }
See REFERENCE.md for iOS/Android native code, conditional imports, and event channels.
Web-Specific Considerations
Build Renderers
flutter build web --web-renderer canvaskit # Better fidelity, larger flutter build web --web-renderer html # Smaller size flutter build web --web-renderer auto # Auto-detect
Best for: Internal tools, dashboards, PWAs, authenticated apps Note: Flutter web renders to canvas - limited SEO by default
Testing
Widget Tests
void main() { testWidgets('Counter increments', (tester) async { await tester.pumpWidget(const MyApp()); expect(find.text('0'), findsOneWidget); await tester.tap(find.byIcon(Icons.add)); await tester.pump(); expect(find.text('1'), findsOneWidget); }); }
Golden Tests
testWidgets('Button matches golden', (tester) async { await tester.pumpWidget(MaterialApp(home: MyButton(label: 'Submit'))); await expectLater(find.byType(MyButton), matchesGoldenFile('goldens/my_button.png')); }); // Update: flutter test --update-goldens
See REFERENCE.md for integration tests, provider testing, and complete test patterns.
Error Handling
| Error | Solution |
|---|---|
| Run , start emulator |
| Run , check Android Studio |
| |
| Check , run |
Debug Commands
flutter run -v # Verbose output flutter doctor -v # Check for issues flutter clean && flutter pub get # Clean rebuild
See REFERENCE.md for complete troubleshooting guide and CI/CD issues.
CI/CD Integration
- uses: subosito/flutter-action@v2 with: flutter-version: "3.24.0" channel: stable cache: true - run: flutter pub get - run: flutter analyze - run: flutter test --coverage - run: flutter build apk --release
See REFERENCE.md for complete GitHub Actions workflows and multi-platform builds.
Auto-Detection Triggers
This skill auto-loads when Flutter context is detected:
File-based triggers:
withpubspec.yaml
dependencyflutter
presentlib/main.dart
files in project.dart
andandroid/
directoriesios/
Context-based triggers:
- User mentions "Flutter"
- User runs flutter CLI commands
- Widget development discussions
Agent Integration
| Agent | Use Case |
|---|---|
| Primary agent for Flutter development |
| Performance profiling, crash analysis |
| Dart code review, accessibility audit |
| App store submissions |
Handoff to Deep-Debugger:
- Performance profiling needed
- Crash analysis required
- Memory leak investigation
- Platform-specific bugs