AWS Builder Center

Por Que Quarkus + Vanilla JS + AWS Lambda + DynamoDB É o Caminho Mais Rápido da Ideia à Produção

Eu construí o re:Money com o Kiro em horas. Mas continuo vendo desenvolvedores criarem apps incríveis com IA e depois travarem no deploy. Veja como escolher Quarkus, vanilla JS, Lambda e DynamoDB torna a ida à produção uma tarefa simples, rápida e escalável.

O desenvolvimento assistido por IA mudou tudo. Você descreve o que quer, uma IA constrói, e em algumas horas você tem um app funcionando no seu laptop. Eu construí o re:Money — um app completo de controle financeiro com dashboards, tabelas dinâmicas, importação de CSV e interface de chat — usando o Kiro , e foi genuinamente divertido.
Mas aqui está o padrão que continuo vendo: desenvolvedores constroem algo incrível com IA, fazem demo no localhost, e então... fica no localhost. Fazer deploy para produção se torna a parte difícil. De repente você precisa de Docker, Kubernetes, banco de dados gerenciado, configurações de VPC, pipelines de CI/CD e um diploma em arquitetura cloud.
Não precisa ser assim.
O segredo não é apenas como você codifica — é o que você escolhe para construir. O re:Money faz deploy na AWS Lambda com dois comandos por causa de quatro escolhas arquiteturais deliberadas: Quarkus como framework, vanilla JavaScript para o front-end, AWS Lambda para computação e DynamoDB para armazenamento. Juntas, essas quatro peças fizeram a distância entre "funciona na minha máquina" e "rodando em produção" ser praticamente zero.

Mas Primeiro — O Que É "Vanilla JS"?

Se você nunca ouviu o termo, tem uma ótima história por trás. Em 2012, um site satírico chamado Vanilla-JS.com  surgiu, apresentando Vanilla JS como um "framework rápido e leve" já "usado por mais sites que jQuery e React combinados." Quando você clicava para "baixar" a biblioteca, recebia um arquivo vazio — porque Vanilla JS é apenas JavaScript puro. Sem framework. Sem dependências. Apenas a linguagem que seu navegador já fala.
Essa piada carrega um insight real: para muitas aplicações, JavaScript puro é tudo que você precisa. E quando se trata de deploy, o que você não depende importa tanto quanto o que você usa.

Serverless é Vida!

Antes de entrarmos nos passos do deploy, vamos falar sobre por que cada peça dessa stack é unicamente adequada para ir da ideia à produção.

Quarkus: Um Framework, Um Artefato, Zero Fricção

O Quarkus é a cola que mantém tudo junto. Ele oferece:
  • Renderização server-side com Qute — Templates HTML que vivem dentro do JAR, sem build de front-end separado
  • Suporte para AWS Lambda — O Quarkus tem uma extensão dedicada para Lambda que cuida do adaptador HTTP para você
  • Inicialização rápida — projetado desde o início para cargas de trabalho cloud-native e serverless
  • Uber-JAR único — toda sua aplicação (API REST, templates, CSS, JS) compila em um só artefato
  • Modo dev com hot reload — ./mvnw quarkus:dev dá feedback instantâneo durante o desenvolvimento

Vanilla JS: Sem Pipeline de Build para o Front-End

Com React ou Angular, você precisa de Node.js, npm, um bundler (Webpack/Vite) e um passo de build separado que produz assets estáticos que você depois precisa servir do S3 ou CloudFront. Com o re:Money, a UI são templates Qute + vanilla JS. Está tudo dentro do JAR. Um build, um artefato, um deploy.

AWS Lambda: Computação Serverless Que Escala até Zero

Lambda significa:
  • Sem servidores para gerenciar — sem instâncias EC2, sem clusters ECS, sem Kubernetes
  • Pague apenas pelo que usar — cobrado por requisição e tempo de computação, ocioso = gratuito
  • Escalonamento automático — de zero a milhares de requisições concorrentes sem configuração
  • SAM torna declarativo — toda sua infraestrutura é definida em um único template.yaml
Lambda é a razão pela qual sam build && sam deploy é tudo que você precisa. Sem registry Docker, sem orquestração de containers, sem load balancers.

DynamoDB: O Banco de Dados Que Combina com o Modelo do Lambda

Este é o grande diferencial. Se o re:Money usasse PostgreSQL ou MySQL, você precisaria:
  • Uma instância RDS (sempre rodando, sempre cobrando)
  • Configuração de VPC para o Lambda alcançar o banco de dados
  • Connection pooling (cold starts do Lambda + bancos relacionais = dor)
  • Migrações de banco a cada deploy
O DynamoDB não tem nenhum desses problemas. Ele é:
  • Pay-per-request — custo zero quando ocioso
  • Sem conexões para gerenciar — é baseado em HTTP, perfeito para a natureza efêmera do Lambda
  • Sem VPC necessária — Lambda se comunica com DynamoDB pela API pública da AWS
  • Sem migrações — schema-free, então seu código é seu schema
  • Escala de zero ao infinito — assim como o próprio Lambda
Lambda + DynamoDB é a única combinação verdadeiramente serverless de computação + armazenamento na AWS. Todo o resto requer algo rodando 24/7.

As Quatro Peças Trabalhando Juntas

Eis por que essas quatro escolhas se potencializam:
  • Quarkus empacota seus templates e JS em um único JAR → sem deploy separado de front-end
  • Vanilla JS significa sem passo de build Node.js → esse JAR é tudo que você precisa buildar
  • Lambda roda esse JAR de forma serverless → sem infraestrutura para provisionar
  • DynamoDB não precisa de VPC ou conexões → Lambda se comunica com ele direto
Remova qualquer peça e a história do deploy fica mais difícil. Juntas, elas criam um caminho sem fricção de git clone à produção.

Artefato Único para Deploy

O re:Money compila em um único function.zip. Sem imagens Docker, sem registries de container, sem builds multi-stage. O SAM faz upload para o S3, Lambda executa. É isso.

A Equação de Custo

Para um app de finanças pessoais (ou qualquer ferramenta de tráfego baixo a moderado), essa arquitetura pode rodar por centavos por mês:
ServiçoCusto
LambdaFree tier: 1M requisições/mês
API GatewayFree tier: 1M chamadas/mês
DynamoDBFree tier: 25GB armazenamento, 25 WCU/RCU
Total~R$0/mês para uso pessoal
Tente conseguir isso com ECS + RDS.

Pré-requisitos

Antes de começar, certifique-se de ter:
  • Java 21+ instalado
  • Maven 3.8+ (ou use o wrapper mvnw incluído)
  • AWS CLI configurado com credenciais (aws configure)
  • AWS SAM CLI instalado (guia de instalação )

Passo 1: Clone e Build

1
2
git clone https://github.com/renascence-computing/reos-money.git
cd reos-money
Construa o artefato pronto para Lambda:
1
./build-lambda.sh
Esse script faz três coisas:
  1. Executa mvn clean package com o perfil uber-jar
  2. Renomeia o JAR runner para function.jar
  3. Compacta em target/function.zip
Essa é sua aplicação inteira — backend, front-end, templates, CSS, JavaScript — em um arquivo zip.

Passo 2: Revise o Template SAM

O template.yaml define tudo que o Lambda precisa:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: re:Money Quarkus Lambda Application

Resources:
ReMoneyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/function.zip
Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
Runtime: java21
Timeout: 30
MemorySize: 1024
Events:
ReMoneyApi:
Type: HttpApi
Properties:
Path: /{proxy+}
Method: ANY
ReMoneyRoot:
Type: HttpApi
Properties:
Path: /
Method: ANY
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref EntryTable

EntryTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: entry
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
Pontos importantes a notar:
  • HttpApi (API Gateway v2) — URLs mais limpas sem o prefixo de stage /Prod
  • PAY_PER_REQUEST billing — você só paga pelo que usa
  • /{proxy+} captura todas as rotas e encaminha para o Quarkus
  • Tabela DynamoDB é criada automaticamente — sem configuração manual
  • Sem VPC, sem subnets, sem security groups — DynamoDB não precisa deles

Passo 3: Deploy com SAM

Para seu primeiro deploy, execute o fluxo guiado:
1
2
sam build
sam deploy --guided
O SAM fará algumas perguntas:
1
2
3
4
5
6
Stack Name [reMoney]: reMoney
AWS Region [us-east-1]: us-east-1
Confirm changes before deploy [y/N]: y
Allow SAM CLI IAM role creation [Y/n]: Y
ReMoneyFunction has no authentication. Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: Y
Isso cria um samconfig.toml para que futuros deploys sejam apenas:
1
sam build && sam deploy
É isso. Dois comandos.

Passo 4: Obtenha Sua URL da API

Após o deploy, o SAM imprime seu endpoint:
1
2
3
4
5
6
Outputs
---------------------------------------------------------------------------
Key ReMoneyApi
Description API Gateway endpoint URL for re:Money application
Value https://abc123xyz.execute-api.us-east-1.amazonaws.com/
---------------------------------------------------------------------------
Abra essa URL no navegador e você verá o re:Money rodando — dashboard, contas, categorias, tabelas dinâmicas, tudo.

Passo 5: Verifique Se Funciona

Teste a API:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Buscar todas as entradas
curl https://abc123xyz.execute-api.us-east-1.amazonaws.com/entryResource/findAll

# Listar categorias
curl https://abc123xyz.execute-api.us-east-1.amazonaws.com/entryResource/listCategories

# Adicionar uma entrada
curl -X POST https://abc123xyz.execute-api.us-east-1.amazonaws.com/entryResource \
-H "Content-Type: application/json" \
-d '{
"accountID": "corrente",
"description": "Café",
"category": "Alimentação",
"amount": -4.50,
"date": "2026-04-06T09:00"
}'
Abra a interface:
1
open https://abc123xyz.execute-api.us-east-1.amazonaws.com/ui

Passo 6: Atualize e Faça Redeploy

Fez alterações? Faça redeploy em menos de um minuto:
1
2
./build-lambda.sh
sam build && sam deploy
Sem Docker push, sem pipeline de CI/CD necessário, sem orquestração de containers. Build, deploy, pronto.

Visão Geral da Arquitetura

Eis o que você obtém:
1
2
3
4
5
6
7
8
9
10
11
┌──────────┐ ┌─────────────┐ ┌──────────────────┐ ┌──────────┐
│ Navegador│────▶│ API Gateway │────▶│ Lambda (Java 21) │────▶│ DynamoDB │
│ │◀────│ │◀────│ Quarkus + Qute │◀────│ │
└──────────┘ └─────────────┘ └──────────────────┘ └──────────┘
│
┌──────┴──────┐
│ JAR Único │
│ - API REST │
│ - HTML/CSS │
│ - Vanilla JS│
└─────────────┘
Três serviços gerenciados da AWS. Zero servidores. Zero containers. Zero infraestrutura para manter.

Por Que Isso Não Funcionaria com uma Stack Tradicional

Vamos comparar como o deploy fica com uma stack moderna típica:
AspectoReact + Spring Boot + PostgreSQLre:Money (Quarkus + Vanilla JS + Lambda + DynamoDB)
FrameworkSpring Boot (cold starts mais pesados)Quarkus (otimizado para Lambda, SnapStart-ready)
Build do front-endnpm install && npm run buildNenhum (templates Qute + vanilla JS no JAR)
Hospedagem do front-endS3 + CloudFrontServido pelo Lambda (empacotado no artefato)
ComputaçãoECS/EKS ou Lambda com config extraLambda (suporte nativo Quarkus)
Banco de dadosRDS ($15+/mês mínimo)DynamoDB (free tier)
VPC necessária?Sim (para RDS)Não
Connection poolingSim (RDS Proxy)Não (baseado em HTTP)
Impacto do cold startAlto (Spring + conexões com DB)Baixo (Quarkus + SnapStart, sem pool de DB)
Comandos de deploy5-10 passossam build && sam deploy
Custo mensal (baixo tráfego)$20-50+$0-1
A combinação Quarkus + vanilla JS + Lambda + DynamoDB não é apenas preferência — é uma decisão arquitetural que elimina categorias inteiras de complexidade de deploy.

Bônus: Elimine Cold Starts com Lambda SnapStart

Java no Lambda tem um trade-off bem conhecido: cold starts. A primeira requisição após um período de inatividade pode levar alguns segundos enquanto a JVM inicializa. Lambda SnapStart resolve isso.

O Que o SnapStart Faz

O SnapStart tira um snapshot de microVM Firecracker da sua função após a inicialização — a JVM está bootada, o Quarkus está carregado, os clientes DynamoDB estão prontos. Quando uma nova invocação chega, o Lambda restaura a partir desse snapshot em vez de iniciar do zero. O resultado: cold starts caem de segundos para milissegundos.

Como Habilitar

Adicione duas linhas nas propriedades da função no seu template.yaml:
1
2
3
4
5
6
7
ReMoneyFunction:
Type: AWS::Serverless::Function
Properties:
# ... propriedades existentes ...
SnapStart:
ApplyOn: PublishedVersions
AutoPublishAlias: live
É isso. SnapStart diz ao Lambda para fazer snapshot após a inicialização, e AutoPublishAlias cria uma versão publicada (necessário — SnapStart só funciona em versões publicadas, não em $LATEST).
Você também pode adicionar essa flag JVM para extrair performance extra de inicialização:
1
2
3
Environment:
Variables:
JAVA_TOOL_OPTIONS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
Então faça redeploy:
1
sam build && sam deploy

Por Que Isso Importa

Sem SnapStart, cold starts de Java no Lambda são tipicamente 3-5 segundos para um app Quarkus. Com SnapStart, estamos falando de ~200-400ms — comparável a cold starts de Node.js ou Python, mas com todos os benefícios da tipagem forte do Java e performance do Quarkus em estado estável.
Combinado com DynamoDB (sem connection pool para reestabelecer na restauração), SnapStart torna Java no Lambda uma escolha genuinamente pronta para produção sem desculpas de latência.

Dicas para Produção

  • Domínio customizado: Adicione um domínio customizado via API Gateway custom domain names + Route 53
  • Autenticação: Adicione Amazon Cognito ou um Lambda authorizer para proteger seus endpoints
  • Cold starts: Habilite SnapStart (veja acima) — é a maior melhoria individual que você pode fazer
  • Monitoramento: CloudWatch Logs são habilitados por padrão — verifique o log group da função Lambda
  • Backups: DynamoDB suporta backups sob demanda e recuperação point-in-time — habilite PITR para tranquilidade

Conclusão

O desenvolvimento assistido por IA nos deu o poder de construir apps em horas. Mas o segredo sujo é que a maioria desses apps nunca sai do localhost — não porque o código é ruim, mas porque a arquitetura não foi escolhida pensando no deploy.
O re:Money funciona em produção por causa de quatro escolhas feitas antes de escrever uma única linha de código: Quarkus como framework, vanilla JS para o front-end, Lambda para computação e DynamoDB para armazenamento. Essas escolhas eliminaram toda a lacuna do deploy.
Sem node_modules. Sem migrações de banco. Sem VPC. Sem containers. Sem orquestração.
Apenas sam build && sam deploy.
Da próxima vez que estiver construindo algo novo com IA, pense em onde precisa rodar — não apenas onde está sendo construído. A melhor arquitetura é aquela que faz produção parecer tão fácil quanto localhost.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article