Node.js és l'entorn que va permetre que JavaScript sortís del navegador i es convertís en un llenguatge de servidor de primer nivell. Abans d'escriure ni una sola línia de codi convé entendre quin problema resol, perquè Node.js no és «un llenguatge més»: és una manera concreta de gestionar la concurrència que explica gairebé totes les seves virtuts i tots els seus defectes. Si comprens el seu model d'entrada/sortida no bloquejant, la resta del curs deixa de ser un recull de receptes i passa a ser una conseqüència lògica.

En aquesta lliçó construirem aquesta base conceptual. Farem servir com a excusa el projecte que ens acompanyarà durant tot el curs: Escena Viva, una petita empresa que ven entrades per a esdeveniments culturals del Teatro Almendra, la Sala Bóveda i l'Auditorio Ribera.

Contingut

  1. Què és Node.js i quin problema resol
  2. JavaScript fora del navegador
  3. Les peces conceptuals: V8 i libuv
  4. El model d'E/S no bloquejant: l'analogia del cambrer
  5. Comparació amb el model d'un fil per petició
  6. Per a què és bo Node.js (i per a què no)
  7. L'ecosistema npm i «JavaScript a tot arreu»
  8. Versions LTS i ritme de publicació
  9. Per què Escena Viva encaixa amb Node.js

  1. Què és Node.js i quin problema resol

Node.js és un entorn d'execució (runtime) de JavaScript del costat del servidor. Dit de manera més precisa: és un programa que pots instal·lar a l'ordinador o en un servidor i que sap llegir fitxers .js i executar-los, donant-los accés al sistema operatiu: fitxers, xarxa, processos, variables d'entorn.

No és un llenguatge. No és un framework. És l'intèrpret més les biblioteques que l'envolten.

El problema històric que va venir a resoldre va ser el de la concurrència en servidors web. A finals dels 2000, els servidors tradicionals atenien cada petició amb un fil del sistema operatiu dedicat. Un fil consumeix memòria (típicament entre centenars de KB i uns quants MB de pila) i canviar d'un fil a un altre té un cost. Amb milers de connexions simultànies —moltes d'elles simplement esperant que respongui una base de dades o que el client acabi de descarregar— el servidor gastava la major part dels seus recursos a gestionar fils ociosos.

Aquest problema té nom propi: el problema C10K (atendre deu mil connexions concurrents en una sola màquina). La resposta de Node.js va ser radical: un sol fil per al teu codi, i totes les operacions d'entrada/sortida en mode asíncron.

Idea central que has de retenir: a Node.js, el teu codi no es queda mai quiet esperant que acabi una operació lenta. Demana l'operació, continua treballant en una altra cosa i, quan el resultat és a punt, hi torna.

  1. JavaScript fora del navegador

Fins al 2009, JavaScript era pràcticament sinònim de «el llenguatge de les pàgines web». Ryan Dahl va agafar el motor V8 de Google Chrome —que ja era molt ràpid— i el va empaquetar amb una biblioteca d'entrada/sortida asíncrona. El resultat va ser Node.js.

En treure JavaScript del navegador canvien les eines disponibles:

Concepte Al navegador A Node.js
Objecte global window (o globalThis) global (o globalThis)
Interfície d'usuari document, DOM, esdeveniments de ratolí No existeix: no hi ha DOM
Emmagatzematge localStorage, IndexedDB Sistema de fitxers, bases de dades
Xarxa fetch, XMLHttpRequest (amb CORS) fetch, mòduls http/https, sòcols TCP, sense CORS
Accés a fitxers Restringit i amb permís de l'usuari Complet (mòdul fs)
Procés i entorn No accessible process.argv, process.env, process.exit()
Model de seguretat Caixa de sorra (sandbox) del navegador Els permisos de l'usuari del sistema

Aquesta última fila és important: al navegador, JavaScript viu tancat per seguretat. A Node.js, el teu script pot esborrar fitxers, obrir ports i llançar processos. Amb aquesta potència arriba la responsabilitat de no executar codi en què no confies.

Veurem les diferències a la pràctica a la lliçó El Teu Primer Programa en Node.js.

  1. Les peces conceptuals: V8 i libuv

Node.js es recolza sobre dos components principals. Aquí els presentem a nivell conceptual; l'arquitectura detallada i el bucle d'esdeveniments amb les seves fases s'estudien al Mòdul 2.

V8: el motor de JavaScript

V8 és el motor de JavaScript desenvolupat per Google. La seva feina és:

  • Analitzar (parsejar) el teu codi JavaScript.
  • Compilar-lo a codi màquina mitjançant compilació just-in-time, optimitzant les funcions que més s'executen.
  • Gestionar la memòria amb un recol·lector d'escombraries automàtic.

Gràcies a V8, JavaScript a Node.js no és «un llenguatge interpretat lent»: per a moltes tasques està a l'altura de llenguatges compilats amb màquina virtual.

libuv: la biblioteca d'E/S asíncrona

V8 sap executar JavaScript, però no sap llegir fitxers ni obrir sòcols. D'això se n'encarrega libuv, una biblioteca escrita en C que ofereix:

  • Una interfície uniforme sobre els mecanismes d'E/S asíncrona de cada sistema operatiu (epoll a Linux, kqueue a macOS/BSD, IOCP a Windows).
  • El bucle d'esdeveniments (event loop), que és el motor que reparteix la feina.
  • Un pool de fils intern per a les operacions que el sistema operatiu no sap fer de manera asíncrona (bona part de l'accés a fitxers, compressió, criptografia).
flowchart TB
    A["El teu codi JavaScript<br/>(src/cataleg.js)"] --> B["Node.js<br/>APIs: fs, http, path..."]
    B --> C["V8<br/>Executa JavaScript"]
    B --> D["libuv<br/>Bucle d'esdeveniments + pool de fils"]
    D --> E["Sistema operatiu<br/>Fitxers, xarxa, temporitzadors"]
    C --> D

Una precisió que evita malentesos freqüents: quan es diu que «Node.js és d'un sol fil» es parla del fil on s'executa el teu JavaScript. Per sota, libuv fa servir diversos fils. El que no passa és que dues línies del teu codi s'executin alhora.

  1. El model d'E/S no bloquejant: l'analogia del cambrer

Aquesta analogia és la millor manera d'interioritzar el model. Imagina't el restaurant del Teatro Almendra una nit d'estrena.

Model bloquejant: un cambrer per taula

En un restaurant tradicional, cada taula té el seu cambrer assignat. El cambrer:

  1. Pren la comanda de la taula 1.
  2. La porta a cuina.
  3. Es queda dret a la cuina esperant que el plat estigui llest.
  4. El porta a la taula 1.
  5. Només llavors atén una altra taula.

Per atendre 50 taules necessites 50 cambrers. La major part del temps estan aturats esperant la cuina. Contractar cambrers és car i el passadís de la cuina s'omple de gent que no fa res.

Model no bloquejant: un cambrer molt organitzat

Ara imagina't un únic cambrer excepcionalment eficient:

  1. Pren la comanda de la taula 1 i la deixa a cuina.
  2. No espera: va a la taula 2 i pren la seva comanda.
  3. Va a la taula 3, serveix les begudes de la 4, cobra a la 5...
  4. Quan la cuina toca la campana («comanda de la taula 1 llesta!»), el cambrer recull el plat i el serveix.

Un sol cambrer atén desenes de taules, perquè la feina lenta no la fa ell: la fa la cuina. Ell només coordina.

Traducció a Node.js:

Restaurant Node.js
El cambrer El fil principal on corre el teu JavaScript
Les taules Les peticions dels clients
La cuina El sistema operatiu, la base de dades, la xarxa, el disc
La campana de la cuina L'esdeveniment d'«operació completada»
La llibreta de comandes pendents La cua d'esdeveniments del bucle
El cambrer cuinant ell mateix un guisat de 3 hores Un càlcul intensiu de CPU que bloqueja tot

Aquest últim punt és la clau de les limitacions de Node.js: mentre el cambrer cuina, ningú no atén les taules. Hi tornarem a l'apartat 6.

Com es veu això en codi

Fixa't en la diferència conceptual (no cal que n'entenguis encara cada detall; només és il·lustratiu):

// Estil BLOQUEJANT (síncron): el programa s'atura a cada línia.
const fs = require('node:fs');

const cataleg = fs.readFileSync('dades/esdeveniments.json', 'utf8'); // Espera aqui
console.log('Cataleg carregat');
console.log("Aquesta linia s'executa despres de llegir el fitxer");
// Estil NO BLOQUEJANT (asincron): el programa continua i hi torna despres.
const fs = require('node:fs');

fs.readFile('dades/esdeveniments.json', 'utf8', (error, cataleg) => {
  // Aquesta funcio s'executa QUAN el fitxer esta llest
  console.log('Cataleg carregat');
});

console.log("Aquesta linia s'executa ABANS que el fitxer acabi de llegir-se");

En el segon cas, la sortida per consola apareix en ordre «invers» al que suggereix la lectura del fitxer. Això desconcerta al principi i és exactament el que explorarem a fons a Callbacks i Programació Asíncrona.

  1. Comparació amb el model d'un fil per petició

Compararem Node.js amb el model clàssic que fan servir (o feien servir) PHP amb Apache o Java amb servlets tradicionals.

Aspecte Un fil/procés per petició (PHP clàssic, Java tradicional) Node.js (bucle d'esdeveniments)
Unitat de concurrència Fil o procés del sistema operatiu Callback / promesa en un únic fil
Cost per connexió ociosa Alt (memòria de pila del fil, ~1 MB o més) Molt baix (uns pocs KB d'estructures)
Connexions simultànies viables Centenars o pocs milers per màquina Desenes de milers per màquina
Model mental del programador Senzill: el codi es llegeix de dalt a baix Requereix pensar en asincronia
Estat compartit en memòria Requereix sincronització (panys, seccions crítiques) Sense condicions de cursa dins d'un callback
Càlcul intensiu de CPU Es reparteix entre fils i nuclis Bloqueja tots els usuaris
Error no controlat Sol afectar només una petició Pot tombar tot el procés si no es gestiona
Aprofitament de diversos nuclis Automàtic Requereix cluster o diversos processos (Mòdul 10)

No hi ha un model «millor». Hi ha un model adequat a un perfil de càrrega. Node.js brilla quan el servidor passa la major part del temps esperant altres sistemes, que és justament el que fa una API web moderna.

sequenceDiagram
    participant C1 as Client A
    participant C2 as Client B
    participant N as Node.js (1 fil)
    participant BD as Base de dades

    C1->>N: GET /esdeveniments
    N->>BD: consulta esdeveniments
    Note over N: No espera: queda lliure
    C2->>N: GET /sessions
    N->>BD: consulta sessions
    BD-->>N: resultat esdeveniments
    N-->>C1: resposta A
    BD-->>N: resultat sessions
    N-->>C2: resposta B

  1. Per a què és bo Node.js (i per a què no)

Casos on Node.js encaixa molt bé

  • APIs REST i microserveis: la feina consisteix a rebre una petició, consultar una base de dades i retornar JSON. És E/S gairebé pura, i JSON és el format natiu de JavaScript.
  • Aplicacions en temps real: xats, notificacions, panells en directe, seguiment d'aforament. Milers de connexions obertes gairebé sempre ocioses: l'escenari ideal.
  • Eines de línia d'ordres (CLI): arrencada ràpida, ecosistema enorme, fàcil de distribuir amb npm. Bona part de l'utillatge del desenvolupament web modern està escrit en Node.
  • BFF (Backend For Frontend): una capa fina que agrega crides a diversos serveis interns i compon la resposta que necessita exactament una interfície. La seva feina és esperar diverses APIs alhora: perfecte per a Node.
  • Streaming de dades: processar fitxers grans o fluxos continus sense carregar-los sencers en memòria (Mòdul 3).
  • Prototipatge i equips full-stack: el mateix llenguatge i les mateixes validacions al client i al servidor.

Casos on Node.js no és la millor opció

  • Càlcul intensiu de CPU: processament de vídeo, entrenament de models, càlcul científic, criptografia massiva, generació d'informes amb milions de files en memòria. Mentre la teva funció calcula, el «cambrer» està cuinant i ningú no atén les taules.
  • Aplicacions amb requisits estrictes de tipatge i concurrència complexa de memòria compartida, on altres ecosistemes ofereixen eines més madures.
  • Tasques que exigeixen precisió numèrica decimal, com la comptabilitat amb decimals: el tipus number de JavaScript és de coma flotant. (Per això, a Escena Viva, desarem els preus en cèntims com a enters; ho formalitzarem a la lliçó El Projecte del Curs).

Important: «no és la millor opció» no vol dir «impossible». El Mòdul 10 mostra com treure el càlcul pesant del fil principal amb worker threads, com repartir càrrega entre nuclis amb cluster i com diferir feina a cues amb Redis. La limitació existeix, però té solucions conegudes.

  1. L'ecosistema npm i «JavaScript a tot arreu»

Juntament amb Node.js s'instal·la npm (Node Package Manager), el registre de paquets més gran del món, amb milions de biblioteques publicades. Això té dues cares.

La cara bona: gairebé qualsevol problema comú ja està resolt. Necessites un framework web? Express. Validar dades? Zod o Joi. Parlar amb MongoDB? Mongoose. Generar el PDF d'una entrada? Hi ha mitja dotzena d'opcions.

La cara a vigilar: instal·lar un paquet és incorporar codi de tercers al teu producte. La gestió de dependències, el versionat semàntic i les auditories de seguretat formen part de l'ofici, i hi dediquem el Mòdul 5 sencer.

A més, «JavaScript a tot arreu» vol dir que el mateix llenguatge serveix per al navegador, el servidor, eines de compilació, aplicacions d'escriptori (Electron) i funcions sense servidor. Per a un equip petit com el d'Escena Viva, això redueix el cost de canviar de context: la persona que valida un formulari al navegador pot reutilitzar aquesta mateixa funció de validació a l'API.

  1. Versions LTS i ritme de publicació

Node.js segueix un calendari de publicació molt predictible. Conèixer-lo evita disgustos en producció.

  • Cada abril surt una versió major de número parell (20, 22, 24, 26...).
  • Cada octubre surt una versió major de número senar (21, 23, 25...).
  • Només les versions parelles passen a LTS (Long Term Support, suport a llarg termini), l'octubre de l'any en què van sortir.
  • Les senars són de vida curta (uns sis mesos) i serveixen per provar novetats.

Cicle de vida d'una versió parell:

Fase Durada aproximada Què rep Es pot fer servir en producció?
Current 6 mesos (abril → octubre) Totes les novetats Només per experimentar
Active LTS 12 mesos Correccions i millores segures Sí, recomanat
Maintenance LTS 12 mesos Només correccions crítiques i de seguretat Sí, però planifica el salt
End of Life — Res No, sense pedaços de seguretat

La regla pràctica per a un projecte real és simple: fes servir sempre l'última versió Active LTS i planifica l'actualització quan la teva entri en Maintenance. Per a Escena Viva farem servir una versió LTS i la fixarem al projecte perquè tot l'equip treballi igual.

Com instal·lar i canviar de versió és exactament el tema de la lliçó següent, Instal·lació i Configuració de l'Entorn.

  1. Per què Escena Viva encaixa amb Node.js

Escena Viva ven entrades per a esdeveniments com el Concierto de Otoño (Teatro Almendra), la Noche de Monólogos (Sala Bóveda) i el Festival de Jazz de Primavera (Auditorio Ribera). Analitzem-ne la càrrega de treball:

Necessitat del negoci Perfil de feina Encaixa amb Node.js?
Catàleg públic d'esdeveniments i sessions Llegir de base de dades i retornar JSON Sí: E/S pura
Aforament disponible en temps real durant una venda anticipada Milers de connexions obertes i ocioses Sí: és el cas estrella
Pics de trànsit en obrir la venda d'un festival Alta concurrència, poca CPU per petició Sí
Confirmació de comanda amb passarel·la de pagament externa Esperar resposta d'una altra API Sí
Enviament de correus amb l'entrada E/S de xarxa, es pot diferir a una cua Sí (Mòdul 10)
Generar 50.000 PDF d'entrades de cop CPU intensiva No al fil principal: worker threads o cua
Informe mensual de vendes en CSV Fitxer gran Sí, amb streams (Mòdul 3)

De set necessitats, sis són E/S. Aquesta proporció —molt habitual en aplicacions de negoci— és la raó per la qual Node.js és una elecció assenyada per a aquesta plataforma. I l'excepció (els PDF) té una solució coneguda dins del mateix ecosistema.

Aquest és l'aspecte que tindrà, d'aquí a uns quants mòduls, el punt d'entrada de la nostra API. No cal que l'entenguis ara; observa'l simplement com a destinació:

// Fragment illustratiu: NO l'escriguis encara.
// Un servidor minim que respon amb el cataleg d'Escena Viva.
const http = require('node:http');

const servidor = http.createServer((peticio, resposta) => {
  resposta.writeHead(200, { 'Content-Type': 'application/json' });
  resposta.end(JSON.stringify({ missatge: 'Benvingut a Escena Viva' }));
});

servidor.listen(3000);

Són vuit línies per tenir un servidor HTTP funcionant, sense instal·lar res més. Aquesta economia de mitjans també forma part de l'atractiu de Node.js.

Errors Comuns i Consells

Error 1: creure que «un sol fil» vol dir «lent» o «no aprofita el maquinari». Un procés de Node.js amb un sol fil pot atendre més connexions concurrents que un servidor tradicional amb centenars de fils, perquè gairebé cap no consumeix CPU. I per aprofitar diversos nuclis existeix cluster (Mòdul 10): es llancen tants processos Node com nuclis.

Error 2: confondre «asíncron» amb «paral·lel». Asíncron vol dir «no espero aquí, ja m'avisaran quan estigui». Paral·lel vol dir «dues coses passant al mateix temps». Node.js fa molt el primer i, per al teu codi JavaScript, gens del segon.

Error 3: pensar que Node.js és un framework web. Node.js serveix per escriure servidors web, però també CLIs, scripts d'automatització, processadors de fitxers o robots d'integració. Express (Mòdul 6) és el framework; Node.js és la plataforma.

Error 4: triar una versió senar per a un projecte seriós. Les versions senars es queden sense suport en pocs mesos. Si el número major és senar, no la portis a producció.

Consell 1: pensa sempre en «qui espera». Davant de qualsevol operació, pregunta't si l'espera la fa el teu codi (malament) o el sistema operatiu (bé). Aquesta pregunta t'acompanyarà tot el curs.

Consell 2: mesura abans de descartar. «Node.js no serveix per a càlcul» és cert a partir de certa escala. Una operació de 2 ms no bloqueja res apreciable; una de 800 ms sí.

Consell 3: no memoritzis APIs, entén el model. Les funcions de fs o de http estan documentades i sempre les pots consultar. El model d'execució, en canvi, l'has de portar al cap.

Exercicis

Exercici 1: classificar càrregues de treball

Per a cadascuna d'aquestes funcionalitats hipotètiques d'Escena Viva, indica si és intensiva en E/S o intensiva en CPU, i si Node.js és una bona elecció per resoldre-la al fil principal:

  1. Consultar les entrades disponibles del Concierto de Otoño a la base de dades.
  2. Comprimir en un ZIP els 40.000 passis del Festival de Jazz de Primavera.
  3. Mantenir oberta una connexió amb cada navegador per avisar quan queden menys de 20 entrades.
  4. Calcular l'assignació òptima de butaques per a un grup de 15 persones a l'Auditorio Ribera provant totes les combinacions.
  5. Cridar la passarel·la de pagament per confirmar un cobrament.

Exercici 2: explicar l'analogia amb les teves paraules

Escriu un paràgraf de 5-8 línies explicant a un company que només coneix PHP per què un únic procés de Node.js pot atendre 10.000 connexions simultànies mentre que el seu servidor Apache se satura a les 300. Has de fer servir l'analogia del cambrer i esmentar explícitament on es fa la feina lenta en cada cas.

Exercici 3: decidir una versió

Estàs arrencant Escena Viva l'agost del 2026. Consultant el calendari de publicació de Node.js:

  1. Quina línia de versions triaries i per què?
  2. Què passarà amb aquesta versió aproximadament d'aquí a un any?
  3. Quin inconvenient tindria triar la versió Current acabada de publicar?

Solucions

Solució 1

# Funcionalitat Tipus Node.js al fil principal?
1 Consultar disponibilitat E/S Sí. La feina la fa la base de dades; Node només espera el resultat.
2 Comprimir 40.000 passis CPU No. Bloquejaria tots els usuaris durant segons o minuts. Es resol amb worker threads o una cua de treballs (Mòdul 10).
3 Connexions obertes per a avisos E/S Sí, i és el cas on Node.js més destaca: milers de connexions ocioses costen molt poc.
4 Combinacions de butaques per força bruta CPU No, si el nombre de combinacions és gran. Convé un algorisme millor o treure-ho a un worker.
5 Crida a la passarel·la de pagament E/S Sí. És esperar per la xarxa, exactament per al que serveix el model asíncron.

Matís: el punt 4 depèn de la mida. Si «totes les combinacions» són unes poques desenes, el càlcul triga microsegons i no hi ha problema. La pregunta correcta mai no és «és CPU?», sinó «quant de temps bloqueja?».

Solució 2 (resposta model)

A Apache amb PHP, cada visitant rep un procés o fil propi. Aquest fil demana les dades a MySQL i es queda aturat esperant la resposta, ocupant memòria sense fer res útil; com que cada fil costa megabytes, a les tres-centes connexions el servidor es queda sense recursos. Node.js funciona com un cambrer únic molt organitzat: pren la comanda (la petició), la deixa a la cuina (la base de dades o el sistema operatiu) i se'n va immediatament a atendre una altra taula en comptes d'esperar dret. La feina lenta no la fa ell, la fa la cuina; ell només coordina i serveix quan sona la campana. Per això deu mil connexions que estan gairebé tota l'estona esperant no costen pràcticament res: són deu mil comandes anotades en una llibreta, no deu mil cambrers. La contrapartida és que, si el cambrer es posa a cuinar ell mateix un guisat —un càlcul pesant—, totes les taules es queden sense atendre alhora.

Solució 3

  1. L'última línia parell en Active LTS. L'agost del 2026 això vol dir la línia 24.x, que va entrar en LTS l'octubre del 2025. És la que rep correccions estables i la que suporten els proveïdors d'allotjament i les biblioteques de l'ecosistema.
  2. Aproximadament l'octubre del 2027 passarà a Maintenance LTS (només pedaços crítics i de seguretat), moment en què convé planificar el salt a la següent parell —la 26.x, que haurà entrat en LTS l'octubre del 2026.
  3. La versió Current acabada de publicar (la 26.x fins a l'octubre del 2026) porta novetats interessants, però pot introduir canvis de comportament, moltes biblioteques natives encara no la suporten i no està pensada per a càrregues de producció. És excel·lent per provar en local, no per vendre entrades.

Conclusió

Node.js és un entorn d'execució que porta JavaScript al servidor combinant el motor V8 (que executa el codi) amb libuv (que gestiona l'entrada/sortida asíncrona i el bucle d'esdeveniments). La seva proposta és substituir el model d'«un fil per petició» per un únic fil que no espera mai: delega la feina lenta i atén avisos, com un cambrer que coordina en comptes de cuinar.

D'aquí se'n deriven les seves fortaleses —APIs, temps real, eines CLI, capes BFF, streaming— i la seva debilitat coneguda: el càlcul intensiu de CPU bloqueja tothom, cosa que el Mòdul 10 resol amb worker threads, cluster i cues. Al seu voltant, l'ecosistema npm aporta una biblioteca de solucions inigualable, i el calendari de versions LTS permet triar amb criteri sobre quina base construir.

Amb aquest mapa mental, hem vist també per què Escena Viva —una plataforma de venda d'entrades on gairebé tot és esperar bases de dades, passarel·les de pagament i clients— és un cas d'ús natural per a Node.js.

A la lliçó següent, Instal·lació i Configuració de l'Entorn, passem de la teoria a la pràctica: instal·larem Node.js amb un gestor de versions, verificarem que tot funciona i crearem la carpeta escena-viva/ on viurà el projecte durant els dotze mòduls del curs.

Curs de Node.js: De Principiant a Avançat

Mòdul 1: Introducció a Node.js

Mòdul 2: Conceptes Bàsics

Mòdul 3: Sistema de Fitxers i E/S

Mòdul 4: HTTP i Servidors Web

Mòdul 5: NPM i Gestió de Paquets

Mòdul 6: Framework Express.js

Mòdul 7: Bases de Dades i ORMs

Mòdul 8: Autenticació i Autorització

Mòdul 9: Proves i Depuració

Mòdul 10: Temes Avançats

Mòdul 11: Desplegament i DevOps

Mòdul 12: Projectes del Món Real

© Copyright 2026. Tots els drets reservats