
Build 10x products in minutes by chatting with AI - beyond just a prototype.
Sometimes, as developers and tech enthusiasts, we wonder why certain tools or languages are chosen for developing a particular app. One such question that has aroused our interest is why the Google Team, mainly known for Android, decided to use Flutter to develop the YouTube Create app, as tweeted on Flutter’s official handle . This blog post will walk you through this interesting puzzle, exploring some of Flutter’s features that Google[might have used to create] the YouTube Create app, which is not a “pure Flutter app”, highlighting the potential benefits Flutter brings to the table.
Selecting a framework to build an application is like selecting the right type of fuel for a car race. The speed, power, and overall performance of the car depend heavily on the fuel it uses.
In this case, we're looking at why Google chose Flutter, for its YouTube Create app. The reason behind this can be Flutter's core principles – beautiful UIs, native performance, and the ability to communicate with native platform-specific code via the use of platform channels. Flutter's native compilation to ARM and x64 machine code promises high performance for both CPU and GPU tasks essential for a video editing application. This capability directly supports intensive tasks such as applying filters or transitions, rendering previews, and exporting the final edited video. These principles simplify the complexity that usually underlies cross-platform development for any wonderful app.
Flutter framework relies on Dart, a programming language praised for its simplicity and powerful functionality. Together, they're changing the game in the world of cross-platform application design. The potential of this combination can also possibly be harnessed to create an optimal user interface experience for the YouTube Create app.
Looking from an overall perspective it seems Flutter can efficiently manage this kind of app with a relevant structure. Architecture plays a big role in any application development. It aims to keep different parts of the code separate, thus making it easier to manage, scale, and update.
Building a video editing app like YouTube Create in Flutter requires careful consideration of state management, some of the approaches that could fit well here:

The Provider + ChangeNotifier approach is relatively simple and easy to understand. It's officially recommended by the Flutter team.
With this approach, you write your business logic in classes that extend , and expose those classes to your widget tree using . You can notify listeners from when there's a change in the state so widgets can rebuild themselves accordingly.
Let's delve deeper into the usage of and in the context of a video editing application, say a feature from the YouTube Create app that allows users to trim a video.
Firstly, imagine we have a model:
Next, we would create a that's going to handle the state of the :
Here, is managing the state of a . Whenever the user trims the video, is called, which modifies the and fields of the object and then calls to inform the widgets that are consuming this that they should rebuild.
Now let's see how to provide the to the widget tree and use it. Use the to create the state and provide it:
In the widget, we will use to listen to changes in :
In the , we display the 's current start and end times, and when the "Trim video" functionality is used, we call , which changes the 's state and triggers a re-build of since it's listening to . Thus the displayed start and end times update.
This pattern is particularly suitable for an app where states are likely to change often such as a video editing app. It allows for a clear separation of UI and business logic, resulting in code that's easier to test and maintain.

More powerful and flexible state management, Riverpod. Riverpod has been regarded as the improved version of Provider, as it addresses many weaknesses in Provider (like its tight coupling with the widget tree).
One of the strengths of Riverpod is its flexibility. It allows you to have conditional providers (Providers that return different values based on other providers), and have more control over the lifecycle of your providers.
Riverpod also comes with built-in support for asynchronous programming (through , , and ), which could be very useful in a video editing app where we usually have many asynchronous operations.
Both of these state management solutions have their strengths and are widely used in the Flutter community.
Applying the clean architecture in Flutter and using its powerful state management could be a reason why the YouTube Create App boasts smooth operations like project creation, editing, and deletion.
Local data persistence is crucial in video editing apps for several reasons like avoiding data loss, saving user preferences and configurations, and caching. User experience must remain intact while they are editing, trimming, or finalizing their videos at that last moment. For such a secure data-saving feature Flutter can be the saviour.
Flutter aids in local data persistence through several libraries, and they can work harmoniously with any state management pattern and can help in the development of a video editing app:
Through these libraries, Flutter gives you tremendous power and flexibility to manage local data persistence in a video editing app, ensuring a seamless user experience. Application state, user preferences, and complex project metadata could comfortably be managed and stored across different sessions of the app.
Certainly, Flutter is designed in a way that makes it a fantastic choice for building applications with rich, complex, and compelling 😍 animations and transitions.
Flutter uses the power of Skia Graphics Library and Realtime Renderer Impeller. Impeller precompiles a small and simple set of shaders at Engine build time to avoid compiling at runtime. Skia is responsible for drawing every pixel that you see on the screen. Because Skia is implemented in C/C++, it allows for faster rendering and smooth animations. Skia provides APIs for 2D graphics, including path drawing, images, text, and shaders which can be leveraged for complex animations which we can see at the start when the YouTube Create app launches on the mobile.
Flutter is declarative and reactive. When a widget’s state changes, the widget rebuilds its description, which the Flutter framework diffs against the previous description to determine the minimal changes needed in the render tree to transition from one state to the next. This ensures that Flutter keeps the UI in sync with the state.
Flutter runs at 60 frames per second (fps) or even 120 fps on devices capable of 120Hz updates. Every frame marks the creation of a set of widget trees (an element tree, a render object tree), which get diffed to calculate the update operations to be performed on the widgets. This ensures smooth and jank-free animations because the UI is always in sync with the frame rate.
Flutter's design enables the creation of complex, customized animations through the and classes. manages the animation, allowing control over its duration and state (started, stopped). It generates a new value for every frame in a defined period. defines the start and end of an animation range, and an interpolated value within that range can be obtained.
So, in the context of a video editing app, the rich animation capabilities that Flutter offers can be directly leveraged to design fluid and customized animations and transitions, leading to a more immersive and interactive user experience.
The url_launcher package in Flutter is a convenient feature that makes launching URLs (Uniform Resource Locator) straightforward, giving your mobile application a commendable level of connectivity with the web.
Here is a technical overview of how it works:
In the case of the YouTube Create video editing app, the package might be providing seamless interaction with browser-based resources, directing users to their YouTube channel pages, among other capabilities, making it a valuable asset to the overall app experience.
The share_plus package in Flutter is a versatile and essential tool, especially in a content creation app like a video editing application. It allows users to share their content, such as edited videos, across different platforms by utilizing the native platform's sharing capabilities.
Here's a brief technical overview:
In a video editing app, using the package would enhance the user experience by allowing users to share their edited videos or send them directly to different platforms. This easy export and share functionality could help increase user engagement, making the app more user-friendly and efficient.
Managing asynchronous tasks in a high-performance app like a video editing application is crucial. Flutter's RxDart and Streams are part of Dart's core library that allows for efficient task management in an asynchronous environment.
Streams are a way of handling asynchronous data sequences, such as user input events or I/O operations. They are especially useful when working with continuous or live data. For instance, in a video editing app, a stream can handle and process video frames in real time.
RxDart is a reactive functional programming library for Dart based on ReactiveX - a cross-platform library for handling asynchronous data streams. RxDart does not provide any additional Widgets, but it is meant to be used in conjunction with Flutter's existing ones.

Here's how they contribute effectively:
In the context of a video editing app to be developed in Flutter, operations such as importing clips, editing them, applying filters, and exporting the final video can be handled efficiently using RxDart and Streams. These operations could be processed as data sequences, and through the use of various operators, developers can map out complex workflows, handle errors gracefully, and improve the overall efficiency of the app.
When it comes to why Flutter was possibly chosen for the YouTube Create App, a few speculations can be made:
It’s important to note that all these are educated guesses, and the actual reasons might vary. However, these points reflect the various ways in which Flutter’s features might have been valuable in developing the YouTube Create App. It’s always exciting to see how developers utilize the capabilities of various languages and frameworks., and in this use case, Flutter can be a great fit!
ChangeNotifierProviderChangeNotifierProviderChangeNotifierVideoChangeNotifierVideoVideoEditingStateVideotrimVideo()startendVideonotifyListeners()ChangeNotifierVideoEditingStateChangeNotifierProviderVideoEditorConsumerVideoEditingStateVideoEditorVideotrimVideo()VideoConsumerVideoEditingStateFutureProviderStreamProviderStateNotifierProvidershared_preferencesAnimationControllerTweenAnimationControllerTweenhttps://mailto:tel:url_launcherurl_launcherFutureurl_launcherurl_launchershare_plusshare_plusshare_plusFutureshare_plusclass Video {
final String id;
final String url;
Duration start;
Duration end;
Video({
required this.id,
required this.url,
required this.start,
required this.end,
});
}
class VideoEditingState with ChangeNotifier {
Video _video;
VideoEditingState(this._video);
Video get video => _video;
void trimVideo(Duration start, Duration end) {
_video.start = start;
_video.end = end;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Youtube',
home: ChangeNotifierProvider(
create: (_) => VideoEditingState(Video(id: '1', url: '<url>', start: Duration.zero, end: Duration(minutes: 10))),
child: VideoEditor(),
),
);
}
}
class VideoEditor extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<VideoEditingState>(
builder: (context, videoEditingState, _) {
return Column(
children: <Widget>[
Text('Video start: ${videoEditingState.video.start}'),
Text('Video end: ${videoEditingState.video.end}'),
RaisedButton(
child: Text('Trim video'),
onPressed: () => videoEditingState.trimVideo(Duration(minutes: 0), Duration(minutes: 5)),
),
],
);
},
);
}
}
// Import the package
import 'package:share_plus/share_plus.dart';// You can use the same function to share on both Android and iOS
Share.share('check out my video https://example.com');// Share text
Share.share('Amazing video');
// Share a link
Share.share('https://example.com/video.mov');// For sharing files
Share.shareFiles(['${Directory.systemTemp.path}/video.mov'], text: 'Great Video');// Conceptual example of a single subscription stream
// that handles video frames for processing
Stream<VideoFrame> videoFrames = getVideoFramesAsStream();
videoFrames.listen((frame) {
applyFilterToFrame(frame);
});// Example of StreamController, Stream and Sink
final controller = StreamController<int>();
final StreamSink<int> input = controller.sink; // Sink
final Stream<int> output = controller.stream; // Stream// Example of BehaviorSubject (keeps the latest item and emit to new subscribers)
var subject = BehaviorSubject<int>();
subject.add(1);
subject.stream.listen((value) => print("First Subscriber: $value")); // will print 1
subject.add(2);
subject.stream.listen((value) => print("Second Subscriber: $value")); // will print 2Observable.range(1, 5)
.map((value) => value * value)
.listen(print); // prints 1, 4, 9, 16, 25