Todo projeto começa limpo. Aí chega a pressa, o "depois eu arrumo", e seis meses depois ninguém acha onde mora a regra de negócio — nem quem escreveu.

A pasta conta uma história (ou devia)

Abra a raiz de um projeto e você já devia sacar do que ele trata só pela estrutura. Se as pastas de topo são utils, helpers, services e components, você não aprendeu nada sobre o domínio — aprendeu sobre o framework, que é a parte que menos importa.
Prefira uma estrutura que reflete o negócio: checkout, faturamento, catalogo, usuarios. A camada técnica é detalhe dentro de cada uma. Um dev novo tem que conseguir apontar "a regra de desconto tá aqui" sem abrir dez arquivos pra descobrir.
Separação de responsabilidades sem terrorismo
Separação de responsabilidades virou desculpa pra criar dez camadas e um monte de interface que ninguém entende. Não é isso. É simples: cada pedaço de código tem um motivo pra existir e, de preferência, um único motivo pra mudar.
O teste prático é o commit. Se mexer numa regra de preço te obriga a editar o componente de UI, o controller, um util e um enum, essas coisas não estão separadas — estão espalhadas, que é o oposto. Junte o que muda junto e isole o que muda por razões diferentes.
Nome bom é o que você não precisa explicar
Nome revela intenção. processData() não diz nada — processa o quê, pra quê? calcularFrete() já conta a história inteira antes de você abrir o corpo da função.
Não economize letra. usr, tmp, d, flag2 custam caro toda vez que alguém relê — e código é lido muito mais do que é escrito. Se você precisa de um comentário pra explicar o que uma variável guarda, o nome dela já falhou. Gaste os segundos a mais escrevendo pedidosPendentes em vez de arr.
Arquivo grande é dívida escondida
Arquivo de 800 linhas quase nunca faz uma coisa só. Ele começou fazendo, foi crescendo, e virou depósito de "não sei onde botar, então põe aqui".
Quebre por responsabilidade, não por número mágico de linhas. A régua boa é cognitiva: um arquivo devia caber na sua cabeça. Você abre, entende o que ele faz e some de lá sem rolar três telas nem segurar cinco conceitos na memória ao mesmo tempo. Quando você hesita pra nomear o arquivo porque ele faz "várias coisas", esse é o sinal de que são dois.
Colocalização vence camada na maioria dos casos

Regra que resolve 80% dos casos: coloque junto o que muda junto. O teste do lado do código que ele testa, o estilo do lado do componente, o hook perto de quem consome.
Separar tudo por tipo técnico — um /tests gigante, um /styles gigante, um /hooks gigante — parece organizado numa screenshot, mas na prática te obriga a abrir quatro pastas distantes pra entender uma feature só. E quando você deleta a feature, sobra lixo espalhado em todas elas. Colocalização também facilita a parte mais honesta de todas: apagar.
README não é enfeite
Um README que diz como rodar, como testar e onde moram as decisões importantes economiza horas de cada pessoa nova — e de você mesmo daqui a três meses, quando esquecer.
Mas atenção: doc que mente é pior que doc que falta, porque você confia e toma decisão errada. A regra é tratar documentação como código: se você mudou o comando de build, muda o README no mesmo commit. Doc que vive longe do código sempre apodrece.
Organização de código não é firula estética nem TOC de quem gosta de pasta alinhada. É o time achando as coisas rápido e mudando o sistema sem medo. Você não precisa refatorar o mundo hoje — só deixar o próximo arquivo que tocar um pouco mais óbvio que estava.


