- Inteligência Artificial
O vibe coding democratizou a criação de software. Ferramentas como o Lovable permitem que em poucos minutos você tenha uma aplicação React funcionando, com autenticação, banco de dados e deploy — tudo a partir de prompts em linguagem natural.
A SoftDesign já publicou sobre como usar o Lovable para acelerar o backlog da TI, e os cenários de prototipação e discovery são realmente transformadores.
Mas o que acontece quando você decide que aquele protótipo vai virar produto?
Como Lead Software Engineer, fiz algo que raramente aparece nos artigos sobre vibe coding: abri o código-fonte. Auditei dois projetos reais construídos com Lovable — aplicações corporativas com dezenas de telas, formulários complexos, integrações com Supabase e APIs externas.
O que encontrei conta uma história que todo gestor de TI precisa ouvir antes de decidir colocar código gerado por IA em produção sem supervisão profissional.
O conceito de vibe coding ganhou espaço como uma abordagem inovadora no desenvolvimento de software, fortemente impulsionada pela evolução de ferramentas com Inteligência Artificial.
Em essência, vibe coding é o ato de programar em fluxo com a IA — traduzindo intenções, ideias e comandos em linguagem natural para gerar código funcional de forma colaborativa, rápida e intuitiva.
Na prática, o fluxo de trabalho com vibe coding segue a seguinte lógica:
De acordo com o Gartner, até 2028, 40% dos novos softwares de produção nas empresas serão desenvolvidos com técnicas e ferramentas de vibe coding.
Embora promissor, esse modelo ainda apresenta limitações, o que reforça a importância de uma adoção responsável e apoiada por especialistas. Veja o motivo a seguir.
Recentemente, analisei dois projetos React 18 + Vite + TypeScript + Tailwind CSS construídos no Lovable, ambos com ambição de ir para produção.
Um deles passou por seis fases de iteração na plataforma. O outro integrava Supabase e uma API REST externa simultaneamente.
A auditoria cobriu dez categorias:
O resultado: ambos os projetos ficaram entre 2.0 e 2.5 em uma escala de 5.0. Não apenas em uma ou duas categorias, mas na média geral.
Os padrões de problema se repetiram de forma quase idêntica em ambos os projetos, o que sugere que não se tratam de incidentes isolados, mas de características sistêmicas da ferramenta.
Vamos a eles.
O TypeScript é uma das decisões técnicas mais inteligentes da stack do Lovable. A tipagem estática evita categorias inteiras de bugs em runtime, documenta contratos entre componentes e dá confiança para refatorar.
O problema é que, em ambos os projetos, o TypeScript estava efetivamente desabilitado:
{
"strict": false,
"noImplicitAny": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false
} Ou seja: a linguagem aceita any em qualquer lugar, não avisa sobre variáveis null, e ignora código morto. Encontrei 99 ocorrências de any em um projeto e 68 no outro.
Exemplos como (inspection as any).name revelam que, quando a IA muda a estrutura de dados entre iterações, em vez de atualizar os tipos, ela simplesmente contorna o compilador com um cast.
strict: false, o TypeScript vira um transpilador sofisticado de JavaScript. Você paga o custo de sintaxe de tipos sem ganhar a proteção que eles oferecem. Logo, erros que seriam detectados em tempo de compilação — como acessar uma propriedade que não existe — viram crashes silenciosos em produção.Ao analisar os projetos de vibe coding, a cobertura de testes foi um dos achados mais alarmantes. Os números falam por si:
| Métrica | Projeto A | Projeto B |
| Arquivos de código-fonte | 308 | 193 |
| Arquivos de teste | 7 | 7 |
| Cobertura estimada | ~2% | ~3.6% |
| Páginas com testes | 0 | 0 |
| Formulários com testes | 0 | 0 |
Mas o mais grave não é a quantidade, é que os testes não rodam. Em um dos projetos, o Jest estava na versão 30 com ts-jest na versão 29 (incompatíveis entre si).
Além disso, a configuração usava moduleNameMapping quando a propriedade correta é moduleNameMapper. Um typo que faz os aliases de import falharem silenciosamente.
Em outras palavras: existe uma infraestrutura elaborada de testes — factories, handlers de mock para requisições HTTP, test-utils —, mas ela nunca foi executada com sucesso.
É scaffolding gerado pela IA para parecer que o projeto tem testes, quando na prática não tem nenhum funcional.
Se a seção anterior preocupa, esta deveria tirar o sono de qualquer gestor de TI.
Em um dos projetos, a configuração do ambiente de produção estava com useMockData: true. Isso significa que, ao fazer deploy, a aplicação apresentaria dados falsos — nomes de usuários inventados, projetos fictícios, métricas fabricadas — como se fossem dados reais.
O ServiceFactory, que decide se usa serviços reais ou mockados, segue cegamente essa flag. Em produção.
No mesmo projeto, o AuthService.login() importava a função authenticateUser de um arquivo chamado mockUsers.ts.
A “autenticação” validava credenciais contra dados hardcoded em um array JavaScript. Ou seja, qualquer pessoa com acesso ao código-fonte saberia exatamente quais são os usuários e senhas válidos.
No outro projeto, a URL e a chave pública do Supabase estavam hardcoded diretamente no código TypeScript, apesar de existir um .env com as mesmas variáveis.
Para piorar, o .env não estava no .gitignore — o que significa que credenciais são commitadas no repositório e ficam no histórico do Git permanentemente.
Uma vulnerabilidade funcional chamou atenção: o sistema de permissões mapeava as roles viewer, inspector e admin em uma hierarquia numérica.
Porém, a role technician — que existia nos tipos TypeScript e que era atribuída a usuários — não foi incluída nesse mapeamento. Como technician não estava no mapa, o sistema retornava um nível indefinido, e ao comparar com o nível mínimo exigido, a verificação sempre falhava (em JavaScript, undefined < 1 resulta em false).
Na prática, todos os usuários com role technician eram bloqueados de todas as rotas protegidas, sem mensagem de erro clara. Um bug funcional que afetava usabilidade e que passou despercebido justamente porque não há testes.
Este é talvez o padrão mais curioso do Lovable. Ao receber prompts que pedem “arquitetura robusta” ou “boas práticas”, a IA responde gerando abstrações enterprise-grade que seriam sofisticadas demais até para projetos com equipes grandes.
Em um dos projetos de vibe coding, que opera 100% com dados mockados e ainda não se conectou a um backend real, encontrei:
São aproximadamente 3.500 linhas de código de infraestrutura que não entregam valor ao usuário final. Enquanto isso, os sete arquivos de teste do projeto mal funcionam.
No outro projeto, o sistema de erros definia 12 classes de erro customizadas (ValidationError, NotFoundError, DatabaseError, AuthenticationError, etc.) — mas o ErrorBoundary que deveria capturá-los nunca foi montado em nenhum componente.
717 linhas de infraestrutura de erros que ninguém usa.
O Lovable encoraja iteração rápida: escreva um prompt, veja o resultado, peça ajustes. Isso é excelente para convergir a uma UI desejada. Mas cada iteração adiciona código sem necessariamente limpar o que veio antes.
Um dos projetos tinha seis arquivos README de fases distintas (PHASE-2 até PHASE-6, mais um README-LAYERED-ARCHITECTURE). Cada fase adicionou serviços, hooks, componentes e abstrações — sem que as fases anteriores fossem refatoradas.
O resultado é o que chamo de legado instantâneo: código que tem cara de herança de três anos, mas que foi gerado em semanas.
Sinais práticos desse padrão:
AuthContext, 51 em uma página — resquícios de iterações anteriores que nunca foram limpos.Inspection definido em três arquivos diferentes com campos potencialmente divergentes.as any para contornar mudanças: quando a IA muda a estrutura de dados entre prompts, ela usa type assertions para silenciar o compilador em vez de atualizar todos os consumidores.Além dos grandes temas acima, alguns achados se repetiram em ambos os projetos com consistência quase mecânica:
| Achado | Projeto A | Projeto B |
Lockfiles conflitantes (bun.lockb + package-lock.json) | Sim | Sim |
ESLint com no-unused-vars: off | Sim | Sim |
| Dependências de teste em dependencies (ao invés de devDependencies) | 13 pacotes | 6 pacotes |
| Console.log em código de produção | 79 | 61 |
| Ausência de Prettier | Sim | Sim |
| CI/CD | Zero | Zero |
<html lang="en"> em projeto pt-BR | Sim | — |
| Lazy loading de rotas | Implementado | Zero |
| Arquivos com mais de 200 linhas | 82 | 17+ |
ErrorBoundary não utilizado | — | Sim |
A repetição desses padrões é o dado mais relevante para gestores. Não estamos falando de projetos feitos por desenvolvedores descuidados — estamos falando de características da ferramenta.
Nada do que apresentei aqui é uma condenação ao vibe coding. O Lovable, por exemplo, é uma ferramenta genuinamente impressionante para prototipação, discovery e aceleração de front-end.
Mas existe uma distância real entre um protótipo funcional e um produto de produção. E essa distância não se resolve com mais prompts. Ela se resolve com engenharia.
O que um engenheiro ou equipe de engenharia faz depois que o Lovable gera o código é o que separa um MVP descartável de um produto sustentável:
strict: true, resolver os erros que aparecerem, substituir any por tipos reais. Isso é trabalho humano que exige compreender o domínio de negócio. Uma regra que tenho aplicado nos projetos que acompanho: para cada hora de vibe coding, reserve ao menos uma hora de revisão e refatoração por um profissional.
Nos dois projetos auditados, a refatoração para um nível mínimo de produção exigiu mais horas do que a geração original.
Não é overhead — é hedge contra dívida técnica. É o que garante que a velocidade do prompt de hoje não se transforme no bloqueio técnico do trimestre que vem.
Atualmente, estamos em um momento extraordinário para o desenvolvimento de software.
A capacidade de converter uma ideia em um protótipo funcional em minutos é real e transformadora. Mas a engenharia de software existe por motivos que uma LLM não resolve sozinha: confiabilidade, segurança, manutenibilidade, escalabilidade.
O vibe coding é um acelerador poderoso. Mas um acelerador sem freios e sem direção é um risco, não uma vantagem.
Os dados das auditorias que compartilhei aqui não são exceções — são padrões. E padrões exigem respostas sistemáticas: processos de revisão, profissionais qualificados e uma cultura que valorize a engenharia tanto quanto valoriza a velocidade.
O futuro do desenvolvimento é, sim, AI-Assisted. Mas “assisted” é a palavra-chave. A Inteligência Artificial gera o código; a inteligência humana garante que ele funcione, que seja seguro, e que possa evoluir.
E essa é uma capacidade que toda organização séria precisa construir — ou contratar.
Juntos, aceleramos sua estratégia de Inteligência Artificial com engenharia e governança.
Por fim, confira respostas para dúvidas sobre o assunto.
Em suma, vibe coding é um método de desenvolvimento de software que usa assistentes de IA para encurtar ciclos, promover iterações contínuas e simplificar o processo, permitindo a participação de pessoas com pouco conhecimento em programação.
Não. O vibe coding não substitui desenvolvedores. Mesmo com automação, o pensamento estratégico e a definição da arquitetura de software são essenciais. Além disso, existem tarefas que a IA não cobre totalmente, como planejar todos os tipos de testes.
Os riscos do vibe-coding incluem dependência excessiva da IA, erros por falta de revisão humana e lacunas em planejamento de testes. Além disso, pode resultar em decisões estratégicas de arquitetura mal definidas.
O Lovable é uma plataforma de desenvolvimento com IA que gera aplicações web a partir de prompts em linguagem natural. Nesse sentido, ele automatiza a criação de front-end, integrações e estrutura básica do projeto, sendo usado para prototipação e aceleração inicial do desenvolvimento.
Entre as vantagens estão rapidez, facilidade de uso e ótima prototipação. Entre os riscos: código inconsistente, pouca cobertura de testes, possíveis falhas de segurança e acúmulo de dívida técnica. Em resumo, acelera muito — mas precisa de engenharia para ir à produção.
Leia também: