Você quer um app que more no celular do usuário, não uma página que ele acessa pelo navegador. Isso costuma soar como projeto de mês, não de fim de semana. Já resolvi "produto instalável no celular" duas vezes sem chegar perto dessa fama: o bandb é um PWA em Next.js e Supabase, o Livro de Receitas é um PWA em Astro e Redis — e o Livro de Receitas nem usa modelo de linguagem nenhum. Os dois instalam direto do navegador, sem loja de aplicativo.

PWA resolve rápido porque pula a revisão de loja inteira. Mas você não tem acesso a certas APIs nativas nem presença nas lojas de aplicativo. Este tutorial ensina a outra rota — construir com Expo, guardar dado local com SQLite e plugar uma chamada de API de IA — para quando isso importar mais do que a velocidade de publicar. O projeto de exemplo é novo, sem relação de código com o Livro de Receitas: um app que sugere receita a partir dos ingredientes que você já tem em casa, com histórico salvo no próprio aparelho.

O que você precisa

  • Node.js na versão mínima exigida pelo Expo SDK 57: 22.13.x
  • Conta gratuita num provedor de LLM com API (Anthropic ou OpenAI, por exemplo) e uma chave de API
  • O app Expo Go instalado no celular (Android ou iOS), para testar sem emulador
  • Um editor de código
  • Custo: Expo e as bibliotecas deste tutorial são gratuitas; o único custo por execução é o consumo da API de LLM

Passo 1: Criar o projeto Expo

Rode o comando abaixo numa pasta vazia:

npx create-expo-app@latest

Ele monta um projeto já no Expo SDK 57.0.0, que empacota React Native 0.86 e React 19.2.3. Em seguida, suba o servidor de desenvolvimento:

npx expo start

Um QR code aparece no terminal. Escaneie com o Expo Go no celular e o app carrega ali mesmo — sem instalar mais nada além do próprio Expo Go. Sem celular à mão, aperte a no terminal para abrir num emulador Android, ou i para um simulador iOS (esse exige Xcode no Mac).

Passo 2: Guardar dado local com expo-sqlite

Instale a biblioteca pelo instalador do próprio Expo, que resolve a versão compatível com o SDK do projeto:

npx expo install expo-sqlite

Abra o banco com SQLite.openDatabaseAsync(...). Para criar tabela e inserir registro use execAsync; para ler um registro, getFirstAsync. O padrão recomendado para um app React é envolver a árvore de componentes com SQLiteProvider e usar o hook useSQLiteContext() em qualquer tela, sem passar a conexão do banco na mão de componente em componente.

Neste app, o SQLite guarda o histórico de ingredientes digitados e as sugestões já recebidas. Resultado prático: a tela de histórico funciona mesmo sem internet, porque não depende de uma nova chamada de API para mostrar o que já foi sugerido antes.

Passo 3: Montar a tela — lista de ingredientes

Esse passo ainda não tem nada de IA. É React Native comum: um campo de texto para adicionar ingrediente, uma lista dos ingredientes já adicionados e um botão "sugerir receita". View, TextInput, FlatList e Pressable bastam.

Mantenha o estado da lista de ingredientes num componente só, por enquanto. O botão "sugerir receita" é o gatilho do próximo passo — ele pega a lista atual e passa adiante.

Passo 4: Chamar a API de IA para sugerir a receita

No clique do botão, monte um prompt com a lista de ingredientes e chame a API do provedor escolhido — um fetch para o endpoint de mensagens ou completions.

Aqui mora o ponto crítico do tutorial inteiro. Um app Expo compilado é um pacote JavaScript rodando no celular do usuário. Qualquer chave de API embutida direto no código pode ser extraída desse pacote por quem souber procurar. A chamada para a API de IA não pode carregar a chave dentro do app — a chave fica num backend simples, uma função serverless por exemplo, e é esse backend que fala com o provedor de IA. O app chama o seu backend; o seu backend chama a IA.

Mostre a resposta na tela e salve no SQLite do Passo 2, para a sugestão aparecer no histórico offline depois.

O que pode dar errado

  • Chave de API dentro do código do app: extraível do pacote por qualquer pessoa. Mova a chamada para um backend que guarda a chave — nunca embuta no app.
  • Testar só no Expo Go achando que já está pronto: o Expo Go tem limitações de módulo nativo, e recursos mais avançados exigem EAS Build — fora do escopo deste tutorial.
  • Esquecer que SQLite local não sincroniza entre aparelhos: é armazenamento por dispositivo, não um banco compartilhado.
  • Confundir "funciona no meu Android" com "funciona em todo Android e iOS": teste nos dois sistemas quando o público final usa os dois.

Próximos passos

EAS Build gera um instalável de verdade e, dali, dá para seguir até a loja — passo natural depois deste tutorial, não coberto aqui. Notificação push nativa entra com expo-notifications, o mesmo recurso que o bandb já entrega como PWA, agora nativo. E um cache mais robusto de resposta de IA repetida vale inspiração no padrão de cache do Livro de Receitas — lá é cache de conteúdo estático em Redis; aqui seria cache de resposta de IA, um problema parecido de forma, diferente de conteúdo.

A escolha entre PWA e Expo nunca foi "qual é melhor". É se o app precisa de loja e de API nativa, ou só precisa estar na tela inicial do usuário o mais rápido possível.