🎯

flutter-development

🎯Skill

from travisjneuman/.claude

VibeIndex|
What it does

Develops cross-platform mobile, web, and desktop applications using Flutter and Dart with native performance and a single codebase.

πŸ“¦

Part of

travisjneuman/.claude(62 items)

flutter-development

Installation

git cloneClone repository
git clone https://github.com/travisjneuman/.claude.git ~/.claude
Install ScriptRun install script
curl -fsSL https://raw.githubusercontent.com/travisjneuman/.claude/master/scripts/install.sh | bash
git cloneClone repository
git clone --recurse-submodules https://github.com/travisjneuman/.claude.git ~/.claude
npxRun with npx
npx vite-bundle-visualizer
npxRun with npx
npx knip
Server ConfigurationMCP server configuration block
{ "mcpServers": { // ─────────────────────────────────────────────────────...
πŸ“– Extracted from docs: travisjneuman/.claude
2Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Cross-platform development with Flutter and Dart for iOS, Android, Web, Desktop, and embedded. Use when building Flutter apps, implementing Material/Cupertino design, or optimizing Dart code.

Overview

# Flutter Development

Build beautiful, natively compiled applications for mobile, web, desktop, and embedded from a single codebase.

Supported Platforms

| Platform | Status | Notes |

| -------- | ------ | ----------------------- |

| iOS | Stable | Full native performance |

| Android | Stable | Full native performance |

| Web | Stable | PWA support |

| macOS | Stable | Native desktop |

| Windows | Stable | Native desktop |

| Linux | Stable | Native desktop |

---

Project Structure

```

my_app/

β”œβ”€β”€ lib/

β”‚ β”œβ”€β”€ main.dart

β”‚ β”œβ”€β”€ app.dart

β”‚ β”œβ”€β”€ features/

β”‚ β”‚ β”œβ”€β”€ home/

β”‚ β”‚ β”‚ β”œβ”€β”€ home_screen.dart

β”‚ β”‚ β”‚ β”œβ”€β”€ home_controller.dart

β”‚ β”‚ β”‚ └── widgets/

β”‚ β”‚ └── settings/

β”‚ β”œβ”€β”€ core/

β”‚ β”‚ β”œβ”€β”€ theme/

β”‚ β”‚ β”œβ”€β”€ utils/

β”‚ β”‚ └── constants/

β”‚ └── shared/

β”‚ β”œβ”€β”€ models/

β”‚ β”œβ”€β”€ services/

β”‚ └── widgets/

β”œβ”€β”€ test/

β”œβ”€β”€ pubspec.yaml

└── analysis_options.yaml

```

---

Basic Structure

Main Entry

```dart

import 'package:flutter/material.dart';

void main() {

runApp(const MyApp());

}

class MyApp extends StatelessWidget {

const MyApp({super.key});

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'My App',

theme: ThemeData(

colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),

useMaterial3: true,

),

home: const HomeScreen(),

);

}

}

```

Stateless Widget

```dart

class GreetingCard extends StatelessWidget {

const GreetingCard({

super.key,

required this.name,

});

final String name;

@override

Widget build(BuildContext context) {

return Card(

child: Padding(

padding: const EdgeInsets.all(16),

child: Text(

'Hello, $name!',

style: Theme.of(context).textTheme.headlineMedium,

),

),

);

}

}

```

Stateful Widget

```dart

class Counter extends StatefulWidget {

const Counter({super.key});

@override

State createState() => _CounterState();

}

class _CounterState extends State {

int _count = 0;

void _increment() {

setState(() {

_count++;

});

}

@override

Widget build(BuildContext context) {

return Column(

mainAxisAlignment: MainAxisAlignment.center,

children: [

Text(

'Count: $_count',

style: Theme.of(context).textTheme.headlineLarge,

),

const SizedBox(height: 16),

ElevatedButton(

onPressed: _increment,

child: const Text('Increment'),

),

],

);

}

}

```

---

State Management

Riverpod (Recommended)

```dart

// Provider definition

final counterProvider = StateNotifierProvider((ref) {

return CounterNotifier();

});

class CounterNotifier extends StateNotifier {

CounterNotifier() : super(0);

void increment() => state++;

void decrement() => state--;

}

// Usage in widget

class CounterScreen extends ConsumerWidget {

const CounterScreen({super.key});

@override

Widget build(BuildContext context, WidgetRef ref) {

final count = ref.watch(counterProvider);

return Scaffold(

body: Center(

child: Text('Count: $count'),

),

floatingActionButton: FloatingActionButton(

onPressed: () => ref.read(counterProvider.notifier).increment(),

child: const Icon(Icons.add),

),

);

}

}

// Async provider

final itemsProvider = FutureProvider>((ref) async {

final repository = ref.watch(repositoryProvider);

return repository.fetchItems();

});

```

BLoC Pattern

```dart

// Events

abstract class CounterEvent {}

class IncrementPressed extends CounterEvent {}

class DecrementPressed extends CounterEvent {}

// State

class CounterState {

final int count;

const CounterState(this.count);

}

// BLoC

class CounterBloc extends Bloc {

CounterBloc() : super(const CounterState(0)) {

on((event, emit) {

emit(CounterState(state.count + 1));

});

on((event, emit) {

emit(CounterState(state.count - 1));

});

}

}

// Usage

BlocBuilder(

builder: (context, state) {

return Text('Count: ${state.count}');

},

)

```

---

Navigation

GoRouter (Recommended)

```dart

final router = GoRouter(

initialLocation: '/',

routes: [

GoRoute(

path: '/',

builder: (context, state) => const HomeScreen(),

routes: [

GoRoute(

path: 'details/:id',

builder: (context, state) {

final id = state.pathParameters['id']!;

return DetailsScreen(id: id);

},

),

],

),

GoRoute(

path: '/settings',

builder: (context, state) => const SettingsScreen(),

),

],

);

// Usage

MaterialApp.router(

routerConfig: router,

)

// Navigate

context.go('/details/123');

context.push('/settings');

context.pop();

```

---

Common Widgets

Lists

```dart

ListView.builder(

itemCount: items.length,

itemBuilder: (context, index) {

final item = items[index];

return ListTile(

leading: CircleAvatar(

backgroundImage: NetworkImage(item.imageUrl),

),

title: Text(item.title),

subtitle: Text(item.subtitle),

trailing: const Icon(Icons.chevron_right),

onTap: () => context.push('/details/${item.id}'),

);

},

)

```

Forms

```dart

class LoginForm extends StatefulWidget {

const LoginForm({super.key});

@override

State createState() => _LoginFormState();

}

class _LoginFormState extends State {

final _formKey = GlobalKey();

final _emailController = TextEditingController();

final _passwordController = TextEditingController();

@override

void dispose() {

_emailController.dispose();

_passwordController.dispose();

super.dispose();

}

void _submit() {

if (_formKey.currentState!.validate()) {

// Process login

}

}

@override

Widget build(BuildContext context) {

return Form(

key: _formKey,

child: Column(

children: [

TextFormField(

controller: _emailController,

decoration: const InputDecoration(

labelText: 'Email',

prefixIcon: Icon(Icons.email),

),

keyboardType: TextInputType.emailAddress,

validator: (value) {

if (value == null || !value.contains('@')) {

return 'Enter a valid email';

}

return null;

},

),

const SizedBox(height: 16),

TextFormField(

controller: _passwordController,

decoration: const InputDecoration(

labelText: 'Password',

prefixIcon: Icon(Icons.lock),

),

obscureText: true,

validator: (value) {

if (value == null || value.length < 6) {

return 'Password must be at least 6 characters';

}

return null;

},

),

const SizedBox(height: 24),

ElevatedButton(

onPressed: _submit,

child: const Text('Login'),

),

],

),

);

}

}

```

---

Networking

Dio HTTP Client

```dart

class ApiService {

final Dio _dio;

ApiService() : _dio = Dio(BaseOptions(

baseUrl: 'https://api.example.com',

connectTimeout: const Duration(seconds: 10),

receiveTimeout: const Duration(seconds: 10),

)) {

_dio.interceptors.add(LogInterceptor());

}

Future> getItems() async {

try {

final response = await _dio.get('/items');

return (response.data as List)

.map((json) => Item.fromJson(json))

.toList();

} on DioException catch (e) {

throw ApiException(e.message ?? 'Unknown error');

}

}

}

```

---

Local Storage

Hive (Recommended)

```dart

// Model

@HiveType(typeId: 0)

class Item extends HiveObject {

@HiveField(0)

late String id;

@HiveField(1)

late String name;

}

// Setup

await Hive.initFlutter();

Hive.registerAdapter(ItemAdapter());

await Hive.openBox('items');

// Usage

final box = Hive.box('items');

await box.put('key', item);

final item = box.get('key');

```

SharedPreferences

```dart

final prefs = await SharedPreferences.getInstance();

await prefs.setString('token', 'abc123');

final token = prefs.getString('token');

```

---

Platform-Specific Code

```dart

import 'dart:io' show Platform;

import 'package:flutter/foundation.dart' show kIsWeb;

Widget build(BuildContext context) {

if (kIsWeb) {

return WebLayout();

} else if (Platform.isIOS) {

return CupertinoLayout();

} else if (Platform.isAndroid) {

return MaterialLayout();

} else if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {

return DesktopLayout();

}

return DefaultLayout();

}

```

---

Testing

Widget Tests

```dart

testWidgets('Counter increments', (tester) async {

await tester.pumpWidget(const MaterialApp(home: Counter()));

expect(find.text('Count: 0'), findsOneWidget);

await tester.tap(find.byIcon(Icons.add));

await tester.pump();

expect(find.text('Count: 1'), findsOneWidget);

});

```

Unit Tests

```dart

test('Item fromJson parses correctly', () {

final json = {'id': '1', 'name': 'Test'};

final item = Item.fromJson(json);

expect(item.id, '1');

expect(item.name, 'Test');

});

```

---

Performance

Best Practices

```dart

// Use const constructors

const SizedBox(height: 16)

// Avoid rebuilds with const

const MyStaticWidget()

// Use ListView.builder for long lists

ListView.builder(

itemCount: items.length,

itemBuilder: (context, index) => ItemWidget(items[index]),

)

// Cache images

CachedNetworkImage(

imageUrl: url,

placeholder: (context, url) => const CircularProgressIndicator(),

)

```

---

Best Practices

DO:

  • Use const constructors everywhere possible
  • Split widgets into smaller components
  • Use Riverpod or BLoC for state
  • Follow Flutter naming conventions
  • Write widget tests

DON'T:

  • Put logic in build methods
  • Create god widgets
  • Use setState for complex state
  • Ignore null safety
  • Skip code generation setup