Voltar para artigosArtigo

NativePHP: como criar apps iOS e Android com PHP

Uma analise tecnica e executiva sobre NativePHP, seus tradeoffs arquiteturais e onde a stack realmente faz sentido em mobile.

9 min
0
Ilustração anime estilo build com carlos: o elefante mascote do PHP no centro, ladeado pelo robô do Android e pelo logo do iOS, ligados por uma ponte NativePHP, com dois celulares rodando o mesmo app.

Tese central

NativePHP e interessante nao porque redefine o mobile, mas porque reduz a distancia entre times Laravel, distribuicao de apps e validacao de produto. O ponto principal nao e substituir Swift, Kotlin, Flutter ou React Native, e sim entender em quais contextos o reuso de stack compensa os tradeoffs de runtime, UI e ecossistema.

Vale separar duas coisas que costumam ser confundidas. A promessa de marketing e “escreva PHP, gere um app nativo”. A realidade tecnica e mais especifica: voce empacota um interpretador PHP dentro de um shell nativo, roda a sua aplicacao Laravel localmente no aparelho e renderiza a interface dentro de uma WebView. Entender essa diferenca e o que separa uma decisao de arquitetura de uma aposta cega. O resto do artigo e sobre isso: o que exatamente acontece dentro do binario, onde isso compensa e onde cobra caro.

Para quem e este artigo

  • Liderancas tecnicas avaliando stacks para MVPs ou ferramentas internas
  • Times Laravel curiosos sobre NativePHP
  • Engenheiros mobile interessados em mapear os limites reais da proposta

Se voce ja e um time mobile nativo consolidado, provavelmente vai ler isto como um mapa de “quando um time de backend deveria ou nao entrar no seu territorio”. Se voce e um time Laravel, vai ler como um teste de realidade antes de prometer um app pra area de produto.

Contexto

Times backend maduros frequentemente esbarram no mesmo problema: precisam criar uma experiencia instalavel, mas nao querem abrir uma nova frente de engenharia mobile logo no inicio. Contratar iOS e Android, montar pipeline de build, aprender as regras das lojas e manter duas bases nativas e um investimento grande para validar uma hipotese que ainda pode nao se sustentar.

Historicamente, a resposta pra esse dilema foi a familia “web dentro de um app”: Cordova, depois Capacitor, e o mundo PWA. NativePHP entra nessa mesma familia conceitual, mas com uma diferenca importante. Em vez de mover a logica pro JavaScript no cliente, ele embute um runtime PHP e executa a aplicacao Laravel inteira, com rotas, controllers, migrations e Eloquent, localmente no dispositivo. O projeto nasceu no desktop (empacotando apps Laravel como executaveis de macOS, Windows e Linux) e a variante mobile aplica a mesma ideia a iOS e Android. Para um time que ja pensa em termos de request, response, model e view, isso muda menos o modelo mental do que qualquer outra abordagem.

Arquitetura simplificada

flowchart TD
  User["Usuario"] --> Shell["Shell nativo (Swift / Kotlin)"]
  Shell --> Runtime["Embedded PHP Runtime"]
  Runtime --> Laravel["Laravel Application"]
  Laravel --> UI["HTML / CSS / JS UI"]
  Laravel --> Native["Bridge para APIs nativas"]
  Native --> Device["Camera, arquivos, notificacoes"]

A imagem mental correta e a de tres camadas empilhadas dentro do mesmo binario.

A primeira e o shell nativo. Em iOS ele e escrito em Swift, em Android em Kotlin. Esse shell e o app “de verdade” que a loja ve: ele cuida do ciclo de vida (launch, background, retomada), hospeda a WebView e sobe o runtime PHP quando o app abre.

A segunda e o runtime PHP embarcado. Um interpretador PHP compilado para a arquitetura do aparelho (tipicamente ARM64) vai dentro do bundle do app, junto com o codigo da sua aplicacao Laravel e o diretorio vendor com as dependencias. Quando o app inicia, o shell efetivamente sobe um servidor PHP local. Nao ha rede envolvida: as requisicoes vao do WebView pra esse servidor via localhost ou um esquema de URL customizado, e voltam.

A terceira e a ponte (bridge) para APIs nativas. Como PHP puro nao sabe abrir a camera nem disparar uma notificacao local, o NativePHP expoe facades PHP que serializam um comando e o entregam pra camada nativa executar. Voce chama algo em PHP, o shell traduz aquilo em uma chamada Swift ou Kotlin de verdade, executa, e devolve o resultado.

O detalhe que faz esse modelo funcionar melhor do que parece e a localidade. Como o “servidor” esta no proprio aparelho, ferramentas server-driven como o Livewire deixam de pagar o custo de latencia de rede. Uma interacao que num app web tradicional seria um round-trip pela internet vira uma chamada localhost de milissegundos. Isso e o que torna a UI reativa sem escrever JavaScript pesado.

Como funciona na pratica

O fluxo de trabalho e deliberadamente familiar pra quem vem de Laravel:

composer require nativephp/mobile
php artisan native:install
php artisan native:serve
php artisan native:build

native:install prepara o projeto nativo (Xcode/Gradle) e a integracao com o runtime. native:serve roda o app conectado ao seu ambiente de desenvolvimento com hot reload, entao editar uma Blade e ver no aparelho e imediato. native:build gera o artefato distribuivel (.ipa / .aab).

O codigo do app continua sendo Laravel comum:

Route::get('/', function () {
    return view('hello');
});
<!DOCTYPE html>
<html>
<head>
  <title>NativePHP Demo</title>
</head>
<body>
  <h1>Hello World</h1>
  <p>This app is running Laravel inside a mobile app.</p>
</body>
</html>

A diferenca aparece quando voce precisa de hardware. Em vez de escrever Swift, voce chama uma facade PHP que o NativePHP mapeia para a API nativa. O formato exato varia por versao, mas a ideia e sempre essa: um metodo PHP que dispara uma capacidade do aparelho.

use Native\Mobile\Facades\Dialog;

Route::post('/confirmar', function () {
    Dialog::alert('Salvo', 'Seu registro foi gravado localmente.');
    return back();
});

Persistencia local segue o modelo Laravel de sempre: SQLite via Eloquent, migrations rodando no aparelho, tudo dentro do sandbox do app. Isso e o que viabiliza fluxos offline reais - o banco esta no dispositivo, nao atras de uma API remota. Para casos que precisam sincronizar, o padrao usual e tratar o backend na nuvem como fonte de verdade e o SQLite local como cache, o mesmo desenho que um app nativo bem feito adotaria.

Onde ele gera valor

  • Reuso de conhecimento por times Laravel. Um time que domina Eloquent, Blade, filas e o container de servicos aproveita quase tudo. A curva de aprendizado deixa de ser “uma nova plataforma” e vira “um novo alvo de deploy”.
  • Ganho de velocidade em MVPs e apps internos. Sem manter duas bases nativas em paralelo, um unico codigo cobre iOS e Android. Para validar uma hipotese de produto, isso encurta o caminho ate ter algo instalado na mao de alguem.
  • Menor atrito inicial para distribuir apps instalaveis. Muita ferramenta interna hoje e um painel web que ninguem instala. Empacotar como app resolve presenca no springboard, notificacoes e acesso a hardware sem reescrever a logica.
  • Fluxos offline reais. Com SQLite e a logica rodando no aparelho, o app funciona sem conexao por design, nao como um recurso adicionado depois.

Onde os tradeoffs pesam

Nenhum desses pontos e fatal por si so, mas ignora-los e o que gera divida tecnica cedo.

  • Tamanho do binario. Voce esta embarcando um interpretador PHP inteiro, o framework Laravel e todo o vendor. Isso adiciona uma base fixa de peso ao app antes de escrever uma linha de feature. Para um utilitario interno, irrelevante; para um app de consumo sensivel a taxa de instalacao, e um custo a medir.
  • Startup mais lento. O cold start precisa subir o runtime PHP e fazer o bootstrap do Laravel (service providers, config, rotas). Mesmo local, isso nao e instantaneo. Cache de config e de rotas ajuda, mas dificilmente iguala o tempo de abertura de um app nativo enxuto.
  • Maior consumo de memoria. Um runtime PHP vivo mais a WebView custam mais RAM do que views nativas puras. Em aparelhos de entrada, isso aproxima o app do limite onde o sistema mata processos em background.
  • UI menos aderente ao nativo. A interface e HTML/CSS renderizado em WebView. Da pra chegar longe com um bom design system web, mas gestos finos, transicoes de 60fps consistentes e aquele “cheiro” de plataforma nativa sao mais dificeis de acertar.
  • Acesso a hardware limitado ao que a ponte expoe. Se uma capacidade nao tem facade, voce cai em escrever codigo nativo ou um plugin - exatamente a competencia que estava tentando evitar contratar.
  • Ecossistema menor e mais jovem. Menos plugins prontos, menos respostas no Stack Overflow, menos casos de producao documentados. Isso importa quando algo quebra as vesperas de um lancamento.

Comparacao de posicionamento

Tecnologia Linguagem UI Performance esperada Maturidade
Native iOS / Android Swift / Kotlin Nativa Muito alta Muito alta
Flutter Dart Engine propria Alta Alta
React Native JS / TS Bridge nativa Media a alta Alta
Capacitor / Cordova JS / TS WebView Baixa a media Alta
NativePHP PHP WebView + runtime local Baixa a media Baixa

A tabela resume, mas as fronteiras merecem nuance.

Contra Flutter: Flutter compila Dart pra codigo nativo e desenha a UI com engine propria (Skia/Impeller), entregando animacao consistente e alta fidelidade visual. E o oposto do modelo WebView. Se pixel e frame rate importam, Flutter joga em outra liga.

Contra React Native: RN renderiza views nativas de verdade a partir de JS. A fidelidade de UI e a performance de rolagem ficam acima de qualquer abordagem WebView. Em troca, voce mantem um mundo JS/TS e a ponte que vem com ele.

Contra Capacitor / Cordova: essa e a comparacao mais justa, porque ambos usam WebView + ponte nativa. A diferenca e onde a logica roda. No Capacitor, a logica e JavaScript no cliente e nao ha servidor. No NativePHP, ha um servidor PHP local de fato, entao a sua logica de dominio roda em PHP no aparelho. Para um time Laravel, isso significa reaproveitar controllers, models e validacao em vez de reescreve-los em JS.

Contra PWA: um PWA nao passa pelas lojas, nao embarca runtime e tem acesso a hardware mais restrito (embora crescente). NativePHP troca essa leveza por presenca nas lojas, uma ponte nativa mais ampla e persistencia local robusta.

Quando eu consideraria usar

  • Ferramentas internas onde a experiencia importa menos que ter algo instalavel rapido
  • Dashboards administrativos que hoje ja sao web e so precisam virar app
  • MVPs para validar uma hipotese antes de investir em engenharia mobile dedicada
  • Produtos com time Laravel forte, prazo curto e necessidade de aprender rapido com usuarios reais

O fio comum e sempre o mesmo: o custo de aprender uma stack nova superaria o beneficio, e a experiencia de UI nao e o diferencial competitivo do produto.

Quando eu evitaria

  • Produto mobile core, onde o app e o negocio e nao um acessorio dele
  • UI muito refinada, com animacoes, gestos e transicoes como parte da proposta de valor
  • Apps com uso pesado de hardware (camera em tempo real, sensores de alta frequencia, graficos)
  • Roadmaps longos que dependem de um ecossistema maduro de bibliotecas e contratacao
  • Casos que exigem atualizacao frequente do codigo pela loja: as regras da App Store restringem baixar e executar codigo novo em runtime, entao apps NativePHP costumam depender do ciclo normal de review pra publicar mudancas de logica, sem o atalho de OTA que um app puramente web teria via servidor

Conclusao

NativePHP pode ser uma trilha valida de experimento. Eu nao o trataria como substituto natural de engenharia mobile madura. Se o objetivo e compressao de stack e velocidade inicial, vale um prototipo serio: monte um fluxo real, meca o tamanho do binario e o tempo de cold start no aparelho mais fraco do seu publico, e teste uma capacidade nativa que voce sabe que vai precisar. Esses tres numeros dizem mais sobre a viabilidade do que qualquer benchmark de marketing.

Se o objetivo e experiencia, escala e longevidade de plataforma, eu seguiria com stacks mais estabelecidas. A pergunta certa nunca e “PHP consegue virar app?” - consegue. E “esse app especifico, com esse publico e esse roadmap, cabe dentro dos limites de uma WebView com runtime embarcado sem me deixar preso mais tarde?”.

Para aprofundar

CTA

Se esse tema te interessa, vale discutir menos se a ideia e curiosa e mais onde ela realmente cabe sem gerar divida tecnica cedo demais.