Porquê nós achamos que Flutter vai nos ajudar a escalar o desenvolvimento mobile no Nubank
Uma apresentação dos critérios e estudos que conduzimos para decidir usar Flutter como a nossa principal tecnologia no desenvolvimento multiplataforma mobile.
Por Alexandre Freire & Vinicius Andrade. tradução de Julio Henrique Bitencourt [available in English]
O Nubank sempre foi uma Fintech mobile-first. Nós começamos o desenvolvimento com aplicativos nativos para o nosso Cartão de Crédito, suportando ambas as plataformas Android e iOS lá em 2013 e rapidamente adotando Kotlin e Swift logo após serem anunciadas. Por um tempo, também suportamos a plataforma do Windows Phone.
Conforme a empresa cresceu (nós agora somos o maior banco digital independente fora da Ásia), desenvolver novos produtos além do Cartão de Crédito se tornou uma prioridade e os novos times tiveram que desvendar como eles iriam integrar com nossas aplicações.
Mas como? Bem, por que não tentar Reactive Native?
O terceiro produto do Nubank foi a NuConta, nossa conta digital.
Quando o time da NuConta foi formado em 2016, encarávamos um desafio: poucos especialistas em desenvolvimento nativo disponíveis. E também não era fácil de contratar, nós vimos (e ainda vemos) uma competição feroz no mercado por esses profissionais.
Nós queríamos desenvolvedores mobile dedicados para o time da NuConta porque nós já sabíamos que times especializados não escalam. Nós acreditamos em times autônomos, ágeis e multifuncionais, trabalhando juntos desde o Conceito até Produção, evitando passar o bastão entre especialidades e sendo responsáveis pela qualidade, operação e evolução dos produtos. Nós acreditamos que times únicos desenvolvendo features de ponta a ponta entregam mais valor, de forma mais rápida.
Escrever uma feature duas vezes, em diferentes linguagens e plataformas, e tendo que aprender todas elas, parecia desperdício. Aprender uma única plataforma híbrida para lançar novas features iria reduzir a barreira de entrada para que desenvolvedores backend pudessem contribuir pro frontend mobile.
Na época, React Native já era uma alternativa estabelecida, mantida por grandes empresas. Além disso, nossa cultura de desenvolvimento é sempre aprender e melhorar de forma contínua (nós deixamos claro que é responsabilidade de cada um aprender e experimentar durante o expediente de trabalho) — então não é difícil entender porque o time da NuConta decidiu experimentar essa tecnologia multiplataforma.
A NuConta obteve um grande sucesso, com mais de 13 MM de usuários, que pouparam aproximadamente US$ 305 Milhões nos últimos 5 anos por não pagar uma série de taxas (dados de Setembro de 2019). Todos eles usaram um app desenvolvido com React Native + GraphQL, um stack tecnológico bastante diferente do utilizado por plataformas nativas.
A história do React Native no Nubank é algo que temos bastante orgulho e merece um post próprio.
Mas hoje nós queremos falar sobre nosso próximo passo. Afinal, não importa quanto sucesso uma ferramenta ou plataforma tem, nossos engenheiros continuam aprendendo e experimentando com novas tecnologias:
Uma cultura de experimento e aprendizagem rápida.
No começo de 2019 novos times de produtos, como Conta PJ e Empréstimo Pessoal, agora tinham uma escolha entre usar nativo ou tentar React Native.
Ao mesmo tempo, a indústria já tinha mostrado um grande avanço em tecnologias mobile (apenas alguns anúncios de 2019): Kotlin como a linguagem principal para o Android, Estabilidade do ABI no Swift 5, Flutter 1.0, atualizações de Governança da comunidade de React Native.
Então começamos a discutir qual a melhor forma de apoiar a produtividade dos nossos engenheiros ao entregar features para nosso app. Aqui estão alguns dos problemas:
- Para engenheiros que são interessados em ser mais full-stack, a barreira de entrada era muito alta. Para contribuir com o Cartão de Crédito era necessário aprender Kotlin para Android, Swift para iOS e, para ajudar na NuConta, também precisava aprender React Native.
- Sem mencionar o fato de que a arquitetura de cada uma dessas opções é muito diferente! Nossa hipótese é que reduzindo a barreira de entrada para o desenvolvimento mobile, o Nubank irá ver mais engenheiros contribuindo para a base de código.
- Outro gargalo que encontramos quando dependendo de times especializados em desenvolvimento nativo para cada nova feature ou produto lançado foi o “pesadelo de alocação”, mesmo com os esforços de contratação aumentados, nunca tivemos desenvolvedores suficientes para preencher nossos times de produtos.
Rapidamente percebemos que nossos times eram mais importantes que o stack de tecnologias e ter todas essas escolhas estava causando desconforto e confusão. Já era tempo de investigar de forma séria qual tecnologia multiplataforma melhor supre as necessidades do Nubank.
Então nós decidimos criar uma força tarefa com a missão de investigar e decidir, com o apoio de todo o time de engenheiros de software, qual tecnologia deveríamos padronizar, considerando Kotlin Native, React Native e Flutter como alternativas.
O objetivo era fazer uma escolha onde, independente da especialização dos membros, os times seriam autônomos e produtivos ao desenvolver aplicações mobile e entregar valor a uma única arquitetura, linguagem de programação e conjunto de padrões.
A força tarefa
Nós montamos um pequeno time com desenvolvedores mobile experientes no Nubank. Eles determinaram 11 critérios para serem avaliados em um projeto de pesquisa e desenvolvimento. Aqui vai uma breve descrição das 5 maiores prioridades:
- Experiência dos desenvolvedores: O que possibilita um desenvolvedor a ser produtivo e entregar valor? Exemplos: hot reload; visualização de componentes; ferramentas de depuração; integração da IDE; e ferramentas de testes.
- Viabilidade a longo prazo: Descrever o nível de confiança no futuro da plataforma. O mantenedor irá continuar suportando ela à longo prazo (5 anos)? Qual a probabilidade da comunidade suportar o projeto caso o mantenedor decidir abandoná-lo?
- Não necessitar especialização na plataforma: Um engenheiro deveria ser capaz de escrever código mobile para o produto sem diferenciar entre Android e iOS. O código tem uma aparência e se comporta igual no Android e iOS, com pouca ocorrência de problemas específicos de SO?
- Custo de abstração incremental: O custo de estender a plataforma para cada tarefa do produto e a dificuldade de centralizar o trabalho em extensões, se necessário. O quão difícil é adicionar um novo componente? Nós criaríamos uma dependência em um time horizontal de plataforma?
- Risco de abstração não linear: Risco de repentinamente precisar de grandes e desproporcionais reescritas na nossa abstração interna. Nós precisaríamos fazer mudanças não triviais ao longo de toda nossa base de código para suportar um novo componente no NuDS (Nubank Design System)?
Nós então partimos para reunir evidências e concordamos em uma nota subjetiva para cada um dos critérios, usando diferentes técnicas como:
- testar uma versão do Flutter de uma das nossas features em produção
- analisar comunidades, repositórios, e recursos disponíveis para cada plataforma
- começar conversas com especialistas, times e empresas por trás do desenvolvimento de cada plataforma
- implementar um clone de uma de nossas features em um app separado, nas 3 plataformas diferentes
- conduzir um teste de usabilidade, onde engenheiros novatos e seniors fariam mudanças nos apps descritos acima
- conduzir apresentações, debates e visitas a times para discutir nossas descobertas, ouvir a opinião de engenheiros e conselheiros seniors, incorporando seu feedback e respondendo as suas questões
Os resultados dos testes de usabilidade foram os mais interessantes. Pessoas de todos os níveis e proveniência (incluindo engenheiros iniciantes, sem conhecimento prévio de mobile) participaram de um teste de uma hora. Eles tinham acesso a um app funcional, um ambiente de desenvolvimento, a documentação da plataforma híbrida e seus componentes, e algumas tarefas que iam aumentando em nível de dificuldade para desenvolver. Eles foram observados pelo nosso time enquanto executavam as tarefas e também responderam um questionário no final.
Como um exemplo, os engenheiros tinham que adicionar uma feature para que os usuários pudessem através de botões de “atalho” com valores pré-definidos, depositar dinheiro em sua NuConta.
Nós escrevemos um relatório da nossa pesquisa, agrupando os resultados e detalhando como avaliamos cada critério. Você vai encontrar um link para requisitar o relatório completo no final deste artigo. Foi bem difícil tomar uma decisão, até mesmo após coletar muita informação, tivemos que focar nos 7 critérios principais para chegar no seguinte resultado:
Levando em consideração nossa própria experiência (80% da nossa codebase de Android é Kotlin, a NuConta é desenvolvida em React Native) e validando nossas alternativas com as prioridades do Nubank, nós sentimos que Kotlin é uma ótima linguagem para se trabalhar. Mas Kotlin Native é a única plataforma que não fornece uma abstração da UI, criando uma dependência da plataforma nativa para desenvolvimento e testes. Enquanto isso teve uma pontuação maior em critérios de menor prioridade, sem mostrar limitações de capacidades ou risco de restrição na loja de apps, nós sentimos que especialmente quando se tratou dos testes de suporte para engenheiros experientes, Kotlin Native não está pronta para nós.
Nós temíamos um viés para o React Native, então conscientemente baixamos a prioridade de outro critério: o custo de construir uma abstração inicial na plataforma, onde React Native obviamente venceria.
Quando analisando critérios mais importantes, React Native também ganha com o suporte da comunidade. Não tivemos medo em relação à continuidade e evolução do projeto e ficamos felizes com a quantidade de documentação e recursos disponíveis para aprendizagem. Mas quando se trata de breaking changes, nós descobrimos que React Native possui muito mais dependências que as outras alternativas, se tornando muito mais vulnerável para manutenção e problemas surgindo de atualizações.
Nossa cultura de desenvolvimento encoraja muito automatização de testes, então Flutter brilhou com sua grande capacidade de testes, que se encaixa perfeitamente com nossa mentalidade (uma infraestrutura preparada para testes de Unidade, Integração e Ponta a Ponta sem a necessidade de renderizar em tela). Enquanto React Native necessita de dependências de terceiros, o que torna mais suscetível a breaking changes. Nós descobrimos que a experiência de desenvolvimento com Flutter é superior, com uma melhor capacidade de hot reload, uma documentação oficial muito forte, e uma API mais estável.
Após muita discussão e controvérsia até o último minuto, nós decidimos utilizar o Flutter como a tecnologia principal para desenvolvimento mobile no Nubank. Isso significa que novas features serão escritas em Flutter e conforme o produto for evoluindo, nós esperamos que Flutter se torne a maior porcentagem de código em nossa base.
Nós estamos extremamente animados em compartilhar esse estudo no mesmo dia em que anunciamos o lançamento de uma feature muito aguardada: a funcionalidade de “transferência de pontos para Smile” do programa de Rewards foi construída em Flutter.
Conclusão: qual a sensação de utilizar Flutter?
Até agora tem sido ótimo utilizar Flutter, nós esperamos ter mais features construídas ou migradas para Flutter disponíveis para nossos usuários em breve.
Ter que incluir o Flutter em um aplicativo em produção com milhares de clientes vem com uma série de desafios que vamos superando gradualmente, o primeiro deles sendo:
- mudanças na pipeline de build
- criação dos principais platform channels
- integração de rotas entre React Native, Flutter, Kotlin e Swift para podermos manter a interoperabilidade
Enquanto Flutter será nossa principal tecnologia, desenvolvedores nativos ainda são necessários e valiosos pois cada plataforma tem sua série de funcionalidades que necessitam de código nativo (e.g.: plugins nativos para GPS e câmera, Apple Watch, Android apps minimizados, etc…) e conforme o time de engenheiros de software no Nubank cresce, especializações individuais são bem vindas.
Para qualquer que esteja considerando Flutter, nós disponibilizamos o nosso relatório completo, com dados detalhados de prós e contras, para download. Nossa história apareceu num vídeo do Flutter Developer Stories.
Esteja avisado que o que funciona para o Nubank pode não funcionar para você. Nós recomendamos também procurar por experiências de outras empresas. Enquanto tem empresas usando Flutter ou React Native, o Dropbox desistiu de sua tecnologia multiplataforma (C++) por conta de “O custo (não tão) oculto de compartilhar código entre iOS e Android” e o AirBnB decidiu “Abandonar React Native”.
E a propósito: Se você está interessado em trabalhar em um ambiente de aprendizagem e experimentação contínua, e animado em desenvolver habilidades full stack e explorar tecnologias multiplataforma para desenvolvimento mobile como Flutter: estamos contratando.
Obrigado a André Moreira, Rafael Ferreira, Ana Paula Maia e Paula Rothman pela ajuda com este artigo. Obrigado a Julio Henrique pela tradução.
Quer aprender Flutter? Recomendamos a Formação Flutter na Alura.
Quer ouvir mais? Participamos de um episódio sobre Flutter no podcast do Hipsters.
Qual a estratégia de desenvolvimento mobile da sua empresa? Vocês estão utilizando tecnologias híbridas também? Por favor comente e nos conte mais sobre suas escolhas.