Next steps: Firebase, web and desktop targets
Add Firebase services with FlutterFire, understand the compromises of Flutter web and desktop, and structure a codebase that grows past one screen.
Firebase with FlutterFire
dart pub global activate flutterfire_cli
flutterfire configure --project=my-app # writes firebase_options.dart
flutter pub add firebase_core firebase_auth cloud_firestoreFuture<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const App());
}
Future<List<Article>> recentArticles() async {
final snap = await FirebaseFirestore.instance
.collection('articles')
.orderBy('publishedAt', descending: true)
.limit(20)
.get();
return snap.docs.map((d) => Article.fromFirestore(d)).toList();
}- Initialise Firebase before
runAppand afterWidgetsFlutterBinding.ensureInitialized(). - Firestore query shapes must match an index you have created, or the query fails at runtime rather than in review.
- Never ship admin credentials in the client; use security rules to express what a signed-in user may read and write.
- Enable offline persistence in Firestore for a mobile app — it turns a flaky network into a cached, still-usable screen.
Web and desktop reality check
| Target | Strong at | Weak at |
|---|---|---|
| Web | Marketing tools, dashboards, one shared codebase | SEO, very large scroll lists, plugins without web support |
| Windows | Internal tools, kiosks | Packaging and installers are a separate job |
| macOS | Desktop companions to an iOS app | Sandboxing and notarisation requirements |
| Linux | CI tooling and embedded displays | Few plugins, distribution fragmentation |
Check every plugin's platform support before committing to a target. A single camera or Bluetooth dependency without web support can make a web release impossible regardless of how much UI code you reuse.
Growing the codebase
lib/
main_production.dart entry point, wires dependencies
main_staging.dart
app.dart MaterialApp, router, theme
core/ errors, networking, logging
result.dart
api_client.dart
features/
tasks/
data/ repository, dto models on the wire
task_repository.dart
domain/ entities and use cases
task.dart
presentation/ widgets, controllers, routes
task_list_page.dart
shared/ reusable widgets and extensions💡
Organise by feature, not by layer. A folder called
models/ with forty files from six features forces you to open unrelated code to change one screen, while features/tasks/ keeps everything you need in one place.FAQ
Should I build for web just because Flutter supports it?
Only if the app is a tool rather than a content site. Flutter web renders to canvas, which is excellent for interactive dashboards and poor for text-heavy pages that search engines must index.
Can I share code with a Flutter web build and a mobile app?
Yes, and the domain and data layers generally move unchanged. The work is in the presentation layer, where layout assumptions and plugin availability differ per target.
Related
Navigation, routing and deep links with go_router CI/CD, flavors and store deployment
Last refreshed 2026-09-18.