Preciso de app mobile. React Native ou PWA?
Resposta curta: Depende.
PWA (Progressive Web App):
- ✅ Custo 60% menor (1 codebase web)
- ✅ Deploy instantâneo (sem app store)
- ❌ Funcionalidades nativas limitadas
React Native:
- ✅ Performance próxima de nativo
- ✅ Acesso completo a features do device
- ❌ Custo 2x maior (iOS + Android)
Este artigo compara custo, performance, features e mostra quando usar cada um.
O que é PWA?
Progressive Web App = Site que funciona como app.
Características:
- Instalável na home screen
- Funciona offline (Service Worker)
- Push notifications
- Acesso a câmera, geolocalização, sensores
Tecnologias:
- HTML/CSS/JavaScript (como site normal)
- Service Workers (cache e offline)
- Web App Manifest (metadata do “app”)
Setup básico (Next.js):
npm install next-pwa
// next.config.js
const withPWA = require('next-pwa')({
dest: 'public',
register: true,
skipWaiting: true,
disable: process.env.NODE_ENV === 'development'
})
module.exports = withPWA({
// config
})
// public/manifest.json
{
"name": "Conecta Prof",
"short_name": "Conecta",
"description": "Marketplace de professores",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4F46E5",
"orientation": "portrait",
"icons": [
{
"src": "/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
// app/layout.tsx
export const metadata = {
manifest: '/manifest.json',
themeColor: '#4F46E5',
appleWebApp: {
capable: true,
statusBarStyle: 'default',
title: 'Conecta Prof'
}
}
Resultado: Usuário pode instalar o “app” direto do browser.
O que é React Native?
React Native = Framework para apps nativos com JavaScript.
Tecnologias:
- React (componentes)
- JavaScript/TypeScript (lógica)
- Compila para código nativo (Swift/Kotlin)
Setup:
npx create-expo-app@latest conecta-prof
cd conecta-prof
npm install @react-navigation/native @react-navigation/stack
// App.tsx
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
const Stack = createStackNavigator()
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</NavigationContainer>
)
}
Componentes nativos:
// components/CameraCapture.tsx
import { Camera } from 'expo-camera'
import { useState } from 'react'
import { View, Button } from 'react-native'
export function CameraCapture() {
const [hasPermission, setHasPermission] = useState(null)
const [camera, setCamera] = useState(null)
const takePicture = async () => {
if (camera) {
const photo = await camera.takePictureAsync()
console.log('Photo:', photo.uri)
}
}
return (
<View>
<Camera
ref={(ref) => setCamera(ref)}
style={{ height: 400 }}
/>
<Button title="Tirar foto" onPress={takePicture} />
</View>
)
}
Comparação: PWA vs React Native
1. Custo de desenvolvimento
PWA:
- 1 codebase (web)
- Desenvolve como site Next.js normal
- Adiciona manifest + Service Worker
- Tempo: 6-8 semanas
- Custo: R$ 45-65K
React Native:
- 1 codebase (JavaScript)
- Mas testa em iOS + Android
- Builds separados
- Review da Apple/Google
- Tempo: 10-14 semanas
- Custo: R$ 95-135K
PWA é 50-60% mais barato.
2. Funcionalidades
| Feature | PWA | React Native |
|---|---|---|
| Offline | ✅ (Service Worker) | ✅ (AsyncStorage) |
| Push notifications | ✅ (Web Push) | ✅ (Native Push) |
| Geolocalização | ✅ (Navigator API) | ✅ (Expo Location) |
| Câmera | ⚠️ (Limitado) | ✅ (Controle total) |
| Contatos | ❌ | ✅ |
| Bluetooth | ⚠️ (Web Bluetooth) | ✅ |
| Biometria | ❌ | ✅ (FaceID, TouchID) |
| Background tasks | ❌ | ✅ |
| App Store | ❌ | ✅ |
| Payments in-app | ❌ | ✅ (IAP) |
PWA cobre 70% dos casos de uso. React Native para features nativas avançadas.
3. Performance
Startup time (tempo até app estar pronto):
| Tipo | Cold start | Warm start |
|---|---|---|
| PWA | 800ms-1.5s | 200-400ms |
| React Native | 1.2-2s | 400-600ms |
| Native (Swift/Kotlin) | 400-800ms | 100-200ms |
PWA é mais rápido (já está no browser).
Animações:
- PWA: 60fps (CSS animations)
- React Native: 60fps (Reanimated 2)
Performance geral: Empate (ambos são bons).
4. Distribuição
PWA:
- Deploy via Vercel/Netlify (5 minutos)
- Atualização instantânea (refresh = nova versão)
- Sem approval da Apple/Google
- ✅ Deploy contínuo
React Native:
- Submit para App Store (iOS: 1-3 dias review)
- Submit para Play Store (Android: 1-2 horas)
- Update = novo build + review
- ❌ Fricção em updates
Exceção: Expo OTA (over-the-air updates)
# Atualiza sem resubmit
npx eas-cli update
Funciona para mudanças JavaScript (não nativas).
5. Descoberta
PWA:
- SEO funciona (Google indexa)
- Compartilhável via URL
- Sem visibilidade em app stores
React Native:
- App Store = descoberta
- ASO (App Store Optimization)
- Sem SEO (não é web)
Híbrido: PWA + listing nas stores (usando TWA/Trusted Web Activity).
Quando usar PWA
Cenários ideais:
- MVP com budget apertado (R$ 40-60K)
- Iterar rápido (deploy múltiplas vezes/dia)
- Funcionalidades web (formulários, listas, buscas)
- SEO importa (tráfego orgânico)
- Usuários mobile + desktop
Exemplos:
- Marketplace (professores, serviços)
- SaaS B2B (gestão, CRM)
- E-commerce
- Plataformas de conteúdo
Cases reais de PWAs:
- Twitter Lite: PWA economizou 70% dados vs app nativo
- Uber: PWA para mercados com 2G/3G
- Pinterest: PWA aumentou engagement em 60%
Quando usar React Native
Cenários ideais:
- Features nativas obrigatórias (câmera avançada, biometria, bluetooth)
- App Store é canal de aquisição (ASO, rankings)
- Uso offline intenso (sync complexo)
- Experiência “app-like” crítica (animações complexas)
- In-app purchases (monetização via store)
Exemplos:
- Apps de fitness (sensores, background tracking)
- Apps de foto/vídeo (câmera, edição)
- Jogos (performance, animações)
- Fintechs (biometria, segurança)
Cases reais React Native:
- Instagram: Partes do app em RN
- Shopify: App mobile em RN
- Discord: iOS + Android com RN
Arquitetura híbrida (PWA + React Native)
Cenário: Começa PWA, adiciona app nativo depois.
Vantagens:
- Validação rápida (PWA em 6 semanas)
- App nativo quando fizer sentido
- Reutiliza 60-70% do código (API, lógica)
Estrutura:
monorepo/
├── packages/
│ ├── web/ ← Next.js (PWA)
│ ├── mobile/ ← React Native
│ ├── shared/ ← Lógica compartilhada
│ └── api/ ← Backend (Next.js API routes)
Código compartilhado:
// packages/shared/hooks/use-bookings.ts
export function useBookings(userId: string) {
const [bookings, setBookings] = useState([])
useEffect(() => {
fetch(`/api/bookings?userId=${userId}`)
.then(res => res.json())
.then(setBookings)
}, [userId])
return { bookings }
}
// Funciona em Web E Mobile
Custo incremental:
- PWA: R$ 50K (6 semanas)
-
- Mobile depois: R$ 40K (4 semanas, reusa código)
- Total: R$ 90K (vs R$ 115K se começasse com RN)
PWA avançado: Funcionalidades nativas
1. Push notifications
// lib/push-notifications.ts
export async function subscribeToPush() {
const registration = await navigator.serviceWorker.ready
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
})
// Envia subscription para backend
await fetch('/api/push/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: { 'Content-Type': 'application/json' }
})
}
// Backend (Next.js API route)
import webpush from 'web-push'
export async function POST(req: Request) {
const subscription = await req.json()
const payload = JSON.stringify({
title: 'Nova aula agendada!',
body: 'Você tem uma aula às 14h',
icon: '/icon-192x192.png'
})
await webpush.sendNotification(subscription, payload)
return Response.json({ success: true })
}
2. Offline com Service Worker
// public/sw.js
const CACHE_NAME = 'conecta-prof-v1'
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll([
'/',
'/dashboard',
'/static/css/main.css',
'/static/js/bundle.js'
])
})
)
})
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
// Cache first, network fallback
return response || fetch(event.request)
})
)
})
3. Install prompt (Android)
// components/InstallPrompt.tsx
export function InstallPrompt() {
const [deferredPrompt, setDeferredPrompt] = useState(null)
useEffect(() => {
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault()
setDeferredPrompt(e)
})
}, [])
const handleInstall = async () => {
if (deferredPrompt) {
deferredPrompt.prompt()
const { outcome } = await deferredPrompt.userChoice
if (outcome === 'accepted') {
console.log('App installed!')
}
setDeferredPrompt(null)
}
}
if (!deferredPrompt) return null
return (
<div className="install-banner">
<p>Instale nosso app para acesso mais rápido!</p>
<Button onClick={handleInstall}>Instalar</Button>
</div>
)
}
Case real: Marketplace que economizou R$ 70K com PWA
Perfil: Marketplace de serviços de beleza (manicure, cabeleireiro).
Decisão: PWA vs React Native.
Análise:
| Critério | PWA | React Native |
|---|---|---|
| Custo | R$ 45K | R$ 115K |
| Timeline | 6 semanas | 12 semanas |
| Deploy | Instantâneo | 2-3 dias (review) |
| Features nativas | 90% suficiente | 100% |
Features necessárias:
- ✅ Geolocalização (buscar profissionais perto)
- ✅ Push notifications (confirmar agendamento)
- ✅ Câmera (foto do resultado)
- ✅ Offline (ver agendamentos)
- ❌ Biometria (não obrigatória)
- ❌ Background tracking (não necessário)
Decisão: PWA.
Resultado (6 meses):
- Desenvolvimento: R$ 45K (6 semanas)
- 2.800 “instalações” (Add to Home Screen)
- 42% dos usuários acessam via PWA (vs browser)
- Retention 30 dias: 58% (PWA) vs 41% (browser)
- Economia: R$ 70K vs React Native
Futuro: Se precisar de features nativas, migra parte para RN (reutiliza código).
Checklist de decisão
Escolha PWA se:
- Budget menor que R$ 80K
- Precisa lançar em menor que 8 semanas
- Features nativas básicas (geo, push, câmera)
- SEO importa
- Iteração rápida (deploys diários)
- Usuários mobile + desktop
Escolha React Native se:
- Budget maior que R$ 100K
- Features nativas avançadas (biometria, bluetooth, sensores)
- App Store é canal de aquisição
- In-app purchases
- Offline complexo
- Apenas mobile (desktop não importa)
Escolha híbrido (PWA → RN) se:
- MVP rápido, evolução para nativo depois
- Quer validar antes de investir em native
- Tem planos de features nativas futuras
Próximos passos
Para PWA:
- Setup manifest.json
- Configurar Service Worker (next-pwa)
- Implementar offline (cache strategy)
- Testar install prompt
- Configurar push notifications
- Otimizar para mobile (responsive)
- Lighthouse audit (PWA score 100)
Para React Native:
- Setup com Expo
- Configurar navegação (React Navigation)
- Implementar features nativas (câmera, biometria)
- Testar em iOS + Android
- Setup CI/CD (EAS Build)
- Submit para stores
- Configurar analytics (Mixpanel)
Lembre-se: PWA é 60% mais barato e 2x mais rápido de lançar. Se funciona para seu caso, use. Sempre pode evoluir para nativo depois.