- A Vercel, uma empresa focada na web, experimentou várias stacks de tecnologia e padrões de UI com a meta de alcançar uma experiência nativa no nível de um Apple Design Award, e no fim concluiu o app com a combinação React Native + Expo
- O ponto central é uma experiência de criação baseada em chat com IA em que você escreve ideias como se fossem notas e elas são produzidas em segundo plano; animações de mensagens, rolagem, teclado e até o composer com Liquid Glass foram projetados em detalhe para implementar interações de chat em nível nativo no iOS
- Na implementação do chat, usaram uma combinação de contextos e hooks com base em LegendList, Reanimated e react-native-keyboard-controller, além de cálculos de
blankSize e contentInset e vinculação à altura do composer para lidar suavemente com altura dinâmica e mudanças do teclado
- A estrutura do código compartilha entre web e nativo os tipos, a lógica de negócio e a camada de API, com um fluxo baseado em Zod de schema OpenAPI → Hey API → Tanstack Query, desenhado para que o v0 web e os clientes da v0 Platform API usem os mesmos endpoints
Visão geral e objetivos do app v0 para iOS
- A Vercel lançou o v0 for iOS, seu primeiro app mobile, e mesmo sendo uma empresa centrada na web definiu como objetivo criar uma experiência nativa de alta qualidade mirando o nível de um Apple Design Award
- Como até o lançamento do app para iOS o foco havia sido a web, o desenvolvimento de um app totalmente nativo era um território novo
- Para isso, antes do beta público, a equipe experimentou dezenas de versões aplicando várias stacks de tecnologia e padrões de UI diferentes
- Como referência, buscaram inspiração em apps como Apple Notes e iMessage, que falam bem a linguagem do iPhone, exigindo um nível de acabamento capaz de ocupar espaço ao lado dos demais apps da tela inicial
- Eles explicam que não ficaram presos a um framework específico, e que chegaram à conclusão só depois de implementar e comparar várias stacks na prática
- Depois de vários experimentos, a escolha final foi React Native + Expo e, como o feedback de desenvolvedores foi de que o resultado parece um app nativo, isso motivou a publicação dos detalhes da arquitetura técnica
A direção da experiência de chat do v0
- O v0 iOS foi pensado como uma ferramenta para transformar em algo executável as ideias que surgem quando você está longe do computador, buscando se posicionar como a próxima geração do app de notas
- Em vez de levar para o celular uma IDE móvel igual à web ou copiar todos os recursos, a prioridade foi uma experiência simples e prazerosa de criar algo com IA em movimento
- O centro dessa experiência é a interface de chat, para a qual foram definidos os seguintes requisitos
- Novas mensagens devem surgir com animações suaves
- Novas mensagens do usuário devem rolar até o topo da tela
- Mensagens do assistente devem ser exibidas em streaming com fade-in em cascata (streaming + atraso)
- O campo de entrada (composer) deve flutuar em estilo Liquid Glass, acima de um conteúdo rolável
- Ao abrir um chat existente, ele deve começar já posicionado na última mensagem
- O comportamento do teclado deve parecer natural e próximo do nativo
- A entrada de texto deve suportar colar imagens e arquivos e foco/desfoque com gesto de pan
- A renderização de Markdown deve ser rápida e também suportar componentes dinâmicos
- Existem muitos padrões de UI para chat com IA no mobile, mas como não havia um padrão mobile para geração de código com IA, foi preciso desenhar um novo padrão do zero, o que exigiu bastante trabalho, testes e ajustes para atingir o nível desejado
Projeto de uma arquitetura de chat componível
- Para atender aos requisitos do chat, o código foi projetado de forma componível, permitindo combinar funcionalidades por partes
- Para isso, foram criados vários Context Providers envolvendo todo o chat, com a lista de mensagens colocada dentro dessa estrutura
- Na implementação do chat, foram usadas as seguintes bibliotecas open source
- LegendList: renderização de listas de alto desempenho
- React Native Reanimated: animações e shared values
- react-native-keyboard-controller: controle de estado do teclado e tratamento de eventos
- A renderização de cada mensagem se ramifica conforme
item.role em user / assistant / optimistic-placeholder, usando componentes diferentes para cada papel
Implementação das animações de mensagem
- A primeira mensagem do usuário faz um fade-in suave usando shared values do Reanimated
- O hook
useFirstMessageAnimation calcula a altura da mensagem, a altura da tela e a altura do teclado para controlar translateY e opacity
- A primeira mensagem do assistente faz um fade-in com atraso depois que a animação da mensagem do usuário termina
- Em chats existentes,
scrollToEnd() e ajustes de contentInset posicionam naturalmente a nova mensagem no topo da tela
Controle de rolagem e teclado
- A qualidade da experiência de chat depende muito de um comportamento natural do teclado, e criar no React Native uma sensação próxima da nativa foi uma tarefa bastante difícil
- Por diferenças entre versões do iOS, surgiram problemas de instabilidade no comportamento do teclado,
e a equipe colaborou com o mantenedor do react-native-keyboard-controller para corrigir bugs e melhorar o desempenho
- O hook
useKeyboardAwareMessageList controla com precisão os eventos de abrir, fechar e arrastar do teclado
- Ao abrir chats existentes, para ajustar automaticamente a posição de rolagem,
scrollToEnd é chamado várias vezes, resolvendo problemas de altura dinâmica
Floating Composer com Liquid Glass e melhorias no campo de entrada
- Aplicando o efeito Liquid Glass do iMessage, foi implementado um campo de entrada semitransparente e flutuante
KeyboardStickyView e o shared value composerHeight ajustam em tempo real o contentInset da scrollview
- Para manter a rolagem automática quando a altura do campo de entrada muda, foi usado o hook
useScrollWhenComposerSizeUpdates
- Para resolver problemas de bounce de rolagem e exibição de indicadores do
TextInput padrão, foi aplicado um patch nativo no RCTUITextView
- Também houve melhorias para permitir foco no teclado por gesto de swipe
Colagem de imagens e fade-in de conteúdo em streaming
- Por meio de um módulo Expo, eventos do
UIPasteboard são detectados para oferecer suporte a colagem de texto, imagens e arquivos
- O componente FadeInStaggeredIfStreaming implementa fade-in palavra por palavra no texto da resposta da IA
- O gerenciamento de um pool de animações permite limitar a quantidade de animações simultâneas e otimizar o desempenho
- Conteúdos já vistos não são animados de novo graças ao
DisableFadeProvider
Compartilhamento de código entre web e nativo e a Platform API
- Entre web e mobile, são compartilhados tipos e funções helper, enquanto UI e gerenciamento de estado ficam separados
- Foi construída uma estrutura de API type-safe baseada em Zod, que gera automaticamente a especificação OpenAPI
- O app mobile faz chamadas de API com Hey API + Tanstack Query
- Com base nessa estrutura, a v0 Platform API foi lançada, oferecendo os mesmos endpoints a desenvolvedores externos
Estilização e componentes nativos
- react-native-unistyles é usado para gerenciamento de tema, permitindo estilização rápida sem acesso via Context
- Com Zeego, foram implementados menus baseados no
UIMenu nativo do iOS
- Foi corrigido um erro de posicionamento de Alert no iOS 26 e enviado um patch upstream para o React Native
- Também foram corrigidos problemas de arrasto e flickering relacionados a modais (
formSheet), com colaboração de Callstack, Meta e Expo para inclusão no React Native 0.82
Próximos planos e colaboração com a comunidade
- Depois de concluir o primeiro app com a combinação React Native + Expo, a empresa pretende manter a mesma stack nos próximos projetos. Eles estão satisfeitos com a stack atual
- A Vercel afirma estar focada em construir produtos ambiciosos com alto nível de qualidade, e
- planeja abrir como open source o know-how desenvolvido internamente para que desenvolvedores web e nativos possam criar produtos no mesmo nível
- em especial, está recrutando a comunidade para beta testar bibliotecas open source para apps de chat com IA e seguirá contribuindo para melhorias no React Native
Ainda não há comentários.