Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    up1

    flutter-development

    up1/flutter-development
    Coding
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

    SKILL.md

    Flutter Development

    Overview

    Create high-performance, visually stunning mobile applications using Flutter with Dart language. Master widget composition, state management patterns, navigation, and API integration.

    When to Use

    • Building iOS and Android apps with native performance
    • Designing custom UIs with Flutter's widget system
    • Implementing complex animations and visual effects
    • Rapid app development with hot reload
    • Creating consistent UX across platforms

    Instructions

    1. Project Structure & Navigation

    // pubspec.yaml
    name: my_flutter_app
    version: 1.0.0
    
    dependencies:
      flutter:
        sdk: flutter
      provider: ^6.0.0
      http: ^1.1.0
      go_router: ^12.0.0
    
    // main.dart with GoRouter navigation
    import 'package:flutter/material.dart';
    import 'package:go_router/go_router.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp.router(
          title: 'Flutter App',
          theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
          routerConfig: _router,
        );
      }
    }
    
    final GoRouter _router = GoRouter(
      routes: <RouteBase>[
        GoRoute(
          path: '/',
          builder: (context, state) => const HomeScreen(),
          routes: [
            GoRoute(
              path: 'details/:id',
              builder: (context, state) => DetailsScreen(
                itemId: state.pathParameters['id']!
              ),
            ),
          ],
        ),
        GoRoute(
          path: '/profile',
          builder: (context, state) => const ProfileScreen(),
        ),
      ],
    );
    

    2. State Management with Provider

    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    class User {
      final String id;
      final String name;
      final String email;
    
      User({required this.id, required this.name, required this.email});
    
      factory User.fromJson(Map<String, dynamic> json) {
        return User(
          id: json['id'],
          name: json['name'],
          email: json['email'],
        );
      }
    }
    
    class UserProvider extends ChangeNotifier {
      User? _user;
      bool _isLoading = false;
      String? _error;
    
      User? get user => _user;
      bool get isLoading => _isLoading;
      String? get error => _error;
    
      Future<void> fetchUser(String userId) async {
        _isLoading = true;
        _error = null;
        notifyListeners();
    
        try {
          final response = await http.get(
            Uri.parse('https://api.example.com/users/$userId'),
            headers: {'Content-Type': 'application/json'},
          );
    
          if (response.statusCode == 200) {
            _user = User.fromJson(jsonDecode(response.body));
          } else {
            _error = 'Failed to fetch user';
          }
        } catch (e) {
          _error = 'Error: ${e.toString()}';
        } finally {
          _isLoading = false;
          notifyListeners();
        }
      }
    
      void logout() {
        _user = null;
        notifyListeners();
      }
    }
    
    class ItemsProvider extends ChangeNotifier {
      List<Map<String, dynamic>> _items = [];
    
      List<Map<String, dynamic>> get items => _items;
    
      Future<void> fetchItems() async {
        try {
          final response = await http.get(
            Uri.parse('https://api.example.com/items'),
          );
    
          if (response.statusCode == 200) {
            _items = List<Map<String, dynamic>>.from(
              jsonDecode(response.body) as List
            );
            notifyListeners();
          }
        } catch (e) {
          print('Error fetching items: $e');
        }
      }
    }
    

    3. Screens with Provider Integration

    class HomeScreen extends StatefulWidget {
      const HomeScreen({Key? key}) : super(key: key);
    
      @override
      State<HomeScreen> createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
      @override
      void initState() {
        super.initState();
        Future.microtask(() {
          Provider.of<ItemsProvider>(context, listen: false).fetchItems();
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Home Feed')),
          body: Consumer<ItemsProvider>(
            builder: (context, itemsProvider, child) {
              if (itemsProvider.items.isEmpty) {
                return const Center(child: Text('No items found'));
              }
              return ListView.builder(
                itemCount: itemsProvider.items.length,
                itemBuilder: (context, index) {
                  final item = itemsProvider.items[index];
                  return ItemCard(item: item);
                },
              );
            },
          ),
        );
      }
    }
    
    class ItemCard extends StatelessWidget {
      final Map<String, dynamic> item;
    
      const ItemCard({required this.item, Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Card(
          margin: const EdgeInsets.all(8),
          child: ListTile(
            title: Text(item['title'] ?? 'Untitled'),
            subtitle: Text(item['description'] ?? ''),
            trailing: const Icon(Icons.arrow_forward),
            onTap: () => context.go('/details/${item['id']}'),
          ),
        );
      }
    }
    
    class DetailsScreen extends StatelessWidget {
      final String itemId;
    
      const DetailsScreen({required this.itemId, Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Details')),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Item ID: $itemId', style: const TextStyle(fontSize: 18)),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => context.pop(),
                  child: const Text('Go Back'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class ProfileScreen extends StatelessWidget {
      const ProfileScreen({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Profile')),
          body: Consumer<UserProvider>(
            builder: (context, userProvider, child) {
              if (userProvider.isLoading) {
                return const Center(child: CircularProgressIndicator());
              }
              if (userProvider.error != null) {
                return Center(child: Text('Error: ${userProvider.error}'));
              }
              final user = userProvider.user;
              if (user == null) {
                return const Center(child: Text('No user data'));
              }
              return Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Name: ${user.name}', style: const TextStyle(fontSize: 18)),
                    Text('Email: ${user.email}', style: const TextStyle(fontSize: 16)),
                    const SizedBox(height: 16),
                    ElevatedButton(
                      onPressed: () => userProvider.logout(),
                      child: const Text('Logout'),
                    ),
                  ],
                ),
              );
            },
          ),
        );
      }
    }
    

    4. UI Testing with Patrol

    • Success cases
    • Failure cases

    Install

    flutter pub global activate patrol_cli
    flutter pub add patrol --dev
    

    Generate test case in folder patrol_test

    Best Practices

    ✅ DO

    • Use widgets for every UI element
    • Implement proper state management
    • Use const constructors where possible
    • Dispose resources in state lifecycle
    • Test on multiple device sizes
    • Use meaningful widget names
    • Implement error handling
    • Use responsive design patterns
    • Test on both iOS and Android
    • Document custom widgets

    ❌ DON'T

    • Build entire screens in build() method
    • Use setState for complex state logic
    • Make network calls in build()
    • Ignore platform differences
    • Create overly nested widget trees
    • Hardcode strings
    • Ignore performance warnings
    • Skip testing
    • Forget to handle edge cases
    • Deploy without thorough testing
    Recommended Servers
    InstantDB
    InstantDB
    Todoist
    Todoist
    Svelte
    Svelte
    Repository
    up1/poc-mobile-testing-lab
    Files