Flutter itself is slowly reaching maturity on mobile and is already quite good, if you can live with a few compromises.
Flutter itself is slowly reaching maturity on mobile and is already quite good, if you can live with a few compromises.
For the record, Swift suffers from this problem as well. Kotlin only avoids it because of Java interop, although even this becomes complicated because of Google’s half-assed implementation of Java on Android.
I think this is one of the biggest reasons to reach for JavaScript instead. It has a lot of flaws, but it has a huge ecosystem that works nearly everywhere.
Compiles to Wasm and can work with other compile to wasm languages.
Has quite good support for C, C++, JS, Swift, Java and Rust interop where they have tools that will write all of the glue code for you.
Also has decent gRPC support meaning you can use any other language that also fits that category.
It’s a small Dart ecosystem but it’s fundamentals are great and it’s extension points are much better than you will likely find elsewhere.
JSX is conceptually the same but somehow seems easier to read. Maybe it's the close tags?
Its Flutter:
``` class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { var appState = context.watch<MyAppState>(); var pair = appState.current;
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BigCard(pair: pair),
SizedBox(height: 10),
ElevatedButton(
onPressed: () => appState.getNext(),
child: Text('Next'),
),
],
),
),
);
}
}
```versus SwiftUI:
``` struct MyHomePage: View { @StateObject private var appState = MyAppState()
var body: some View {
VStack {
BigCard(pair: appState.current)
.padding(.bottom, 10)
Button("Next") {
appState.getNext()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
}
}
```versus React Native:
``` const MyHomePage = () => { const [pair, setPair] = useState(/* initial pair /);
const getNext = () => {
// Logic to get the next pair
// You'll need to implement this function
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
{/* Replace BigCard with appropriate React Native components */}
<BigCard pair={pair} />
<View style={{ marginVertical: 10 }}>
<Button title="Next" onPress={getNext} />
</View>
</View>
);
};
```That said, SwiftUI is clearly the supreme leader in this declarative approach.
The Flutter looks the best to me, out of those, hands down.
1) SwiftUI feel more like jquery so that you can chain styles like padding, color, font etc. Because of that :
- code completion just works and is fast you just press a '.' and see all choices
- it's easy refactor the code if you wan't to change styling or layout
2) Flutter abusing too much composition and adapter pattern to the point they using refactoring in VSCode to add simple padding etc. Just have look at this official GIF from 'Test Drive' - how many times 'down arrow' got pressed:
https://codelabs.developers.google.com/static/codelabs/flutt...
Now imagine designer come to you and telling you we change layout and styling slightly - in flutter I feel it's easier to throw away such layout code and start from scratch than trying to refactor it. In swift UI you just change VStack to HStack, change maybe some parameters and move around chain of .padding().color() around and are done with it.
What would improve flutter readability is extending Dart to have something like Swift:
- first parameter can be marked as optional specifing parameters name such as '_ child:'
- escaping parameters in Swift so you instead of doing ... children: []) you can just close previous Widget and make also 'children' parameter name optional so that you can write :
Row(.min) { ElevatedButton( onPressed:() { appState.getNext(); } ) { Text('Next') } }
- similar enum behavior like in Swift when you can just type '.red' instead of 'Color.red' - this is even more useful for more nested enums.
edit: I gave up with proper formatting of code here in HN, super annoying.
Is this supposed to be a bad thing? :(
Code generation (and modification) tools are there to help you. You can choose to walk everywhere but once the car becomes ubiquitous, why walk?
* The support for tagged unions (Rust style enums) is pretty nonexistent.
* `int` is 64-bit but not on the web. I totally get why they did that and hopefully they can fix it with wasm at some point but it's very annoying for interop with languages that have the full range of int types.
* As many many people have said, it's quite verbose to make dataclass style types.
But it still deserves to be way more popular than it is. It's basically what JavaScript would be if it was designed by someone with taste.
It's not a bad language. It just lacks some needed features. They'll probably get implemented over a span of a few years.
Ecosystem is small, but at least there's FFI interop.
It also has some baggage from it's early days when it was meant as JavaScript replacement. Since we now have WASM (and soon WASM-GC) I think it would be best, if compilation to JS would be dropped, so more low level features can be implemented.
FFI continues to be a disaster (to be fair, this is not unique to Dart/Flutter).
The biggest problem with any cross-platform system on mobile is always getting performance out of the native interop. It's often easier to ship a computation to a server on the web and ship teh result back rather than execute it natively on another thread on the bloody phone. It's infuriating. We have a zillion cores, and every single phone OS tries it's damnedest to prevent you from using them because, heaven forbid, you might actually use up some of the battery. The Horror! The Horror!
The cross-platform systems for phones are really good at doing puzzle games or CRUD. Step outside of that and you enter "Here Be Dragons" territory very quickly.
I agree. The team behind the language is the real problem.
> It just lacks some needed features. They'll probably get implemented over a span of a few years.
For years they have dismissed calls to add multi-threading in the language, despite it being sorely needed for anything computationally non-trivial (isolates have ridiculous overhead).
When Flutter came around, for whatever reason they decided to pick Dart, the original prototype was in JavaScript (the official reason being it wasn't good enough given the language semantics), and Dart 2.0 effort started, with the language gaining strong typing (it was dynamic with optional typing in Dart 1.0), and AOT compilation support.