---
title: "Roda Reinventada"
type: "ai-smell"
slug: "reinvented-wheel"
url: "http://localhost:3000/pt-br/ai-smells/reinvented-wheel.md"
category: "Estrutura"
description: "O modelo escreve à mão código sob medida para algo que uma biblioteca padrão, uma dependência existente ou um helper já presente no repositório já faz — adicionando lógica duplicada e menos testada em vez de chamar o que já existe."
---
# Roda Reinventada

> O modelo escreve à mão código sob medida para algo que uma biblioteca padrão, uma dependência existente ou um helper já presente no repositório já faz — adicionando lógica duplicada e menos testada em vez de chamar o que já existe.

## Signs and Symptoms

Um revisor identifica a Roda Reinventada quando um diff introduz um trecho não trivial de lógica "do zero" para resolver um problema que já está resolvido — pelo runtime da linguagem, por uma dependência já presente em `package.json` ou por um utilitário que já existe em outro lugar do repositório. Sinais comuns:

* Um `deepClone`, `debounce`, `groupBy`, `chunk`, `retry`, `slugify`, `deepMerge` ou `uuid` escrito à mão quando o runtime ou uma biblioteca instalada já o fornece.
* Uma **regex** sob medida de e-mail/URL/UUID em vez de um validador que já é uma dependência.
* Cálculos de data personalizados, parsing de query-string ou lógica de paginação que reimplementam `Intl`/`URLSearchParams`/um recurso de ORM.
* Dois ou três helpers privados quase idênticos espalhados por arquivos (a mesma roda re-esculpida por funcionalidade) — a duplicação que aparece nas métricas de copiar/colar.
* A versão reinventada está sutilmente **errada**: ela trata o caminho feliz, mas deixa passar casos extremos que o original testado em batalha cobre.

```ts
// Escrito por IA: um deep clone sob medida reinventado inline
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);
  const out = {};
  for (const k in obj) out[k] = deepClone(obj[k]);
  return out; // descarta silenciosamente Date, Map, Set, RegExp; entra em loop em ciclos
}
// ...mesmo que o runtime já forneça structuredClone(), E
// o repositório já exporta cloneDeep() de src/utils/object.ts

```

A verificação mais rápida: procure no repositório e em `node_modules` pela capacidade antes de aceitar o novo código. Se `structuredClone`, `lodash`, `date-fns` ou um helper local já o cobre, a nova função é uma roda reinventada.

## Reasons for the Problem

**Por que os modelos produzem isso**

* **Sem contexto do repositório por padrão.** O modelo muitas vezes não consegue ver seu `src/utils`, suas dependências instaladas ou as convenções da casa, então recorre à conclusão estatisticamente mais provável: uma implementação inline autocontida. Ele reconstrói a roda porque nunca viu a sua.
* **Localidade do próximo token.** LLMs otimizam para uma continuação localmente plausível, não para a minimalidade global. Escrever `function groupBy(...)` é uma sequência de alta probabilidade; parar para descobrir que `lodash.groupBy` já está importado a três arquivos de distância não é algo que a previsão de tokens faça.
* **Os incentivos de treinamento recompensam a autossuficiência.** Uma enorme parcela dos dados de treinamento são tutoriais, respostas do Stack Overflow e trechos que deliberadamente mostram a implementação completa. O modelo aprendeu que "responder bem" significa emitir código completo e autônomo — exatamente o instinto errado dentro de uma base de código madura.
* **Defasagem do corte de treinamento.** O modelo pode não saber que uma capacidade foi promovida à biblioteca padrão (por exemplo, `structuredClone`, `Array.prototype.at`, `Object.groupBy`) ou que seu repositório adotou um helper após seu corte, então ele faz polyfill de algo que já existe.
* **Bajulação / menor resistência.** Solicitado a "adicionar X," o modelo adiciona X da maneira mais direta em vez de contestar com "nós já temos isso." Ele raramente sugere espontaneamente "você não precisa escrever isso."
* **Superespecificação.** A análise da OX Security de mais de 300 repositórios constatou que a IA tende a um estilo de código "vanilla" que reconstrói funcionalidades comuns em vez de usar bibliotecas comprovadas, com soluções de escopo restrito e não reutilizáveis em cerca de 80–90% dos casos — cada nova variação ganha código novo em vez de reutilização.

**Por que isso é prejudicial**

* **Manutenibilidade e dívida técnica.** Esta é a face mensurável do declínio na qualidade do código de IA. A análise da GitClear sobre 211 milhões de linhas constatou que o código copiado/colado subiu de 8,3% (2020) para 12,3% (2024), os blocos de 5+ linhas duplicadas cresceram \~8x em 2024, e as linhas "movidas" (refatoradas) caíram de 24,1% para 9,5% — 2024 foi o primeiro ano em que o copiar/colar superou a refatoração. As rodas reinventadas são por onde essa duplicação entra.
* **Correção.** A versão sob medida pula os casos extremos que a implementação madura conquistou ao longo de anos de relatórios de bugs (fusos horários, Unicode, ciclos, escape). Parece certa e falha na cauda longa.
* **Segurança.** Reescrever criptografia, autenticação, sanitização ou validação em vez de usar uma biblioteca confiável é como o código escrito por IA "viola as melhores práticas de engenharia" em escala (o efeito "Exército de Juniores" da OX) — padrões vulneráveis chegam à produção mais rápido do que a revisão consegue detectá-los.
* **Carga de revisão.** Os revisores agora precisam ler, raciocinar sobre e testar 40 linhas de lógica personalizada em vez de reconhecer uma única chamada de biblioteca confiável — multiplicado em cada PR.

## Treatment

**Táticas de revisão e de prompting**

* **Dê ao modelo o contexto que lhe falta.** Antes de gerar, aponte-o para seus utilitários e dependências: "Reutilize helpers de `src/utils/*` e bibliotecas já presentes em `package.json`; não adicione novas sem perguntar." Cole as dependências relevantes do `package.json` e o índice dos seus utils.
* **Faça do "buscar primeiro" uma regra.** Instrua: "Antes de escrever qualquer helper, verifique se a biblioteca padrão, uma dependência existente ou um utilitário do repositório já faz isso; em caso afirmativo, chame-o." Ferramentas agênticas devem fazer grep no repositório primeiro.
* **Questione cada novo helper privado na revisão.** Para cada utilitário feito à mão pergunte: o runtime faz isso? uma dependência faz isso? nós já temos isso? Se sim, é Roda Reinventada — substitua-a.
* **Execute a toolchain.** Um scanner de duplicação (jscpd / PMD CPD / SonarQube) na CI sinaliza a faceta de copiar/colar automaticamente; conecte-o ao portão para que rodas re-esculpidas façam o build falhar.

**A refatoração** — isto é o clássico **Código Duplicado** e **Reinventar a Roda**; a correção é **Substituir Algoritmo** (trocar o corpo sob medida pela chamada da biblioteca/padrão) e, onde existem várias cópias, **Extrair Função** / subir para um único helper compartilhado.

```ts
// ANTES — reinventado, parcialmente correto, duplicado por funcionalidade
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);
  const out = {};
  for (const k in obj) out[k] = deepClone(obj[k]);
  return out;
}
const copy = deepClone(state);

```

```ts
// DEPOIS — chame o que já existe (casos extremos corretos, zero código novo)
const copy = structuredClone(state);
// ou, se o padrão do repositório for o helper local:
import { cloneDeep } from "@/utils/object";
const copy = cloneDeep(state);

```

Se a roda foi reinventada em vários arquivos, apague todas as cópias e direcione cada chamador para a única fonte de verdade. Resultado líquido: menos linhas, menos bugs e as métricas de duplicação voltam na direção certa.

## Detected by

- **jscpd** `duplication` — Detecção de copiar/colar (min-tokens / limite) (https://github.com/kucherenko/jscpd)
- **PMD** `cpd` — CPD (Copy/Paste Detector) (https://docs.pmd-code.org/latest/pmd_userdocs_cpd.html)
- **SonarQube** `common-duplications` — Blocos duplicados / duplicated_lines_density (https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/test-coverage/duplications/)
