O que é Vibe Coding?
Vibe Coding: O Manifesto da Nova Era da Programação
Por Jacques Belmont | Engenheiro de Prompt & Arquiteto de Soluções
Do Código à Intenção
Você ainda programa pensando em ponto e vírgula? O jogo mudou.
Vibe Coding é uma metodologia de desenvolvimento onde a sintaxe rígida dá lugar ao fluxo criativo.
A IA (LLMs) atua como nosso “compilador”, transformando linguagem natural em sistemas robustos.
Não é no-code; é code-at-speed-of-thought.
Diferente de plataformas que escondem o código, o Vibe Coding gera código real, limpo e escalável (React, TypeScript, Python), mas a interface principal é a visão do arquiteto — não a digitação manual de caracteres.
A Filosofia do “One-Person Unicorn”
Eu defendo que o desenvolvedor moderno não é um operário de código, mas um orquestrador de inteligência. No Vibe Coding, a barreira entre a ideia e o software funcional é dissolvida.
O mercado não paga pelo código que você digita — paga pelo problema que você resolve. Essa metodologia permite que um único desenvolvedor construa ecossistemas inteiros.
Foi assim que desenvolvi produtos como o Roulette Analytica e estruturas do meu ecossistema sozinho, em uma fração do tempo de um time tradicional.
O Stack do Vibe Coder
- IDEs com IA nativa: Cursor & Windsurf para manter o contexto total do projeto.
- Cérebros digitais: Claude 3.5 Sonnet e GPT-4o para raciocínio lógico complexo.
- Foco: sai a “depuração de sintaxe”, entra a “depuração de lógica de negócio”.
- Disciplina: prompts com constraints, critérios de aceite, segurança e testes.
Engenharia de Prompt: O que separa “prompt aleatório” de “prompt de produção”
Um prompt profissional não é “faça X”. É um contrato de entrega: define papel, escopo, restrições, critérios de aceite e checklist de segurança.
Template (o prompt que eu realmente uso)
Você é [PAPEL: ex. Senior Fullstack Engineer].
Contexto: [o que já existe no repo].
Objetivo: [o que precisa ser implementado].
Restrições:
- Linguagem: [TS/React/Python]
- Sem quebrar APIs existentes
- Sem comentários novos
- Tipagem estrita
- Sem secrets hardcoded
- Validar inputs e tratar erros
Critérios de aceite:
- [lista objetiva, testável]
- [ex.: retorna 200/400 corretamente, não vaza stacktrace, etc.]
Entregáveis:
- Diff minimalista
- Trechos de código finais
- Lista do que foi validado e como testar
Vibe Coding na Prática: Exemplos Reais (com código do meu repo)
O “código-fonte” do Vibe Coder é a intenção clara. Abaixo estão exemplos onde um prompt bem estruturado vira código de produção — com segurança, padrões e deploy em mente.
Exemplo 1: Paywall de Produção (React + Tailwind + UX)
A Intenção (Prompt de UI/UX com constraints):
Você é um Senior Frontend Engineer especialista em produtos pagos.
Crie um componente React + TypeScript para paywall:
- Estado: método ('PIX' | 'CREDIT_CARD') e plano ('MONTHLY_100' | 'FULL')
- Gerar URL de referral usando window.location.origin e user.referralCode
- Ter ações "Copiar link" e "Compartilhar" (usar navigator.share se disponível, fallback para clipboard)
- Design em Tailwind: modal central, foco em conversão, CTA com loading
- Não use libs extras
- Tipagem estrita e props claras
Critérios de aceite:
- Copiar/compartilhar funciona com fallback
- Botão de pagar só habilita após escolher método
- Texto reforça "checkout seguro" sem prometer coisas falsas
Resultado (trecho real do projeto: Roullete-PRO/components/PaywallScreen.tsx):
const PaywallScreen: React.FC<Props> = ({ user, onUpgrade }) => {
const [method, setMethod] = useState<'PIX' | 'CREDIT_CARD' | null>(null);
const [plan, setPlan] = useState<'MONTHLY_100' | 'FULL'>('FULL');
const [processing, setProcessing] = useState(false);
const referralUrl = `${window.location.origin}/?ref=${user.referralCode}`;
const handleCopyReferral = async () => {
try {
await navigator.clipboard.writeText(referralUrl);
alert('Link copiado! Envie para seu amigo.');
} catch {
alert('Não foi possível copiar automaticamente. Copie manualmente: ' + referralUrl);
}
};
const handleShareReferral = async () => {
try {
// @ts-ignore
if (navigator.share) {
// @ts-ignore
await navigator.share({
title: 'Roulette Analytica Pro',
text: 'Use meu link para se cadastrar. Quando você ativar qualquer plano, eu ganho 15 rodadas.',
url: referralUrl,
});
return;
}
await handleCopyReferral();
} catch {
await handleCopyReferral();
}
};
const handlePay = () => {
if (!method) return;
setProcessing(true);
onUpgrade(method, plan);
};
return (
<div className="fixed inset-0 z-50 bg-slate-950 flex items-center justify-center p-4">
{/* ... UI do paywall ... */}
</div>
);
};
Exemplo 2: Upgrade com Stripe (Frontend chamando API serverless)
A Intenção (Prompt de integração segura):
Você é um Senior Fullstack Engineer.
Implemente um fluxo de upgrade:
- Se método for cartão: chamar POST /api/create-checkout-session com { userId, email, plan }
- Validar response.ok, garantir que existe data.url, senão erro
- Redirecionar para Stripe Checkout via window.location.href
- PIX deve ficar desabilitado por segurança (evitar ativação simulada em produção)
- Erros devem exibir mensagem amigável
Critérios de aceite:
- Não redireciona sem URL
- Não "ativa" PIX fake
- Não quebra se localStorage falhar
Resultado (trecho real: Roullete-PRO/App.tsx):
const handleUpgrade = async (method: 'PIX' | 'CREDIT_CARD', plan: 'MONTHLY_100' | 'FULL') => {
if (!user) return;
try {
if (user.subscriptionStatus === 'FREE' && user.credits <= 0) {
try {
localStorage.setItem('rp_resume_needed', '1');
} catch {
// ignore
}
}
// Stripe Checkout (redirect)
if (method === 'CREDIT_CARD') {
const response = await fetch('/api/create-checkout-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: user.id, email: user.email, plan }),
});
const data = await response.json();
if (!response.ok) throw new Error(data?.message ?? 'Falha ao iniciar pagamento');
if (!data?.url) throw new Error('Stripe URL ausente');
window.location.href = data.url;
return;
}
// PIX disabled for now (avoid simulated activation in production)
alert('PIX em breve. Por enquanto, use Cartão de Crédito.');
return;
} catch (e: any) {
alert(e?.message ?? 'Falha ao processar upgrade');
throw e;
}
};
Exemplo 3: Segurança de Produção (API Stripe com bloqueio de chave de teste)
Aqui é onde Vibe Coding vira engenharia de verdade: o prompt pede segurança, e o código devolve proteções que evitam incidentes reais.
A Intenção (Prompt de hardening):
Você é um Backend Engineer focado em segurança.
Crie uma serverless function (Vercel) para Stripe checkout:
- Ler STRIPE_SECRET_KEY de env e falhar rápido se ausente
- Se VERCEL_ENV=production, bloquear sk_test_
- Criar sessão de assinatura com metadata { userId, plan }
- Construir baseUrl usando headers x-forwarded-proto e host
- Validar method POST e retornar 405 para outros métodos
- Retornar 200 com { url } ou 400 com { message } sem stacktrace
Critérios de aceite:
- Nunca usa chave de teste em produção
- Nunca expõe segredo no response
- Validação de body (userId/email)
Resultado (trecho real: Roullete-PRO/api/create-checkout-session.ts):
const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
if (!stripeSecretKey) {
throw new Error('Missing STRIPE_SECRET_KEY');
}
if (process.env.VERCEL_ENV === 'production' && stripeSecretKey.startsWith('sk_test_')) {
throw new Error('Pagamento em produção não configurado (chave Stripe de teste).');
}
const stripe = new Stripe(stripeSecretKey, {
apiVersion: '2025-02-24.acacia',
});
function getBaseUrl(req: VercelRequest) {
const proto = (req.headers['x-forwarded-proto'] as string | undefined) ?? 'https';
const host = req.headers.host;
if (!host) throw new Error('Missing host header');
return `${proto}://${host}`;
}
export default async function handler(req: VercelRequest, res: VercelResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method Not Allowed' });
}
try {
const { userId, email, plan } = req.body as {
userId?: string;
email?: string;
plan?: 'MONTHLY_100' | 'FULL';
};
if (!userId || !email) {
return res.status(400).json({ message: 'Missing userId/email' });
}
// ... cria sessão do Stripe e retorna session.url ...
return res.status(200).json({ url: session.url });
} catch (error: any) {
return res.status(400).json({ message: error?.message ?? 'Unknown error' });
}
}
Exemplo 4: “Créditos” como regra de negócio (Prisma + Serverless)
A Intenção (Prompt de regra de negócio com proteção):
Você é um Backend Engineer.
Crie endpoint POST /api/deduct-credit:
- Recebe userId
- Busca usuário no Prisma
- Se subscriptionStatus='FREE', decrementa créditos em 1
- Retorna userProfile com subscriptionExpiry em timestamp (number|null)
- Retornar 405 para métodos inválidos
- Tratar erros sem vazar detalhes internos
Critérios de aceite:
- Só decrementa se for FREE
- Retorna JSON consistente
- Erros retornam 400 com message
Resultado (trecho real: Roullete-PRO/api/deduct-credit.ts):
const prisma = new PrismaClient();
export default async function handler(req: VercelRequest, res: VercelResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method Not Allowed' });
}
const { userId } = req.body;
try {
const user = await prisma.user.findUnique({ where: { id: userId } });
if (!user) throw new Error("User not found");
let updatedUser = user;
if (user.subscriptionStatus === 'FREE') {
updatedUser = await prisma.user.update({
where: { id: userId },
data: { credits: { decrement: 1 } },
});
}
const userProfile = {
...updatedUser,
subscriptionExpiry: updatedUser.subscriptionExpiry ? updatedUser.subscriptionExpiry.getTime() : null,
};
res.status(200).json(userProfile);
} catch (error: any) {
res.status(400).json({ message: error.message });
}
}
Exemplo 5: Prompt para criação de site (Astro) com SEO e config central
Em site institucional, prompt bom não fala só de UI. Fala de SEO, config central, metadados e disciplina de conteúdo.
A Intenção (Prompt de arquitetura para site):
Você é um Web Architect especializado em Astro.
Crie uma configuração central (SITE_CONFIG):
- name, title, description, url, image
- seo.keywords, author, robots, verificações
- social links (linkedin, github, youtube, twitter)
- schema.org Person com sameAs e knowsAbout
Restrições:
- Tudo centralizado em src/config/site.ts
- O layout deve consumir essa config (sem duplicar strings)
Critérios de aceite:
- Fácil trocar metadados em um único lugar
- SEO pronto (keywords, author, robots)
- Schema.org consistente
Resultado (trecho real: site/src/config/site.ts):
export const SITE_CONFIG = {
name: 'Jacques Belmont',
title: 'Jacques Belmont - Senior Prompt Engineer & AI Agent Developer',
description:
'Specialist in AI Automation, Vibe Coding, and Reverse Prompt Engineering. Architecting autonomous workforces and robust AI systems using Python & LLMs.',
url: '[https://www.jacquesbelmont.com](https://www.jacquesbelmont.com)',
image: '/og-image.jpg',
contact: {
email: '[email protected]',
phone: '+55 (83) 9 9999-9999',
location: 'João Pessoa, Paraíba, Brazil',
linkedin: '[https://linkedin.com/in/jacquesbelmont'](https://linkedin.com/in/jacquesbelmont'),
youtube: '[https://youtube.com/@jacquesbelmont'](https://youtube.com/@jacquesbelmont'),
github: '[https://github.com/jacquesbelmont'](https://github.com/jacquesbelmont'),
twitter: 'https://x.com/belmont_jacques',
},
seo: {
keywords: [
'Prompt Engineer',
'AI Agent Developer',
'Vibe Coding',
'AI Automation',
'Reverse Engineering',
'n8n Specialist',
'LLM Optimization',
'Python Automation',
'Agentes Autônomos',
],
author: 'Jacques Belmont',
robots: 'index, follow',
googleSiteVerification: 'your-google-verification-code',
bingSiteVerification: '4SEU-CODIGO-B44C1E113E12F01E60096',
},
// ... schema.org Person ...
};
Segurança no Vibe Coding: o prompt como firewall
Se você não pede segurança no prompt, você recebe “código que funciona” — até o dia em que não funciona mais. Aqui vai um conjunto de prompts que eu uso para garantir que a IA produza código pronto para produção.
Prompt 1: Anti-vazamento de segredos
Checklist de segurança obrigatório:
- Nunca hardcode API keys, tokens, secrets
- Ler tudo via env (process.env)
- Em caso de erro, retornar mensagem genérica (sem stacktrace, sem config)
- Bloquear execução em produção com credenciais de teste (ex.: Stripe sk_test_)
- Validar method e payload (400/405)
Entregue: implementação + pontos onde posso testar.
Prompt 2: Validação e contratos de API
Implemente validação defensiva:
- Campos obrigatórios
- Tipagem explícita
- Mensagens de erro consistentes
- Sem comportamento implícito perigoso
Critério: nenhuma request malformada causa crash.
Prompt 3: “Produção não aceita gambiarra”
Se existir funcionalidade simulada (ex.: PIX fake), deve ficar desabilitada por default.
Produção = comportamento determinístico e auditável.
Critério: não existe caminho que “ativa” acesso sem pagamento confirmado.
Conclusão
Vibe Coding não é “deixar a IA codar por você”.
É arquitetar intenção, traduzir isso em prompts com critérios de produção e usar o modelo como motor de implementação.
A diferença entre “prompt bonito” e “produto no ar” é: contexto, restrições, segurança e validação. Quando você domina isso, você vira um verdadeiro One-Person Unicorn.