Você sabe como funcionam os super apps chineses? Um estudo com Flutter

Aqui está o artigo formatado em formato bilíngue, conforme solicitado:

Do you know how Chinese super apps work? A study with Flutter

Você sabe como funcionam os super apps chineses? Um estudo com Flutter

You have probably heard that “WeChat is your WhatsApp, your bank, and your Uber, all in the same app.” This comparison sells the idea well to those who have never used a Chinese super app, but it is only the surface. Behind it lies a very specific software architecture decision that most articles about “super apps in Flutter” never manage to explain: how can a single application run tens of thousands of third-party services without each update going through the App Store? In this article, I move away from the product discourse and go straight to the architecture: how WeChat, Alipay, and Douyin solve this technically, why this solution is not replicable with pure Flutter, and what can actually be built when the goal is to have multiple services within the same app.

Você já deve ter ouvido que “o WeChat é seu WhatsApp, seu banco e seu Uber, tudo no mesmo app”. Essa comparação vende bem a ideia pra quem nunca usou um super app chinês, mas é só a superfície. Por trás dela existe uma decisão de arquitetura de software bem específica, que a maioria dos artigos sobre “super apps em Flutter” nunca chega a explicar: como um único aplicativo consegue rodar dezenas de milhares de serviços de terceiros sem que cada atualização passe pela App Store? Neste artigo eu saio do discurso de produto e vou direto pra arquitetura: como o WeChat, o Alipay e o Douyin resolvem isso tecnicamente, por que essa solução não é replicável com Flutter puro, e o que dá pra construir de fato quando o objetivo é ter vários serviços dentro do mesmo app.


Summary

  • What is a super app, technically
  • Why there is no “dynamic Flutter” inside a super app
  • The real architecture: native shell, engine, and JSBridge
  • What can (and cannot) be done with Flutter
  • What is already ready (and in production) in the Flutter ecosystem
  • Four 100% Flutter paths for dynamic mini-apps
  • Conclusion

Sumário

  • O que é, tecnicamente, um super app
  • Por que não existe “Flutter dinâmico” dentro de um super app
  • A arquitetura real: shell nativo, engine e JSBridge
  • O que dá (e o que não dá) pra fazer com Flutter
  • O que já existe pronto (e em produção) no ecossistema Flutter
  • Quatro caminhos 100% Flutter pra mini-apps dinâmicos
  • Conclusão

What is a super app, technically A super app is not just “a big app with many screens.” It is a platform with three well-defined layers:

  • Host / shell: The app the user downloads from the store. It handles authentication, payments, system permissions (camera, location), and top-level navigation.
  • Mini-program runtime: An engine embedded within the shell, capable of executing third-party code in an isolated and secure manner.
  • Mini-programs: The “apps within the app,” developed by internal teams or external partners, published and updated without going through the App Store or Play Store. The piece that makes everything work is the runtime, and that is exactly where the catch lies.

O que é, tecnicamente, um super app Um super app não é só “um app grande com muitas telas”. É uma plataforma com três camadas bem definidas:

  • Host / shell: o app que o usuário baixa da loja. Cuida de autenticação, pagamentos, permissões de sistema (câmera, localização) e a navegação de topo.
  • Runtime de mini-programs: um motor embarcado dentro do shell, capaz de executar código de terceiros de forma isolada e segura.
  • Mini-programs: os “apps dentro do app”, desenvolvidos por times internos ou parceiros externos, publicados e atualizados sem passar pela App Store ou pela Play Store. A peça que faz tudo funcionar é o runtime, e é exatamente aí que mora a pegadinha.

Why there is no “dynamic Flutter” inside a super app The first question every Flutter dev asks is: can we package each mini-app as a Dart module and load it dynamically, like Android’s dynamic feature modules? No, and the reason is not technical; it is store policy. Apple’s Guideline 2.5.2 states that an app must be self-contained and cannot download, install, or execute code that introduces or alters functionality after review. Historically, the only accepted loophole was for interpreted scripts running within WebKit or JavaScriptCore embedded in iOS itself, provided they did not change the app’s main purpose declared in the store. An AOT-compiled Dart binary does not fit this loophole because it is native code, not interpreted by a system engine.

Por que não existe “Flutter dinâmico” dentro de um super app A primeira pergunta que todo dev Flutter faz é: dá pra empacotar cada mini-app como um módulo Dart e carregar isso dinamicamente, tipo dynamic feature modules do Android? Não, e o motivo não é técnico, é de política de loja. A Guideline 2.5.2 da Apple determina que um app precisa ser autocontido e não pode baixar, instalar ou executar código que introduza ou altere funcionalidades depois da revisão. Historicamente, a única brecha aceita era pra scripts interpretados rodando dentro do WebKit ou do JavaScriptCore embutidos no próprio iOS, desde que não mudassem o propósito principal do app declarado na loja. Um binário Dart compilado em AOT não se encaixa nessa brecha porque é código nativo, não interpretado por uma engine do sistema.


It is worth noting that this is a legally sensitive area: Apple has publicly clashed with the mini-program category more than once, and oversight of this type of code download has only become stricter in recent years. This is why no Chinese super app runs Flutter, React Native, or any natively compiled framework within its mini-programs. Each giant solved this with its own embedded script engine:

Vale registrar que essa é uma área juridicamente sensível: a Apple já entrou em atrito público com a categoria de mini-programs mais de uma vez, e a fiscalização sobre esse tipo de download de código só ficou mais rígida nos últimos anos. É por isso que nenhum super app chinês executa Flutter, React Native ou qualquer framework compilado nativamente dentro dos seus mini-programs. Cada gigante resolveu isso com sua própria engine de script embarcada:


  • WeChat (MINA framework): Separates the application into two threads. The rendering layer (WXML/WXSS) runs inside a WebView, while the logic layer (the developer’s JS) is isolated in a JSCore thread, a pure JS engine without access to DOM or window. This separation exists for security, as third-party code never touches the UI directly, and for performance, because the UI does not freeze waiting for business JS to process.

  • Alipay (APPX + V8 Worker framework): Went further. Each mini-program runs its own rendering script (index.js, executed in WebView) and its own business logic script (index.worker.js, executed as a Worker on a dedicated V8 engine). This architecture allows initializing the WebView and the V8 engine in parallel, isolates the framework’s JS from the developer’s JS in separate V8 contexts, and exposes a JSAPI for native plugins to connect to the execution context.

  • Douyin: Uses the same base architecture as WeChat: the official documentation of the Douyin mini-program platform describes the framework as divided into a logic layer (JS Core) and a rendering layer (WebView), with its own markup language (TTML/TTSS) equivalent to WeChat’s WXML/WXSS.

  • WeChat (framework MINA): separa a aplicação em duas threads. A camada de renderização (WXML/WXSS) roda dentro de uma WebView, enquanto a camada lógica (o JS do desenvolvedor) fica isolada numa thread JSCore, um motor JS puro, sem acesso a DOM ou window. Essa separação existe por segurança, já que o código de terceiros nunca toca a UI diretamente, e por performance, porque a UI não trava esperando o JS de negócio processar.

  • Alipay (framework APPX + V8 Worker): foi além. Cada mini-program roda seu próprio script de renderização (index.js, executado em WebView) e seu próprio script de lógica de negócio (index.worker.js, executado como Worker sobre uma engine V8 dedicada). Essa arquitetura permite inicializar a WebView e a engine V8 em paralelo, isola o JS do framework do JS do desenvolvedor em contextos V8 separados, e ainda expõe uma JSAPI pra plugins nativos se conectarem ao contexto de execução.

  • Douyin: usa a mesma arquitetura de base do WeChat: a documentação oficial da plataforma de mini-programs do Douyin descreve o framework como dividido em camada lógica (JS Core) e camada de renderização (WebView), com uma linguagem de marcação própria (TTML/TTSS) equivalente ao WXML/WXSS do WeChat.