JavaScript fora do navegador
Durante anos, o JavaScript só vivia dentro do navegador. O Node.js mudou isso: é um ambiente de execução que permite rodar JavaScript na sua máquina ou em um servidor, assim como você rodaria Python ou Java.
Por dentro, o Node usa o V8, o mesmo motor de JavaScript do Chrome. O V8 compila seu código para instruções de máquina muito rápidas. Ao V8 falta tudo o que não é a linguagem em si (ler arquivos, abrir conexões de rede...): isso é fornecido pelo Node, que adiciona um conjunto de APIs próprias.
O navegador não está aqui
Como não há navegador, não existem window, document nem o DOM. No seu
lugar, o Node oferece seus próprios objetos globais:
console.log(process.version); // versão do Node, p. ex. "v20.11.0"
console.log(process.platform); // "linux", "darwin", "win32"...
globalThis.meuDado = 42; // 'global' / 'globalThis' em vez de 'window'
process: informação e controle do processo (argumentos, variáveis de ambiente, saída...).global/globalThis: o objeto global (o equivalente awindow).
O modelo não bloqueante
O Node executa seu JavaScript em uma única thread. Isso parece limitante, mas é a chave do seu desempenho graças a um detalhe: o I/O é assíncrono.
Quando você pede algo lento (ler um arquivo, uma consulta ao banco de dados, uma requisição de rede), o Node não fica esperando (não bloqueia a thread): ele delega essa operação, segue atendendo outras coisas e, quando o resultado está pronto, executa seu código de continuação. Esse mecanismo é o event loop: um laço que vai tirando tarefas terminadas de uma fila e executando seus callbacks.
console.log("1: começo");
setTimeout(() => console.log("3: tarefa adiada"), 0);
console.log("2: sigo sem esperar");
// Imprime: 1, 2, 3 -> o setTimeout não bloqueia; é executado "depois"
Por isso um único servidor Node pode atender milhares de conexões ao mesmo tempo: enquanto uma espera pelo disco ou pela rede, a thread está livre para atender as demais. A regra de ouro: nunca bloqueie o event loop com trabalho síncrono pesado, ou todas as requisições ficarão congeladas.
Exemplos
O event loop não espera: a ordem não é a do código
console.log("A");
setTimeout(() => console.log("C (adiado)"), 0);
Promise.resolve().then(() => console.log("B (microtarefa)"));
console.log("D");
// Ordem: A, D, B, C