RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/ThanhTrunggDEV/DontBeLazy

Cursor rule

.cursor/rules/dart-patterns.mdc
Cursor rules

Quality

74/100

Scores the file, not the repository.

Length

724 words

11 headings · 9 code blocks

Repository

6

— · pushed 80 days ago

Last changed

3 days ago

First indexed 3 days ago.
ThanhTrunggDEV/DontBeLazy/.cursor/rules/dart-patterns.mdcRawGitHub
1---
2paths:
3 - "**/*.dart"
4 - "**/pubspec.yaml"
5---
6# Dart/Flutter Patterns
7 
8> This file extends [common/patterns.md](../common/patterns.md) with Dart, Flutter, and common ecosystem-specific content.
9 
10## Repository Pattern
11 
12```dart
13abstract interface class UserRepository {
14 Future<User?> getById(String id);
15 Future<List<User>> getAll();
16 Stream<List<User>> watchAll();
17 Future<void> save(User user);
18 Future<void> delete(String id);
19}
20 
21class UserRepositoryImpl implements UserRepository {
22 const UserRepositoryImpl(this._remote, this._local);
23 
24 final UserRemoteDataSource _remote;
25 final UserLocalDataSource _local;
26 
27 @override
28 Future<User?> getById(String id) async {
29 final local = await _local.getById(id);
30 if (local != null) return local;
31 final remote = await _remote.getById(id);
32 if (remote != null) await _local.save(remote);
33 return remote;
34 }
35 
36 @override
37 Future<List<User>> getAll() async {
38 final remote = await _remote.getAll();
39 for (final user in remote) {
40 await _local.save(user);
41 }
42 return remote;
43 }
44 
45 @override
46 Stream<List<User>> watchAll() => _local.watchAll();
47 
48 @override
49 Future<void> save(User user) => _local.save(user);
50 
51 @override
52 Future<void> delete(String id) async {
53 await _remote.delete(id);
54 await _local.delete(id);
55 }
56}
57```
58 
59## State Management: BLoC/Cubit
60 
61```dart
62// Cubit — simple state transitions
63class CounterCubit extends Cubit<int> {
64 CounterCubit() : super(0);
65 
66 void increment() => emit(state + 1);
67 void decrement() => emit(state - 1);
68}
69 
70// BLoC — event-driven
71@immutable
72sealed class CartEvent {}
73class CartItemAdded extends CartEvent { CartItemAdded(this.item); final Item item; }
74class CartItemRemoved extends CartEvent { CartItemRemoved(this.id); final String id; }
75class CartCleared extends CartEvent {}
76 
77@immutable
78class CartState {
79 const CartState({this.items = const []});
80 final List<Item> items;
81 CartState copyWith({List<Item>? items}) => CartState(items: items ?? this.items);
82}
83 
84class CartBloc extends Bloc<CartEvent, CartState> {
85 CartBloc() : super(const CartState()) {
86 on<CartItemAdded>((event, emit) =>
87 emit(state.copyWith(items: [...state.items, event.item])));
88 on<CartItemRemoved>((event, emit) =>
89 emit(state.copyWith(items: state.items.where((i) => i.id != event.id).toList())));
90 on<CartCleared>((_, emit) => emit(const CartState()));
91 }
92}
93```
94 
95## State Management: Riverpod
96 
97```dart
98// Simple provider
99@riverpod
100Future<List<User>> users(Ref ref) async {
101 final repo = ref.watch(userRepositoryProvider);
102 return repo.getAll();
103}
104 
105// Notifier for mutable state
106@riverpod
107class CartNotifier extends _$CartNotifier {
108 @override
109 List<Item> build() => [];
110 
111 void add(Item item) => state = [...state, item];
112 void remove(String id) => state = state.where((i) => i.id != id).toList();
113 void clear() => state = [];
114}
115 
116// ConsumerWidget
117class CartPage extends ConsumerWidget {
118 const CartPage({super.key});
119 
120 @override
121 Widget build(BuildContext context, WidgetRef ref) {
122 final items = ref.watch(cartNotifierProvider);
123 return ListView(
124 children: items.map((item) => CartItemTile(item: item)).toList(),
125 );
126 }
127}
128```
129 
130## Dependency Injection
131 
132Constructor injection is preferred. Use `get_it` or Riverpod providers at composition root:
133 
134```dart
135// get_it registration (in a setup file)
136void setupDependencies() {
137 final di = GetIt.instance;
138 di.registerSingleton<ApiClient>(ApiClient(baseUrl: Env.apiUrl));
139 di.registerSingleton<UserRepository>(
140 UserRepositoryImpl(di<ApiClient>(), di<LocalDatabase>()),
141 );
142 di.registerFactory(() => UserListViewModel(di<UserRepository>()));
143}
144```
145 
146## ViewModel Pattern (without BLoC/Riverpod)
147 
148```dart
149class UserListViewModel extends ChangeNotifier {
150 UserListViewModel(this._repository);
151 
152 final UserRepository _repository;
153 
154 AsyncState<List<User>> _state = const Loading();
155 AsyncState<List<User>> get state => _state;
156 
157 Future<void> load() async {
158 _state = const Loading();
159 notifyListeners();
160 try {
161 final users = await _repository.getAll();
162 _state = Success(users);
163 } on Exception catch (e) {
164 _state = Failure(e);
165 }
166 notifyListeners();
167 }
168}
169```
170 
171## UseCase Pattern
172 
173```dart
174class GetUserUseCase {
175 const GetUserUseCase(this._repository);
176 final UserRepository _repository;
177 
178 Future<User?> call(String id) => _repository.getById(id);
179}
180 
181class CreateUserUseCase {
182 const CreateUserUseCase(this._repository, this._idGenerator);
183 final UserRepository _repository;
184 final IdGenerator _idGenerator; // injected — domain layer must not depend on uuid package directly
185 
186 Future<void> call(CreateUserInput input) async {
187 // Validate, apply business rules, then persist
188 final user = User(id: _idGenerator.generate(), name: input.name, email: input.email);
189 await _repository.save(user);
190 }
191}
192```
193 
194## Immutable State with freezed
195 
196```dart
197@freezed
198class UserState with _$UserState {
199 const factory UserState({
200 @Default([]) List<User> users,
201 @Default(false) bool isLoading,
202 String? errorMessage,
203 }) = _UserState;
204}
205```
206 
207## Clean Architecture Layer Boundaries
208 
209```
210lib/
211├── domain/ # Pure Dart — no Flutter, no external packages
212│ ├── entities/
213│ ├── repositories/ # Abstract interfaces
214│ └── usecases/
215├── data/ # Implements domain interfaces
216│ ├── datasources/
217│ ├── models/ # DTOs with fromJson/toJson
218│ └── repositories/
219└── presentation/ # Flutter widgets + state management
220 ├── pages/
221 ├── widgets/
222 └── providers/ (or blocs/ or viewmodels/)
223```
224 
225- Domain must not import `package:flutter` or any data-layer package
226- Data layer maps DTOs to domain entities at repository boundaries
227- Presentation calls use cases, not repositories directly
228 
229## Navigation (GoRouter)
230 
231```dart
232final router = GoRouter(
233 routes: [
234 GoRoute(
235 path: '/',
236 builder: (context, state) => const HomePage(),
237 ),
238 GoRoute(
239 path: '/users/:id',
240 builder: (context, state) {
241 final id = state.pathParameters['id']!;
242 return UserDetailPage(userId: id);
243 },
244 ),
245 ],
246 // refreshListenable re-evaluates redirect whenever auth state changes
247 refreshListenable: GoRouterRefreshStream(authCubit.stream),
248 redirect: (context, state) {
249 final isLoggedIn = context.read<AuthCubit>().state is AuthAuthenticated;
250 if (!isLoggedIn && !state.matchedLocation.startsWith('/login')) {
251 return '/login';
252 }
253 return null;
254 },
255);
256```
257 
258## References
259 
260See skill: `flutter-dart-code-review` for the comprehensive review checklist.
261See skill: `compose-multiplatform-patterns` for Kotlin Multiplatform/Flutter interop patterns.
262 

Commands it names

  • flutter-dart-code-review

Sections

  • Dart/Flutter Patterns
  • Repository Pattern
  • State Management: BLoC/Cubit
  • State Management: Riverpod
  • Dependency Injection
  • ViewModel Pattern (without BLoC/Riverpod)
  • UseCase Pattern
  • Immutable State with freezed
  • Clean Architecture Layer Boundaries
  • Navigation (GoRouter)
  • References

What it covers

code-style

Stack — with the evidence

javascript

(0.80)

csharp

(0.60)

dotnet

(0.60)

github-actions

(0.60)

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
ThanhTrunggDEV
Language
—
License
—
Archived
no

All configs in this repo

Also in ThanhTrunggDEV/DontBeLazy

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
ThanhTrunggDEV/DontBeLazy.cursor/rules/zh-agents.mdc · 6Cursor rulesjavascriptcsharp+2no sections50/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/zh-patterns.mdc · 6Cursor rulesjavascriptcsharp+2api30/1003 days ago
ThanhTrunggDEV/DontBeLazy.agent/AGENTS.md · 6AGENTS.mdjavascriptcsharp+2buildteststylearch+477/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/AGENTS.md · 6AGENTS.mdjavascriptcsharp+2buildteststylearch+477/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-agents.mdc · 6Cursor rulesjavascriptcsharp+2agent-behaviour50/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-code-review.mdc · 6Cursor rulesjavascriptcsharp+2styletesting-strategygitsecurity+365/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-coding-style.mdc · 6Cursor rulesjavascriptcsharp+2style54/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-development-workflow.mdc · 6Cursor rulesjavascriptcsharp+2gitagent-behaviour39/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-git-workflow.mdc · 6Cursor rulesjavascriptcsharp+2lint-formatgitagent-behaviour43/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-hooks.mdc · 6Cursor rulesjavascriptcsharp+2styletypessecuritydo-not36/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-patterns.mdc · 6Cursor rulesjavascriptcsharp+2lint-formatstyleapi52/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-performance.mdc · 6Cursor rulesjavascriptcsharp+2buildperformance48/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-security.mdc · 6Cursor rulesjavascriptcsharp+2security39/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/common-testing.mdc · 6Cursor rulesjavascriptcsharp+2testtesting-strategyagent-behaviour34/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/cpp-coding-style.mdc · 6Cursor rulesjavascriptcsharp+2lint-formatstyle52/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/cpp-hooks.mdc · 6Cursor rulesjavascriptcsharp+2buildlint-formatdeployment60/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/cpp-patterns.mdc · 6Cursor rulesjavascriptcsharp+2style54/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/cpp-security.mdc · 6Cursor rulesjavascriptcsharp+2securityperformancedo-not73/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/cpp-testing.mdc · 6Cursor rulesjavascriptcsharp+2testtesting-strategy55/1003 days ago
ThanhTrunggDEV/DontBeLazy.cursor/rules/csharp-coding-style.mdc · 6Cursor rulesjavascriptcsharp+2lint-formatstyletypes66/1003 days ago
Diff against .cursor/rules/zh-agents.mdc Diff against .cursor/rules/zh-patterns.mdc Diff against .agent/AGENTS.md Diff against .cursor/AGENTS.md Diff against .cursor/rules/common-agents.mdc Diff against .cursor/rules/common-code-review.mdc Diff against .cursor/rules/common-coding-style.mdc Diff against .cursor/rules/common-development-workflow.mdc Diff against .cursor/rules/common-git-workflow.mdc Diff against .cursor/rules/common-hooks.mdc Diff against .cursor/rules/common-patterns.mdc Diff against .cursor/rules/common-performance.mdc Diff against .cursor/rules/common-security.mdc Diff against .cursor/rules/common-testing.mdc Diff against .cursor/rules/cpp-coding-style.mdc Diff against .cursor/rules/cpp-hooks.mdc Diff against .cursor/rules/cpp-patterns.mdc Diff against .cursor/rules/cpp-security.mdc Diff against .cursor/rules/cpp-testing.mdc Diff against .cursor/rules/csharp-coding-style.mdc

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126Cursor rulesgobun+5setupbuildtestlint-format+6100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45Cursor rulestypescriptpytest+15teststyletesting-strategysecurity+397/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack