Es pot construir una aplicació d’IA en un sol fitxer HTML? ChatJPT demostra que sí. El fitxer té unes 19.000 línies i pesa una mica més d’un megabyte. Ho conté tot: la interfície, els estils, la lògica i les traduccions. I tot i així dialoga amb 16 proveïdors d’IA i genera imatges, vídeos i veus. Així està construït.
Un sol fitxer és, abans de res, una instal·lació que no ho és. El baixa, l’obre a Chrome, Edge, Firefox o Safari, i ja està. No hi ha dependències per instal·lar, ni compilació, ni servidor per engegar.
Aquesta elecció també influeix en el desenvolupament. Cada canvi es comprova recarregant la pàgina. A més, la distribució és trivial: una versió és un fitxer, el nom del qual porta el número, com ChatJPT_1_35_2.html. Aquest ritme explica en part la història de ChatJPT i les seves 47 versions en cinc mesos.
El fitxer segueix una organització estable: capçalera i estils CSS, després la interfície i després un únic script principal. No hi ha React, ni Vue, ni cap eina de compilació. Funcions JavaScript clàssiques gestionen cada etapa: l’enviament, el streaming de la resposta, la representació, la persistència.
Les funcions dels proveïdors es descriuen en taules de configuració en lloc de en codi dispers. Per exemple, una taula enumera els models d’imatge de cada proveïdor. La interfície llegeix aquesta taula: si un proveïdor hi figura, la pestanya Imatge s’activa sola. Afegir un model sol consistir, per tant, a afegir una línia.
Els colors passen per variables CSS, cosa que permet el tema clar i el tema fosc. Finalment, cada text visible existeix en tres idiomes: francès, anglès i castellà.
Una aplicació d’IA en un sol fitxer HTML no té servidor. Per això el navegador crida directament l’API de cada proveïdor. Aquesta restricció té una conseqüència important: el CORS.
Un navegador impedeix per defecte que una pàgina llegeixi la resposta d’un altre domini, llevat que aquest domini ho autoritzi. Aquest mecanisme s’explica a MDN (en anglès). Abans d’integrar un proveïdor, ChatJPT passa per tant una prova: una petició real des de Chrome, amb el fitxer obert en local. Si el proveïdor bloqueja, no s’integra.
Aquesta prova ja ha descartat diversos serveis. Per exemple, l’API directa de Z.ai bloqueja el navegador; els seus models GLM passen, per tant, per Alibaba, que sí que ho autoritza. De la mateixa manera, el vídeo d’Alibaba només s’ofereix a les regions on el seguiment de tasques és obert al navegador.
Mostrar text produït per una IA és arriscat: una resposta podria contenir codi maliciós. Per això ChatJPT aplica diverses proteccions:
Cada proveïdor té el seu propi format de resposta. Tanmateix, la visualització ha de ser la mateixa: el text que s’escriu en directe, el bloc de raonament desplegable, les fonts, els gràfics. ChatJPT resol aquest problema amb una funció de crida per família d’API i un lector de flux que tradueix cada format a una forma comuna. Després, una única funció de representació pren el relleu.
Molts proveïdors segueixen el format d’OpenAI. Per a ells, una línia en una taula n’hi ha prou per declarar l’adreça de l’API; la resta és genèrica.
El projecte no té cadena de compilació. Per això les comprovacions es fan en un navegador real. Uns escenaris automatitzats simulen les respostes dels proveïdors per comprovar la interfície; després, cada funció es prova amb una clau real. Cada versió nova comprova també els tres idiomes i els dos temes.
ChatJPT es desenvolupa amb l’ajuda d’un assistent de programació, Claude Code. El desenvolupador decideix les funcions, valida cada elecció i prova en condicions reals; l’assistent escriu i comprova el codi. Aquest mètode enllaça amb el mode Vibe Coder de ChatJPT, pensat per ajudar els principiants a crear sense saber programar.
Una aplicació d’IA en un sol fitxer HTML imposa regles: sense servidor, proveïdors oberts al navegador, una seguretat sense concessions. A canvi, continua sent lleugera i transparent. Aquestes eleccions no són només tècniques; deriven de la filosofia de ChatJPT.