What you'll learn
Quick Answer
Flutter uses Dart and renders every pixel with its own engine rather than platform widgets. That gives identical appearance across platforms and full design control, at the cost of not matching native conventions automatically.
It draws its own widgets
This is the defining decision and it explains everything else.
React Native maps its components onto real platform controls — a React Native button becomes an actual Android button. Flutter does not. It ships a rendering engine and paints every pixel itself, the way a game engine would.
Consequences in Flutter's favour: the app looks pixel-identical on both platforms, you are never blocked by a missing bridge to a platform control, animations are smooth because the whole frame is under one renderer, and there is no JavaScript bridge to serialise across.
Consequences against: your app does not automatically inherit platform conventions, so an iOS user may notice it does not feel quite like an iOS app. Flutter ships both Material and Cupertino widget sets to mitigate this, and you have to choose to use them. App size is also larger, since the engine ships with your app.
Dart, briefly
Dart is unremarkable if you know Java or JavaScript, which is deliberate.
class Student {
final String name;
int marks;
Student(this.name, {this.marks = 0});
String get grade => marks >= 90 ? 'A' : marks >= 75 ? 'B' : 'C';
@override
String toString() => '$name ($marks) -> $grade';
}
Asha (91) -> A
Ravi (68) -> C
Named parameters with defaults, string interpolation with $, and expression-bodied members with =>.
Null safety works as in Kotlin:
String? maybe;
print(maybe?.length); // null
print(maybe ?? 'none'); // none
And async is familiar:
Future<String> fetchName() async {
await Future.delayed(Duration(milliseconds: 50));
return 'Asha';
}
Dart is a small language to learn — most of the effort in Flutter is the widget model, not the syntax.
Everything is a widget
Not only visible controls. Padding is a widget. Centering is a widget. Alignment, gestures and even the app itself are widgets. The UI is a tree of them.
class Counter extends StatefulWidget {
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => setState(() => count++),
child: const Text('Increment'),
),
],
);
}
}
setState is the key call — it tells Flutter the state changed so it rebuilds. Modifying count without it changes the value and nothing on screen, which is the most common beginner bug.
StatelessWidget for anything that only displays what it is given; StatefulWidget when it holds changing state. Prefer stateless where possible.
Composition rather than properties is the style: instead of a padding attribute, you wrap in a Padding widget. That produces deep nesting, which is Flutter's main readability complaint. Extracting widgets into named classes is the fix, and it also improves rebuild performance.
Practical notes
- Hot reload is excellent and genuinely changes the development loop — UI changes appear in under a second with state preserved. It is the feature people cite most.
constmatters. Marking widgetsconstlets Flutter skip rebuilding them. It is free performance and the linter will point out where.- State management beyond setState — Provider or Riverpod for shared state. Do not reach for one on day one; feel the problem first, as with frontend state management.
- You still need platform knowledge for permissions, notifications, deep links and store submission. Cross-platform reduces the work; it does not eliminate the platforms.
- iOS builds require a Mac. This is Apple's restriction, not Flutter's, and it is a real constraint for Indian students — you can develop and test on Android throughout and only need macOS to build and submit for iOS.
Is it worth learning?
Good reasons: you want both platforms from one codebase, you are building for a startup or client where cost matters, or you want a strong portfolio project — a published app is unusually convincing evidence of ability.
Reasons to pause: if you specifically want an Android engineering role, native Kotlin is what is being hired for. If your app depends heavily on the newest platform features, native reaches them first.
For an Indian student, Flutter is a strong practical choice for freelance and startup work — one codebase for two stores is a genuine commercial argument, and the client does not care which framework produced it. See freelancing for students.
Dart is worth about a week. The widget tree, state and lifecycle take longer, and that is where the actual learning is.
