O browser entende JavaScript, mas browsers diferentes além de versões diferentes de cada browser suportam features diferentes do JavaScript.
Para verificar o nível de suporte de uma feature, normalmente usamos o site caniuse.com. Por exemplo, suporte para Array.prototype.map é bem grande enquanto suporte para Native Filesystem API é pequeno ainda.
Além disso, com bibliotecas como React e Vue, a gente escreve código que o browser não entende nativamente. E se adicionarmos TypeScript no meio, daí que complica mesmo, porque o browser não sabe interpretá-lo.
Para suportar os casos acima e outros mais, normalmente usamos ferramentas de compilação ou transpilação. Muitas vezes falamos de compilação quando estamos falando de transpilação, então não precisa focar na diferença, mas existe.
Ferramentas de compilação transformam código que não está em "JavaScript puro" (TypeScript, JSX (React) e etc) em código que o browser consegue entender. Ferramentas de transpilação transformam código não suportado por um browser ou versão de browser específica em código que o browser consegue entender.
Ferramentas nessa "categoria": tsc (TypeScript Compiler), Babel, esbuild, swc. É possível configurar quais são os targets desses compiladores, por exemplo: "as últimas 3 versões dos browsers" ou "até Internet Explorer 11". Essa configuração é normalmente feita usando browserlist. Compare "últimas 3 versões" e "Internet Explorer 11".
O código resultante de ferramentas de compilação é bem diferente daquele que escrevemos. O compilador compila o código de uma forma "segura" que o browser com certeza vai entender. Além disso, faz várias otimizações que dificultam a leitura do código final.
Exemplo de compilação do Babel: repl.