- Vercel, una empresa enfocada en la web, experimentó con múltiples stacks tecnológicos y patrones de UI con el objetivo de lograr una experiencia nativa al nivel de un Apple Design Award, y finalmente la completó con la combinación de React Native + Expo
- La clave fue una experiencia de creación basada en chat con IA donde escribes ideas como si fueran notas y se construyen en segundo plano; diseñaron con detalle la animación de mensajes, el scroll, el teclado y un compositor Liquid Glass para lograr interacciones de chat a nivel nativo en iOS
- En la implementación del chat, usaron una combinación de contextos y hooks basada en LegendList, Reanimated y react-native-keyboard-controller, además de cálculos de
blankSize y contentInset, y sincronización con la altura del composer para manejar con fluidez la altura dinámica y los cambios del teclado
- La estructura del código se caracteriza por compartir entre web y nativo los tipos, la lógica de negocio y la capa de API, y por diseñar un flujo de esquema OpenAPI basado en Zod → Hey API → Tanstack Query para que tanto la web de v0 como los clientes de v0 Platform API usen los mismos endpoints
Resumen y objetivos de la app v0 para iOS
- Vercel lanzó v0 for iOS, su primera app móvil, y aunque es una empresa centrada en la web, se propuso crear una experiencia nativa de alta calidad con el nivel de un Apple Design Award
- Hasta antes del lanzamiento de la app para iOS, se había enfocado en la web, por lo que desarrollar una app completamente nativa era un terreno nuevo
- Para lograrlo, antes de la beta pública probaron decenas de versiones aplicando distintos stacks tecnológicos y patrones de UI
- Como referencia, se inspiraron en apps como Apple Notes e iMessage, que aprovechan muy bien el lenguaje del iPhone, y exigieron un nivel de acabado capaz de ganarse un lugar entre las demás apps de la pantalla de inicio
- Explican que no se ataron a un framework específico, sino que implementaron y compararon varios stacks en la práctica antes de llegar a una conclusión
- Después de múltiples experimentos, finalmente eligieron React Native + Expo y, como recibieron muchos comentarios de desarrolladores diciendo que se siente como una app nativa, decidieron compartir en detalle su arquitectura técnica
Dirección de la experiencia de chat en v0
- v0 para iOS apunta a ser una herramienta para convertir en algo ejecutable de inmediato las ideas que surgen cuando estás lejos de la computadora, con la ambición de convertirse en la siguiente generación de la app de notas
- En lugar de trasladar un IDE móvil o toda la funcionalidad de la web, priorizaron una experiencia simple y agradable para crear algo con IA mientras te desplazas
- El centro de esta experiencia es la interfaz de chat, para la cual definieron requisitos como los siguientes
- Los mensajes nuevos deben aparecer con una animación suave
- Los nuevos mensajes del usuario deben desplazarse hasta la parte superior de la pantalla
- Los mensajes del asistente deben mostrarse en streaming con un fade in escalonado (streaming + retraso)
- La caja de entrada (composer) debe flotar con estilo Liquid Glass sobre contenido desplazable
- Al abrir un chat existente, debe iniciar desplazado hasta el último mensaje
- El comportamiento del teclado debe sentirse natural y cercano a lo nativo
- La entrada de texto debe soportar pegado de imágenes y archivos y focus/blur mediante gestos de arrastre
- El renderizado de Markdown debe ser rápido y también soportar componentes dinámicos
- Aunque existen muchos patrones de UI de chat con IA en móvil, no había un patrón móvil claro para generación de código con IA, así que tuvieron que diseñar uno nuevo por su cuenta, lo que requirió bastante trabajo, pruebas y ajustes para cumplir sus criterios
Diseño de una arquitectura de chat componible
- Para satisfacer los requisitos del chat, diseñaron el código de chat de forma componible (composable) por funcionalidad
- Para ello, crearon varios Context Provider que envuelven todo el chat y ubicaron la lista de mensajes dentro de esa estructura
- En la implementación del chat usaron las siguientes librerías open source
- LegendList: renderizado de listas de alto rendimiento
- React Native Reanimated: animaciones y shared values
- react-native-keyboard-controller: control del estado del teclado y manejo de eventos
- El renderizado de cada mensaje se bifurca según
item.role en user / assistant / optimistic-placeholder, usando componentes distintos para cada rol
Implementación de animaciones de mensajes
- El primer mensaje del usuario hace un fade in suave usando shared values de Reanimated
- El hook
useFirstMessageAnimation calcula la altura del mensaje, la altura de la pantalla y la altura del teclado para controlar translateY y opacity
- El primer mensaje del asistente aparece con un fade in retrasado después de que termina la animación del mensaje del usuario
- En chats existentes, colocan de forma natural los nuevos mensajes en la parte superior de la pantalla mediante
scrollToEnd() y ajustes de contentInset
Control de scroll y teclado
- La calidad de la experiencia de chat depende en gran medida de que el comportamiento del teclado se sienta natural, y en React Native fue bastante difícil lograr una sensación cercana a lo nativo
- Debido a diferencias entre versiones de iOS, surgieron problemas de inestabilidad en el comportamiento del teclado, y trabajaron con el mantenedor de
react-native-keyboard-controller para corregir bugs y mejorar el rendimiento
- Con el hook
useKeyboardAwareMessageList controlan con detalle los eventos de apertura, cierre y arrastre del teclado
- Al abrir chats existentes, resolvieron problemas de altura dinámica ajustando la posición de autoscroll mediante múltiples llamadas a
scrollToEnd
Composer flotante Liquid Glass y mejoras en la caja de entrada
- Aplicaron el efecto Liquid Glass de iMessage para crear una caja de entrada translúcida y flotante
- Ajustan en tiempo real el
contentInset del scroll view usando KeyboardStickyView y el shared value composerHeight
- Para mantener el autoscroll cuando cambia la altura de la caja de entrada, usan el hook
useScrollWhenComposerSizeUpdates
- Para resolver problemas de rebote de scroll y visibilidad de indicadores del
TextInput por defecto, aplicaron un parche nativo a RCTUITextView
- También lo mejoraron para permitir enfocar el teclado con un gesto de swipe
Pegado de imágenes y fade in del contenido en streaming
- Mediante un módulo de Expo, detectan eventos de
UIPasteboard y soportan pegado de texto, imágenes y archivos
- Usan el componente FadeInStaggeredIfStreaming para implementar un fade in palabra por palabra del texto de respuesta de IA
- Con la gestión de un pool de animaciones, limitan la cantidad de animaciones simultáneas y optimizan el rendimiento
- El contenido ya visto evita reanimarse mediante
DisableFadeProvider
Compartir código entre web y nativo, y Platform API
- Comparten entre web y móvil los tipos y funciones helper, mientras que separan la UI y el manejo de estado
- Construyeron un framework de API type-safe basado en Zod que genera automáticamente la especificación OpenAPI
- La app móvil realiza llamadas de API con Hey API + Tanstack Query
- Sobre esta estructura, publicaron la v0 Platform API, ofreciendo los mismos endpoints a desarrolladores externos
Estilos y componentes nativos
- Usan react-native-unistyles para gestionar temas y permitir estilos rápidos sin acceso a Context
- Implementaron menús basados en
UIMenu nativo de iOS mediante Zeego
- Corrigieron un error de posición de Alert que aparecía en iOS 26 y contribuyeron el parche upstream a React Native
- También corrigieron problemas de arrastre y flickering relacionados con modales (
formSheet), trabajando con Callstack, Meta y Expo para integrarlo en React Native 0.82
Próximos planes y colaboración con la comunidad
- Después de completar su primera app con la combinación React Native + Expo, planean mantener el mismo stack en proyectos futuros. Están satisfechos con el stack actual
- Vercel afirmó que está enfocada en crear productos ambiciosos con un alto nivel de ejecución, y
- planea publicar como open source el know-how interno que construyó para que desarrolladores web y nativos puedan crear productos al mismo nivel
- en particular, está reclutando comunidad para beta testing de librerías open source para apps de chat con IA, y seguirá contribuyendo a mejorar React Native
Aún no hay comentarios.