Fast programming and time-to-market
Flutter has server tools that speed up processes that skip time-consuming steps and allow faster code development, such as a hot reload feature, quick experimentation, and UI building.
As a Software Development Company, we focus on choosing the right technology for every project. Our mission is to achieve first-class products with modern and high-quality technology.
We have worked with several technologies before we worked with Flutter, but since we met it has definitely changed the way we develop apps. It was a before-and-after moment in our developers' lives.
Flutter is our solution for productive, high-quality, and modern app development. It saves us the trouble of having multiple codes for different platforms and different working teams. This means Flutter improves efficiency while reducing costs and still achieves outstanding apps with native performance.
Flutter
Serverless
Firebase
Node.js
Docker
SQLite
Github actions
Firebase App Distribution
Testflight
Amazon Web services
Google Cloud
Flutter is a software development kit created by Google for building beautiful, natively compiled, and high-performance applications for mobile, web, and desktop from a single code base.
Flutter has server tools that speed up processes that skip time-consuming steps and allow faster code development, such as a hot reload feature, quick experimentation, and UI building.
The Quality Assurance process is faster because developers write automated tests only once since it's the same codebase for multiple platforms.
Flutter's performance is indistinguishable from a native app. Contrary to most cross-platform frameworks , Flutter not only has a native look but it also provides a native performance.
The google technology offers several benefits of the development of software products, some of them are:
A single codebase. One working team. Multiple Platforms. The use of Flutter saves time, effort, and costs while still achieving high-quality results.
Flutter offers a wide variety of ready-made widgets that solve the most common problems when developing user interfaces. Flutter supports accessible widgets and allows customization.
The UI is more flexible and versatile since it provides the possibility of customizing anything you see on screen. With Flutter it's simple and adjustable of the complexity of the components.
We focus on creating scalable, maintainable and testable architecture.
We design every software solution before implementing them.
We do unit testing , integration testing and smoke testing with Flutter.
We apply good practice around clean code.
We apply scalable software designs like for the Main State Management used : BLoC and provider.
Reactive programming for live and efficient updates for the UI.
Error management and error logging.
We have a set of prebuilt Flutter modules to speed up development.
We use SCRUM methodology to manage and measure scalable teams.
We constantly review and improve processes from Flutter consulting to deploy and enhance apps.
Pull, request, Linter, Refractor.
Branching model depending on the project Gitflow using GitLab flow or GitHub Flow.
CI/CD testing: Testing, Fastlane, Github actions, Codemagic, Firebase App Distribution , Test Flight.
Code review: every code written by a Developer is reviewed by at least 2 other Devs.
We use services to measure performance analytics, bugs, UX experience, and much more.
Daily SCRUM meetings in English & English Day on Thursdays to practice.
At-least 1-2hr per week dedicated to training and learning something new.
Pair programming when needed.
Constant retrospectives to analyze and understand which areas need improvement.
Documentation of the code and project to guide our work and maintain all the relevant part of the project.
As soon as Flutter web was officially released on stable with Flutter 2, we started immersing ourselves in this new possibility and creating web projects with this technology.
We are able to reuse over 95% of the code used for each project into the web platform. As a result, we practically have the web of the project without additional cost.
The software architecture we used is a combination of all the best practices we have acquired and worked with during our Flutter journey. We always focus on implementing clean architecture methodologies and continue learning and improving it.
As a result, this approach has a proven record with our success cases that allows our clients' businesses to easily scale with no sweat and without compromising quality.
We focused on defining the following structure on a high level. It is simple enough yet really powerful when scaling an app on Flutter.
The UI layer is what the users see. The layout that will be displayed based on each different state that bloc produces.
The bloc layer is in charge of handling the logic and state management.
The repository is a layer that abstracts external services of the application. In this case could be an API.
The network package is in charge of dealing with all communication with the API. Provides the necessary data the app will use.
BLoC(Business Logic Component) allows us to manage the state within the application. In this way, all the things that change within the screens can be handled from one component, rather than through the app in various locations.
It has provided the team the confidence to scale a production-ready challenging application. Its short-term bureaucracy a.k.a "boilerplate" is highly contributed to long-term efficiency. Using the BLoC pattern also enables our team to accomplish reactive programming without the complexity of managing traditional reactive libraries like rxdart.
We have studied and experimented with different solutions such as an inherited widget, provider, GetX, Riverprod, MobX, and have decided to choose BLoC because of its efficiency with scalable projects.
We always define with clarity all the responsibilities from the beginning of the project. This way, developers can easily navigate through the project structure correctly follow the architecture.
Every library, package, component and widget has its corresponding place. By increasing the level of abstraction on how we code we can tackle the hardest problems and at the same time we are able to find patterns that make solutions simpler.
CI/CD scripts for automation
Inside lib we typically define a folder for each structure. We follow a feature-driven approach. Also we can have helper functions that we use across the app and internationalization to support languages. Finally we can have widgets folder where we keep purely UI components.
Here we define all necessary scripts related to tools that we use, so developers can easily access. For instance, testing, automation, coverage, code generation.
We define a package for each repository that is necessary. For instance, we could have an API repository that communicates with an external API, third-party services that we use across the app, like persistence, notification, or a UI repository where we have files related to string, font weights, colors, themes, and assets.
Unit & widget testing. Here we define a folder for each failure that we defined in lib folder.
integration testing
In our experience, organizing a project using a feature-driven approach achieves better results than using a layered approach. One major advantage is that developers can focus on a single feature without it affecting other features and potentially reduce merging conflicts. This happens because the feature is more isolated.
Here we put the screen of the feature with the necessary widgets. This folder is responsible to implement the screen(UI) that users are going to interact with. It can make use of several widgets and it will be a function of the state that will continuously listen for changes and re-render itself.
This is where we handle the current state of the app. The view communicates with the bloc dispatching event and listening to changes in the state. The bloc will be in charge of processing those events and recreating the state based on the old state. Typically it will communicate with a repository to exchange information.
Here you can find abstractions that define entities of the real world or entities that will help complete a feature more easily. By defining classes we can program with a higher level of abstraction.
Testing is at the core of our processes. We focus on correctly evaluating the app to assure high quality. This way we can prevent undesired bugs and provide the perfect user experience.
We carry out different kinds of testing, such as:
The beauty of Flutter also relies on the possibility of integrating everything with this technology. That's why we also perform Quality Assurance processes with Flutter in order to improve efficiency and quality testing.
We have high-standard metrics in our QA process to achieve the highest quality. One of our key metrics is code coverage: testing every line of code our developers write.
We also use other tools such as Icov to know exactly what percentage of the app has been tested. This allows us to clearly visualize in percentages what lines of code have been tested and the ones who still need another test. We normally establish the threshold percentage we want to accomplish and then define what scenarios must be prioritized based on the core interest of our client’s business.
Firebase is a great Backend as a service (Baas). that provides hosted backend services such as real-time database, cloud storage, authentication, crash reporting, machine learning, remote configuration, and hosting your static files.
We especially use it for MVP and medium-size apps because it allows us to have scalable databases and cloud functions that help the business times and needs.
Flutter + Firebase is a great combination to start a project. We use all the services it provides, each one providing a specific use for each client case. They are organized under the following categories: "Build", "Release and monitor", "Analytics", and "Engage".
Serverless is a method of providing Back-end services without the hassle of worrying about the underlying infrastructure. This way we can focus more on writing business logic code rather than maintaining the server.
We suggest using this option when you want more control over all the business logic and needs of the app. The combination of Flutter + Serverless provides more flexibility and the possibility for developers to focus on developing more features. As a result, this modern technology saves time, effort as well as cost.
Even though when using BaaS sometimes you have to deal with some restrictions, when moving to Serverless it doesn't since you can define any business logic you prefer.
In addition, developers can write server-side code and deploy it to the cloud in a quick and interactive way that increases their efficiency. As a matter of fact, clients can also save costs because they have the possibility of only paying for what they use, meaning the total number of hours a particular function runs.
Our favorite stack is a combination of Node.js (typescript) and Lambda functions, either G cloud or AWS
Using a single microservice will implement some business logic and might also expose an API so it can intercommunicate with all of the other microservices. By having this as a separate service, we won't have a big monolith and the code will be much simpler and maintainable. Each developer is able to select the best technology or programming language that fits better and we can easily re-write a microservice when we think it's becoming obsolete.
We suggest using third option in big projects when the client already knows the app counts will count with a big number of users since day 1.
We choose to use a microservice architecture for many reasons:
Even though our favorite stack is a combination of Node.js, Docker, and AWS, each scenario will be different depending on the selected software architecture . We feel very comfortable working with modern architecture like microservices yet we know rather is an architecture that fits a problem and team must be prepared and know why they are choosing the architecture
Continuous Integration is the practice of merging all of the developers' work to a shared mainline often. This gives them confidence to include new features in the current codebase, knowing it will be fully tested.
Github actions is our best option for CI since we already use GitHub for SCM. This way we can have instant feedback on each Pull Request.
In addition, Continuous Deployment allows us to ship versions of the app more often. In order to not carry out repetitive tasks and risk skipping a step, we set up a CI/CD from day one so we can automate these tasks.
Codemagic is a great option of CD since it focuses on mobile app and has great support for Flutter. It allows us to continuously deliver the latest version of the applications to our clients
We also integrate other tools into our workflows such as Slack, Firebase App Distribution, Fastlane, TestFlight, Google Play Console, and App Store Connect. Through automating all this work, we can get notifications, send emails with new builds, update jira columns, and focus on continually developing features