<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Neurau Tech</title>
    <description>The latest articles on DEV Community by Neurau Tech (@neurau_tech).</description>
    <link>https://dev.to/neurau_tech</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3994593%2F49cb77af-0363-49eb-af59-7b2c101fad24.png</url>
      <title>DEV Community: Neurau Tech</title>
      <link>https://dev.to/neurau_tech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/neurau_tech"/>
    <language>en</language>
    <item>
      <title>Salaire ingénieur IA en 2026 : France, Suisse, Luxembourg et Canada, sources à l'appui</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Sat, 14 Nov 2026 11:07:38 +0000</pubDate>
      <link>https://dev.to/neurau_tech/salaire-ingenieur-ia-en-2026-france-suisse-luxembourg-et-canada-sources-a-lappui-2p3b</link>
      <guid>https://dev.to/neurau_tech/salaire-ingenieur-ia-en-2026-france-suisse-luxembourg-et-canada-sources-a-lappui-2p3b</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Le salaire ingénieur IA en France dépend de la source et de ce qu'elle mesure&amp;nbsp;: 63&amp;nbsp;000&amp;nbsp;€ brut annuel fixe en moyenne en Île-de-France selon Michael Page, 60&amp;nbsp;600&amp;nbsp;€ chez Silkhom (milieu de fourchette, tous niveaux et zones), 54&amp;nbsp;000&amp;nbsp;€ de médiane, fixe et variable, pour les cadres de la data selon l'Apec. Ce dernier chiffre est plus bas parce qu'il couvre toute la famille data, data analysts compris, des salariés en poste dans toute la France, variable inclus. Les grilles parisiennes partent de 45&amp;nbsp;000&amp;nbsp;€ et atteignent 90&amp;nbsp;000&amp;nbsp;€ pour un ingénieur IA senior, 105&amp;nbsp;000&amp;nbsp;€ pour un ingénieur Machine Learning.&lt;/p&gt;

&lt;p&gt;Cet article compare des sources nommées et datées, consultées les 9 et 13 novembre 2026&amp;nbsp;: l'Apec, cinq cabinets de recrutement et des statistiques officielles pour le Canada et les États-Unis. C'est une synthèse, sans enquête maison. Pour les développeurs en général, voir notre &lt;a href="https://neurautech.com/salaires-developpeurs-france-2026-grille-complete/" rel="noopener noreferrer"&gt;grille des salaires développeurs en France&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chez Silkhom, un ingénieur IA parisien gagne de 45&amp;nbsp;000 à 58&amp;nbsp;000&amp;nbsp;€ brut fixe en junior et de 78&amp;nbsp;000 à 90&amp;nbsp;000&amp;nbsp;€ en senior&amp;nbsp;; un ingénieur Machine Learning senior va jusqu'à 105&amp;nbsp;000&amp;nbsp;€.&lt;/li&gt;
&lt;li&gt;Après la recherche, les métiers LLM et MLOps paient le mieux chez Silkhom&amp;nbsp;: 85&amp;nbsp;400&amp;nbsp;€ pour un LLMOps Engineer, 75&amp;nbsp;300&amp;nbsp;€ pour un MLOps, contre 60&amp;nbsp;600&amp;nbsp;€ pour un ingénieur IA (milieu de fourchette, pas une moyenne de salaires réels).&lt;/li&gt;
&lt;li&gt;Selon l'Apec, la médiane des cadres du Big Data atteint 54&amp;nbsp;000&amp;nbsp;€ brut annuel, fixe et variable, contre 50&amp;nbsp;000&amp;nbsp;€ dans le développement&amp;nbsp;; l'écart se creuse après 45&amp;nbsp;ans (70&amp;nbsp;000&amp;nbsp;€ contre 57&amp;nbsp;000&amp;nbsp;€).&lt;/li&gt;
&lt;li&gt;En Suisse, Robert Half projette une médiane de 129&amp;nbsp;250 CHF, en francs suisses et sans comparaison directe possible&amp;nbsp;; au Luxembourg, Morgan Philips situe un AI/ML Engineer de 3 à 6&amp;nbsp;ans entre 75&amp;nbsp;000 et 95&amp;nbsp;000&amp;nbsp;€ par an.&lt;/li&gt;
&lt;li&gt;En freelance, Hays donne de 550 à 800&amp;nbsp;€ par jour pour un data scientist. Le baromètre de Malt n'a pas pu être lu.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Salaire ingénieur IA en France : ce que mesurent les sources
&lt;/h2&gt;

&lt;p&gt;Aucune statistique publique française ne suit le métier d'ingénieur IA en tant que tel. Il faut croiser l'Apec, qui regroupe la data et l'IA, avec des grilles de cabinets plus fines mais fondées sur leur clientèle.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Ce qui est mesuré&lt;/th&gt;
&lt;th&gt;Population&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apec&lt;/td&gt;
&lt;td&gt;Décembre 2025&lt;/td&gt;
&lt;td&gt;Médiane et déciles, brut annuel, fixe et variable&lt;/td&gt;
&lt;td&gt;Cadres du privé en poste, famille «&amp;nbsp;Big Data&amp;nbsp;»&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Silkhom (cabinet)&lt;/td&gt;
&lt;td&gt;30 juin 2026&lt;/td&gt;
&lt;td&gt;Fourchettes par niveau et zone, brut annuel fixe&lt;/td&gt;
&lt;td&gt;Plus de 25&amp;nbsp;000 profils suivis par le cabinet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Michael Page (cabinet)&lt;/td&gt;
&lt;td&gt;Étude 2027&lt;/td&gt;
&lt;td&gt;Bas, moyenne, haut, brut annuel fixe, Île-de-France&lt;/td&gt;
&lt;td&gt;Clientèle du cabinet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Robert Half (cabinet)&lt;/td&gt;
&lt;td&gt;Guide 2027&lt;/td&gt;
&lt;td&gt;25e, 50e et 75e centiles, brut annuel fixe à l'embauche&lt;/td&gt;
&lt;td&gt;Projections du cabinet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hays (cabinet)&lt;/td&gt;
&lt;td&gt;Étude 2026&lt;/td&gt;
&lt;td&gt;Fourchettes par tranche d'expérience&lt;/td&gt;
&lt;td&gt;Panel de plus de 2&amp;nbsp;500 professionnels&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;L'Apec est la seule source redressée statistiquement&amp;nbsp;: enquêtes de 2021 à 2025, 26&amp;nbsp;000 cadres interrogés en 2025, résultats corrigés avec les données de l'Insee (&lt;a href="https://corporate.apec.fr/files/live/sites/corporate/files/Nos%20etudes/PDF/Les%20remunerations%20des%20cadres%20dans%20111%20familles%20de%20metiers%202025.pdf" rel="noopener noreferrer"&gt;Apec, rémunérations des cadres dans 111 familles de métiers&lt;/a&gt;, décembre 2025). Sa limite&amp;nbsp;: la famille «&amp;nbsp;Big Data&amp;nbsp;» mêle data scientist, data engineer, data analyst et chercheur, sans ligne propre à l'IA.&lt;/p&gt;

&lt;p&gt;Les cabinets nomment mieux les métiers récents (MLOps, ingénieur RAG, LLMOps), mais reflètent leur clientèle et ne publient que le fixe&amp;nbsp;: «&amp;nbsp;hors primes, variables, BSPCE&amp;nbsp;» chez &lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt; (30 juin 2026), «&amp;nbsp;hors primes et avantages&amp;nbsp;» chez &lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;Robert Half&lt;/a&gt; (guide 2027).&lt;/p&gt;




&lt;h2&gt;
  
  
  Le salaire selon l'expérience
&lt;/h2&gt;

&lt;p&gt;L'expérience est le premier facteur du salaire ingénieur IA&amp;nbsp;: chez Silkhom, la fourchette parisienne double entre le bas du junior et le haut du senior.&lt;/p&gt;

&lt;p&gt;Chez Silkhom, un ingénieur IA à Paris gagne de 45&amp;nbsp;000 à 58&amp;nbsp;000&amp;nbsp;€ en junior (0 à 3&amp;nbsp;ans), de 58&amp;nbsp;000 à 78&amp;nbsp;000&amp;nbsp;€ en confirmé (3 à 7&amp;nbsp;ans) et de 78&amp;nbsp;000 à 90&amp;nbsp;000&amp;nbsp;€ en senior (7&amp;nbsp;ans et plus). Un ingénieur Machine Learning parisien va de 48&amp;nbsp;000&amp;nbsp;€ en junior à 105&amp;nbsp;000&amp;nbsp;€ en senior (&lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;, 30 juin 2026).&lt;/p&gt;

&lt;p&gt;Hays ne publie pas de ligne «&amp;nbsp;ingénieur IA&amp;nbsp;», mais donne le data scientist par tranche&amp;nbsp;: 47&amp;nbsp;000 à 52&amp;nbsp;000&amp;nbsp;€ de 0 à 3&amp;nbsp;ans, 52&amp;nbsp;000 à 57&amp;nbsp;000&amp;nbsp;€ de 3 à 5&amp;nbsp;ans, 57&amp;nbsp;000 à 73&amp;nbsp;000&amp;nbsp;€ de 5 à 8&amp;nbsp;ans et 73&amp;nbsp;000 à 89&amp;nbsp;000&amp;nbsp;€ au-delà (&lt;a href="https://www.hays.fr/conseils-carriere/article/metiers-les-plus-recherches-en-2026-salaires" rel="noopener noreferrer"&gt;Hays, métiers les plus recherchés en 2026&lt;/a&gt;, consulté le 13 novembre 2026). La page ne précise ni s'il s'agit de brut ou de net, ni la part variable.&lt;/p&gt;

&lt;p&gt;L'Apec raisonne par âge, sur des cadres en poste. Dans la famille Big Data, la médiane passe de 48&amp;nbsp;000&amp;nbsp;€ avant 35&amp;nbsp;ans à 58&amp;nbsp;000&amp;nbsp;€ entre 35 et 45&amp;nbsp;ans, puis 70&amp;nbsp;000&amp;nbsp;€ après 45&amp;nbsp;ans (&lt;a href="https://corporate.apec.fr/files/live/sites/corporate/files/Nos%20etudes/PDF/Les%20remunerations%20des%20cadres%20dans%20111%20familles%20de%20metiers%202025.pdf" rel="noopener noreferrer"&gt;Apec&lt;/a&gt;, décembre 2025, page 62).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzo3ap9zh34pzswpch4t.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzo3ap9zh34pzswpch4t.webp" alt="Courbes du salaire médian par âge selon l'Apec&amp;nbsp;: famille Big Data de 48&amp;nbsp;000 à 70&amp;nbsp;000 euros, développement informatique de 44&amp;nbsp;000 à 57&amp;nbsp;000 euros, base de comparaison pour le salaire ingénieur IA" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour un débutant&lt;/strong&gt;, le bas des fourchettes parisiennes se situe vers 45&amp;nbsp;000&amp;nbsp;€ brut fixe (Silkhom, Michael Page). Dans la zone «&amp;nbsp;Régions&amp;nbsp;» de Silkhom, hors Paris et hors grandes villes, le junior est donné entre 36&amp;nbsp;000 et 45&amp;nbsp;000&amp;nbsp;€, soit 9&amp;nbsp;000 à 13&amp;nbsp;000&amp;nbsp;€ de moins qu'à Paris aux deux bornes (notre calcul).&lt;/p&gt;




&lt;h2&gt;
  
  
  Paris face aux régions
&lt;/h2&gt;

&lt;p&gt;Le salaire ingénieur IA est plus élevé à Paris&amp;nbsp;: de 5 à 25&amp;nbsp;% selon les pourcentages annoncés par les cabinets, jusqu'à 27&amp;nbsp;% dans la grille Silkhom elle-même (notre calcul)&amp;nbsp;; l'Apec mesure 21&amp;nbsp;% sur la médiane des cadres de la data et un écart bien plus large au 9e décile.&lt;/p&gt;

&lt;p&gt;Silkhom écrit que Paris paie «&amp;nbsp;10 à 15&amp;nbsp;%&amp;nbsp;» de plus que les grandes villes et que l'écart avec les régions moins denses «&amp;nbsp;atteint 15 à 20&amp;nbsp;%&amp;nbsp;». Pour un ingénieur IA confirmé, sa grille donne 58&amp;nbsp;000 à 78&amp;nbsp;000&amp;nbsp;€ à Paris, 52&amp;nbsp;000 à 68&amp;nbsp;000&amp;nbsp;€ dans les grandes villes (Lyon, Toulouse, Nantes, etc.) et 45&amp;nbsp;000 à 62&amp;nbsp;000&amp;nbsp;€ dans les autres régions (&lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;, publié le 30 juin 2026, modifié le 28 septembre 2026, relu le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;Sa propre grille contredit en partie ce pourcentage&amp;nbsp;: de milieu de fourchette à milieu de fourchette, Paris dépasse les régions d'environ 27&amp;nbsp;% en junior et en confirmé, et d'environ 24&amp;nbsp;% en senior, où la grille donne 78&amp;nbsp;000 à 90&amp;nbsp;000&amp;nbsp;€ à Paris contre 62&amp;nbsp;000 à 74&amp;nbsp;000&amp;nbsp;€ dans les régions (notre calcul).&lt;/p&gt;

&lt;p&gt;Michael Page publie des abattements par rapport à l'Île-de-France, de 5&amp;nbsp;% en Provence-Alpes-Côte d'Azur à 15 à 20&amp;nbsp;% en Bretagne, en Normandie et en Centre-Val de Loire (&lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/data-ia-ing%C3%A9nieur-ia-d%C3%A9veloppeur-ia" rel="noopener noreferrer"&gt;Michael Page, ingénieur IA&lt;/a&gt;, étude 2027, relue le 13 novembre 2026). Un abattement de 20&amp;nbsp;% équivaut à une prime parisienne de 25&amp;nbsp;% (notre calcul).&lt;/p&gt;

&lt;p&gt;L'Apec mesure, pour les cadres du Big Data, une médiane de 58&amp;nbsp;000&amp;nbsp;€ en Île-de-France contre 48&amp;nbsp;000&amp;nbsp;€ dans les autres régions, soit environ 21&amp;nbsp;% d'écart (notre calcul). Le haut de la distribution diverge bien plus&amp;nbsp;: le 9e décile atteint 112&amp;nbsp;000&amp;nbsp;€ en Île-de-France contre 70&amp;nbsp;000&amp;nbsp;€ ailleurs, soit 60&amp;nbsp;% d'écart (notre calcul) (&lt;a href="https://corporate.apec.fr/files/live/sites/corporate/files/Nos%20etudes/PDF/Les%20remunerations%20des%20cadres%20dans%20111%20familles%20de%20metiers%202025.pdf" rel="noopener noreferrer"&gt;Apec&lt;/a&gt;, décembre 2025, page 62).&lt;/p&gt;




&lt;h2&gt;
  
  
  Le salaire par métier : ML, MLOps, LLM, data science
&lt;/h2&gt;

&lt;p&gt;MLOps, LLMOps et recherche paient davantage que l'ingénieur IA généraliste&amp;nbsp;; le chercheur en IA arrive en tête chez Silkhom, jusqu'à 130&amp;nbsp;000&amp;nbsp;€ pour un senior parisien, et le prompt engineer est en bas de l'échelle.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métier&lt;/th&gt;
&lt;th&gt;Silkhom, milieu de fourchette (pas une moyenne de salaires réels)&lt;/th&gt;
&lt;th&gt;Silkhom, Paris, junior à senior&lt;/th&gt;
&lt;th&gt;Michael Page, Île-de-France (bas / moyenne / haut)&lt;/th&gt;
&lt;th&gt;Robert Half (P25 / P50 / P75)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur IA&lt;/td&gt;
&lt;td&gt;60&amp;nbsp;600&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000 à 90&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000 / 63&amp;nbsp;000 / 90&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur Machine Learning&lt;/td&gt;
&lt;td&gt;67&amp;nbsp;100&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;48&amp;nbsp;000 à 105&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000 / 65&amp;nbsp;000 / 90&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data scientist&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000 / 59&amp;nbsp;000 / 80&amp;nbsp;000&amp;nbsp;€ (avec data engineer)&lt;/td&gt;
&lt;td&gt;55&amp;nbsp;000 / 60&amp;nbsp;000 / 70&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MLOps Engineer&lt;/td&gt;
&lt;td&gt;75&amp;nbsp;300&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;55&amp;nbsp;000 à 115&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spécialiste IA générative&lt;/td&gt;
&lt;td&gt;74&amp;nbsp;200&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;55&amp;nbsp;000 à 110&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLMOps Engineer&lt;/td&gt;
&lt;td&gt;85&amp;nbsp;400&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;60&amp;nbsp;000 à 125&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur RAG&lt;/td&gt;
&lt;td&gt;64&amp;nbsp;400&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;50&amp;nbsp;000 à 95&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur NLP&lt;/td&gt;
&lt;td&gt;69&amp;nbsp;900&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;50&amp;nbsp;000 à 110&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur Computer Vision&lt;/td&gt;
&lt;td&gt;55&amp;nbsp;600&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000 à 80&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt Engineer&lt;/td&gt;
&lt;td&gt;49&amp;nbsp;700&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;000 à 75&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chercheur en IA&lt;/td&gt;
&lt;td&gt;86&amp;nbsp;800&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;60&amp;nbsp;000 à 130&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;td&gt;Pas de ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Montants en brut annuel fixe. Sources&amp;nbsp;: &lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt; (30 juin 2026), &lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/data-ia-ing%C3%A9nieur-ia-d%C3%A9veloppeur-ia" rel="noopener noreferrer"&gt;Michael Page, ingénieur IA&lt;/a&gt;, &lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/data-ia-machine-learning-engineer" rel="noopener noreferrer"&gt;Michael Page, ML engineer&lt;/a&gt; et &lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/data-ia-data-engineer-data-scientist" rel="noopener noreferrer"&gt;Michael Page, data scientist&lt;/a&gt; (étude 2027), &lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;Robert Half&lt;/a&gt; (guide 2027).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0pt129jw8i10sg9vi91u.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0pt129jw8i10sg9vi91u.webp" alt="Barres horizontales&amp;nbsp;: valeur de milieu de fourchette publiée par Silkhom pour dix métiers de l'IA, du Prompt Engineer à 49&amp;nbsp;700 euros au chercheur en IA à 86&amp;nbsp;800 euros" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deux réserves. Silkhom est ambigu sur sa valeur de synthèse&amp;nbsp;: son tableau l'intitule «&amp;nbsp;Salaire moyen&amp;nbsp;», la note dessous parle de «&amp;nbsp;Médiane calculée sur l'ensemble des niveaux et zones&amp;nbsp;», et sa méthode indique «&amp;nbsp;la médiane entre les valeurs hautes et basses de chaque fourchette&amp;nbsp;». C'est donc un milieu de fourchette, ou plus exactement une valeur centrale des milieux de fourchette sur tous les niveaux et zones, pas une moyenne de salaires réels. Michael Page raisonne en années d'expérience sur le poste et cache le détail par niveau derrière un formulaire.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce qui fait monter la rémunération
&lt;/h2&gt;

&lt;p&gt;Trois leviers ressortent des sources&amp;nbsp;: la spécialité, la responsabilité et la part variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La spécialité LLM et IA générative.&lt;/strong&gt; Chez Silkhom, en milieu de fourchette (pas une moyenne de salaires réels), le spécialiste IA générative (74&amp;nbsp;200&amp;nbsp;€) et le LLMOps Engineer (85&amp;nbsp;400&amp;nbsp;€) dépassent nettement l'ingénieur IA généraliste (60&amp;nbsp;600&amp;nbsp;€), alors que le prompt engineer reste à 49&amp;nbsp;700&amp;nbsp;€ (&lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;, 30 juin 2026). L'ingénieur &lt;a href="https://neurautech.com/rag-retrieval-augmented-generation/" rel="noopener noreferrer"&gt;RAG&lt;/a&gt; (64&amp;nbsp;400&amp;nbsp;€) devance aussi le prompt engineer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les compétences IA en général.&lt;/strong&gt; Selon Robert Half, 37&amp;nbsp;% des responsables du recrutement en IT proposent des salaires plus élevés aux candidats qui ont des compétences en IA, notamment l'IA agentique (voir notre article sur les &lt;a href="https://neurautech.com/agent-ia-quest-ce-que-cest-et-comment-ca-marche/" rel="noopener noreferrer"&gt;agents IA&lt;/a&gt;), l'IA générative et le machine learning (&lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;Robert Half, guide 2027&lt;/a&gt;, relu le 13 novembre 2026). C'est une enquête auprès de recruteurs, pas une mesure de salaires.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La sécurité de l'IA.&lt;/strong&gt; Silkhom affiche 81&amp;nbsp;500&amp;nbsp;€ (milieu de fourchette, pas une moyenne de salaires réels) pour un AI Security Specialist (&lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;, 30 juin 2026). Ce profil croise l'IA et les &lt;a href="https://neurautech.com/metiers-de-la-cybersecurite/" rel="noopener noreferrer"&gt;métiers de la cybersécurité&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le management et la part variable.&lt;/strong&gt; Selon l'Apec, 46&amp;nbsp;% des cadres du Big Data touchent une part variable, d'un montant médian de 4&amp;nbsp;000&amp;nbsp;€, et la médiane monte à 75&amp;nbsp;000&amp;nbsp;€ avec une responsabilité hiérarchique contre 51&amp;nbsp;000&amp;nbsp;€ sans (&lt;a href="https://corporate.apec.fr/files/live/sites/corporate/files/Nos%20etudes/PDF/Les%20remunerations%20des%20cadres%20dans%20111%20familles%20de%20metiers%202025.pdf" rel="noopener noreferrer"&gt;Apec&lt;/a&gt;, décembre 2025, page 62).&lt;/p&gt;




&lt;h2&gt;
  
  
  IA ou développement : l'écart réel
&lt;/h2&gt;

&lt;p&gt;Le salaire ingénieur IA dépasse celui d'un développeur, mais l'écart est plus faible qu'on ne le lit souvent&amp;nbsp;: de 7 à 8&amp;nbsp;% sur la médiane selon l'Apec et Robert Half, nettement plus en haut de l'échelle et en fin de carrière. Faute de ligne «&amp;nbsp;ingénieur IA&amp;nbsp;» chez ces sources, la famille data de l'Apec et le data scientist de Robert Half et de Hays servent ici d'approximation.&lt;/p&gt;

&lt;p&gt;Selon l'Apec, la médiane des cadres du Big Data atteint 54&amp;nbsp;000&amp;nbsp;€, contre 50&amp;nbsp;000&amp;nbsp;€ pour le développement informatique, soit 8&amp;nbsp;% d'écart (notre calcul). Le 9e décile creuse la différence&amp;nbsp;: 98&amp;nbsp;000&amp;nbsp;€ contre 74&amp;nbsp;000&amp;nbsp;€, soit 32&amp;nbsp;% (notre calcul). Après 45&amp;nbsp;ans, la médiane est de 70&amp;nbsp;000&amp;nbsp;€ dans la data contre 57&amp;nbsp;000&amp;nbsp;€ dans le développement (&lt;a href="https://corporate.apec.fr/files/live/sites/corporate/files/Nos%20etudes/PDF/Les%20remunerations%20des%20cadres%20dans%20111%20familles%20de%20metiers%202025.pdf" rel="noopener noreferrer"&gt;Apec&lt;/a&gt;, décembre 2025, pages 62 et 64).&lt;/p&gt;

&lt;p&gt;Robert Half aboutit au même ordre de grandeur pour un profil intermédiaire&amp;nbsp;: 60&amp;nbsp;000&amp;nbsp;€ pour un data scientist contre 56&amp;nbsp;000&amp;nbsp;€ pour un développeur, soit 7&amp;nbsp;% d'écart (notre calcul, &lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;guide 2027&lt;/a&gt;, relu le 13 novembre 2026). Chez Hays, le data scientist de plus de 8&amp;nbsp;ans est donné entre 73&amp;nbsp;000 et 89&amp;nbsp;000&amp;nbsp;€, contre 55&amp;nbsp;000 à 68&amp;nbsp;000&amp;nbsp;€ pour un développeur full stack (&lt;a href="https://www.hays.fr/conseils-carriere/article/metiers-les-plus-recherches-en-2026-salaires" rel="noopener noreferrer"&gt;Hays&lt;/a&gt;, relu le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;Le détail par langage est dans notre article sur les &lt;a href="https://neurautech.com/langages-de-programmation-les-mieux-payes-en-2026/" rel="noopener noreferrer"&gt;langages de programmation les mieux payés&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Freelance : les tarifs journaliers
&lt;/h2&gt;

&lt;p&gt;En freelance, un data scientist facture de 550 à 800&amp;nbsp;€ par jour selon Hays, soit 100 à 150&amp;nbsp;€ de plus qu'un développeur full stack au même niveau (notre calcul). Ce sont des tarifs moyens hors taxes, parisiens selon &lt;a href="https://www.blogdumoderateur.com/freelance-tech-taux-journaliers-moyens-metier-2026/" rel="noopener noreferrer"&gt;Blog du Modérateur&lt;/a&gt; (29 janvier 2026). Aucune source exploitable ne publie de TJM propre à l'ingénieur IA.&lt;/p&gt;

&lt;p&gt;Hays donne pour le data scientist 550&amp;nbsp;€ par jour de 0 à 3&amp;nbsp;ans, 640&amp;nbsp;€ de 3 à 5&amp;nbsp;ans, 715&amp;nbsp;€ de 5 à 8&amp;nbsp;ans et 800&amp;nbsp;€ au-delà. Pour le développeur full stack&amp;nbsp;: 450, 515, 580 et 650&amp;nbsp;€ (&lt;a href="https://www.hays.fr/conseils-carriere/article/metiers-les-plus-recherches-en-2026-salaires" rel="noopener noreferrer"&gt;Hays&lt;/a&gt;, relu le 13 novembre 2026). Le même article de Blog du Modérateur signale pour la data un écart moyen de 9&amp;nbsp;% hors Île-de-France.&lt;/p&gt;

&lt;p&gt;Le baromètre Silkhom de juin 2025 place un data scientist senior entre 550 et 700&amp;nbsp;€ par jour à Paris, 480 à 580&amp;nbsp;€ en région, contre 500 à 600&amp;nbsp;€ pour un développeur Python senior parisien (&lt;a href="https://www.silkhom.com/barometre-des-tjm-informatique-electronique-digital/" rel="noopener noreferrer"&gt;Silkhom, baromètre des TJM&lt;/a&gt;, 4 juin 2025). Ce baromètre ne contient pas de ligne IA ou MLOps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/postes-en-freelance-et-management-de-transition-les-recherch%C3%A9s-tmj-ing%C3%A9nieur-ia" rel="noopener noreferrer"&gt;Michael Page&lt;/a&gt; affiche pour l'ingénieur IA freelance 600&amp;nbsp;€ en bas et 1&amp;nbsp;000&amp;nbsp;€ en moyenne comme en haut (étude 2027), mais présente ces montants comme des salaires annuels&amp;nbsp;: nous ne les retenons pas. Pour le statut, voir notre guide pour &lt;a href="https://neurautech.com/devenir-developpeur-freelance-en-2026-guide-complet/" rel="noopener noreferrer"&gt;devenir développeur freelance&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Suisse, Luxembourg, Canada et Belgique
&lt;/h2&gt;

&lt;p&gt;Les montants suisses (en CHF) et canadiens (en&amp;nbsp;$ CA) ne se comparent pas directement aux montants français&amp;nbsp;: devise, coût de la vie, fiscalité et périmètre diffèrent. Ils sont repris tels quels, sans conversion. Les sources disponibles sont surtout des cabinets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suisse.&lt;/strong&gt; Pour un ingénieur en intelligence artificielle, Robert Half projette pour 2027 une fourchette salariale nationale de 103&amp;nbsp;500 CHF au 25e centile («&amp;nbsp;débute dans ce type de fonction&amp;nbsp;»), 129&amp;nbsp;250 CHF au 50e et 154&amp;nbsp;000 CHF au 75e. En P25 / P50 / P75, un ingénieur en apprentissage automatique est donné à 104&amp;nbsp;000, 119&amp;nbsp;500 et 137&amp;nbsp;750 CHF, un ingénieur MLOps à 93&amp;nbsp;500, 114&amp;nbsp;500 et 135&amp;nbsp;250 CHF (&lt;a href="https://www.roberthalf.com/ch/fr/details-emploi/ingenieur-en-intelligence-artificielle" rel="noopener noreferrer"&gt;Robert Half Suisse&lt;/a&gt;, relu le 13 novembre 2026). Projections de cabinet, salaires annuels&amp;nbsp;; la page ne précise ni s'il s'agit de brut ou de net, ni l'inclusion des primes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Luxembourg.&lt;/strong&gt; Ici, les montants sont en euros, mais le périmètre diffère des grilles françaises. Le cabinet Morgan Philips, cité par Paperjam, situe un AI/ML Engineer entre 75&amp;nbsp;000 et 95&amp;nbsp;000&amp;nbsp;€ par an avec 3 à 6&amp;nbsp;ans d'expérience, et entre 95&amp;nbsp;000 et 135&amp;nbsp;000&amp;nbsp;€ au-delà de 6&amp;nbsp;ans, hors primes et avantages (&lt;a href="https://paperjam.lu/article/les-experts-en-ia-peuvent-gagner-jusqua-200-000-euros-au-luxembourg" rel="noopener noreferrer"&gt;Paperjam&lt;/a&gt;, 11 septembre 2026). L'article ne précise pas s'il s'agit de brut&amp;nbsp;; nous n'avons trouvé aucune statistique officielle propre aux métiers de l'IA au Luxembourg.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canada et Québec.&lt;/strong&gt; Le site officiel Guichet-Emplois donne pour les scientifiques de données (CNP 21211) au Québec un salaire horaire de 31,73&amp;nbsp;$ CA en bas, 46,00&amp;nbsp;$ CA en médiane et 64,84&amp;nbsp;$ CA en haut (période 2023-2024, Statistique Canada&amp;nbsp;; &lt;a href="https://www.guichetemplois.gc.ca/rapportmarche/salaire-profession/227147/ca" rel="noopener noreferrer"&gt;Guichet-Emplois&lt;/a&gt;, mis à jour le 19 novembre 2025, relu le 13 novembre 2026). Selon sa &lt;a href="https://www.guichetemplois.gc.ca/analyse-tendances/recherche-salaires/methodologie-salaires" rel="noopener noreferrer"&gt;méthodologie&lt;/a&gt;, le bas correspond «&amp;nbsp;dans la plupart des cas&amp;nbsp;» au 10e centile et le haut au 90e. Ces montants horaires ne se comparent pas aux montants annuels des cabinets.&lt;/p&gt;

&lt;p&gt;Côté cabinet, Robert Half Canada donne pour un développeur en apprentissage automatique une fourchette salariale nationale annuelle de 91&amp;nbsp;500&amp;nbsp;$ CA (bas), 124&amp;nbsp;250&amp;nbsp;$ CA (moyen) et 167&amp;nbsp;000&amp;nbsp;$ CA (élevé). Ces trois niveaux décrivent l'expérience du candidat (nouveau, modérée, vaste), pas des centiles&amp;nbsp;; brut ou net n'est pas précisé (&lt;a href="https://www.roberthalf.com/ca/fr/details-emploi/developpeur-en-apprentissage-automatique" rel="noopener noreferrer"&gt;Robert Half Canada&lt;/a&gt;, relu le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Belgique.&lt;/strong&gt; Aucune grille sourcée propre à l'IA trouvée&amp;nbsp;; Robert Half Belgique indique seulement que 51&amp;nbsp;% des employeurs offrent des rémunérations plus élevées aux professionnels qui ont des compétences en IA générative (&lt;a href="https://www.roberthalf.com/be/fr/tendances/guide-des-salaires/it-digital" rel="noopener noreferrer"&gt;Robert Half Belgique&lt;/a&gt;, consulté le 9 novembre 2026).&lt;/p&gt;




&lt;h2&gt;
  
  
  Et aux États-Unis ?
&lt;/h2&gt;

&lt;p&gt;La statistique officielle porte sur le salaire, Levels.fyi sur la rémunération totale déclarée, actions comprises.&lt;/p&gt;

&lt;p&gt;Le Bureau of Labor Statistics donne un salaire annuel médian de 120&amp;nbsp;230&amp;nbsp;$ US pour les data scientists en mai 2025&amp;nbsp;; 10&amp;nbsp;% gagnent moins de 67&amp;nbsp;240&amp;nbsp;$ US et 10&amp;nbsp;% plus de 199&amp;nbsp;130&amp;nbsp;$ US. Il prévoit une hausse de 35&amp;nbsp;% de l'emploi entre 2025 et 2035 (&lt;a href="https://www.bls.gov/ooh/math/data-scientists.htm" rel="noopener noreferrer"&gt;BLS, data scientists&lt;/a&gt;, page modifiée le 27 août 2026, relue le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;Levels.fyi affiche une rémunération totale médiane de 285&amp;nbsp;650&amp;nbsp;$ US pour un machine learning engineer aux États-Unis, de 200&amp;nbsp;000&amp;nbsp;$ US au 25e centile à 386&amp;nbsp;500&amp;nbsp;$ US au 75e, sur 1&amp;nbsp;023 déclarations (&lt;a href="https://www.levels.fyi/t/software-engineer/title/machine-learning-engineer/locations/united-states" rel="noopener noreferrer"&gt;Levels.fyi&lt;/a&gt;, mis à jour le 13 novembre 2026). Ces chiffres sont autodéclarés, et la page les présente comme les salaires des grandes entreprises («&amp;nbsp;top companies&amp;nbsp;», notre traduction)&amp;nbsp;: ils ne décrivent pas le marché moyen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comment devenir ingénieur IA
&lt;/h2&gt;

&lt;p&gt;Dans la grille Silkhom (milieux de fourchette), après la recherche, ce sont les métiers de mise en production qui paient le plus&amp;nbsp;: LLMOps 85&amp;nbsp;400&amp;nbsp;€, MLOps 75&amp;nbsp;300&amp;nbsp;€, IA générative 74&amp;nbsp;200&amp;nbsp;€, contre 49&amp;nbsp;700&amp;nbsp;€ pour le prompt engineer. Six étapes, chacune détaillée ailleurs&amp;nbsp;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choisir une voie de formation&lt;/strong&gt;&amp;nbsp;: école d'ingénieurs, master spécialisé en IA ou en data, ou évolution depuis un poste de développeur&amp;nbsp;; notre guide de &lt;a href="https://neurautech.com/reconversion-developpeur-web/" rel="noopener noreferrer"&gt;reconversion&lt;/a&gt; traite le financement d'une formation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Poser les bases mathématiques et ML.&lt;/strong&gt; Statistiques, algèbre linéaire et probabilités, puis les modèles classiques avec scikit-learn et les réseaux de neurones avec PyTorch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maîtriser Python&lt;/strong&gt;, langage de ces bibliothèques, avec notre guide pour &lt;a href="https://neurautech.com/apprendre-python-guide-complet-pour-debutants/" rel="noopener noreferrer"&gt;apprendre Python&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Déployer un projet LLM.&lt;/strong&gt; Un système RAG ou un agent, mis en ligne et mesuré&amp;nbsp;; un &lt;a href="https://neurautech.com/llm-local-ollama/" rel="noopener noreferrer"&gt;LLM local avec Ollama&lt;/a&gt; permet de s'entraîner sans budget.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apprendre l'outillage MLOps&lt;/strong&gt;&amp;nbsp;: les pratiques &lt;a href="https://neurautech.com/devops-c-est-quoi/" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;, les conteneurs et l'intégration continue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Montrer et défendre son travail&lt;/strong&gt;&amp;nbsp;: un portfolio qui présente ces projets, puis notre préparation à l'&lt;a href="https://neurautech.com/entretien-technique-developpeur/" rel="noopener noreferrer"&gt;entretien technique&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Points restés ouverts au 13 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le baromètre de Malt&lt;/strong&gt; et &lt;strong&gt;la fiche métier data scientist de l'Apec&lt;/strong&gt; ont refusé notre accès automatisé&amp;nbsp;: aucun chiffre n'en est tiré.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le détail par niveau chez Michael Page&lt;/strong&gt; est verrouillé&amp;nbsp;; la grille complète de Hays n'est pas en ligne.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aucune ligne «&amp;nbsp;ingénieur IA&amp;nbsp;»&lt;/strong&gt; chez Robert Half France, ni &lt;strong&gt;statistique officielle propre à l'IA&lt;/strong&gt; en France, en Suisse, au Luxembourg ou en Belgique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le brut ou le net&lt;/strong&gt; n'est pas précisé chez Hays, Morgan Philips, Robert Half Suisse et Canada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La rémunération totale&lt;/strong&gt; (variable, BSPCE, actions) en France&amp;nbsp;: les cabinets ne publient que le fixe.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Combien gagne un ingénieur IA débutant ?
&lt;/h3&gt;

&lt;p&gt;Selon &lt;a href="https://www.silkhom.com/les-salaires-ia-et-ml/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt; (juin 2026), de 45&amp;nbsp;000 à 58&amp;nbsp;000&amp;nbsp;€ brut annuel fixe à Paris et de 36&amp;nbsp;000 à 45&amp;nbsp;000&amp;nbsp;€ dans sa zone «&amp;nbsp;Régions&amp;nbsp;» (hors grandes villes), soit 9&amp;nbsp;000 à 13&amp;nbsp;000&amp;nbsp;€ de moins. Hays donne 47&amp;nbsp;000 à 52&amp;nbsp;000&amp;nbsp;€ pour un data scientist de 0 à 3&amp;nbsp;ans, sans préciser brut ou net ni la part variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quel est le salaire d'un ingénieur IA en France ?
&lt;/h3&gt;

&lt;p&gt;Cela dépend du périmètre. &lt;a href="https://www.michaelpage.fr/grilles-de-salaires/technology/data-ia-ing%C3%A9nieur-ia-d%C3%A9veloppeur-ia" rel="noopener noreferrer"&gt;Michael Page&lt;/a&gt; donne 63&amp;nbsp;000&amp;nbsp;€ brut fixe en moyenne en Île-de-France (étude 2027)&amp;nbsp;; Silkhom 60&amp;nbsp;600&amp;nbsp;€ en milieu de fourchette, tous niveaux et zones (pas une moyenne de salaires réels). L'Apec mesure une médiane de 54&amp;nbsp;000&amp;nbsp;€, fixe et variable, pour toute la famille data, data analysts compris, en France entière.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quel salaire pour un ingénieur IA en Suisse ?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.roberthalf.com/ch/fr/details-emploi/ingenieur-en-intelligence-artificielle" rel="noopener noreferrer"&gt;Robert Half Suisse&lt;/a&gt; projette pour 2027 une médiane de 129&amp;nbsp;250 CHF par an, dans une fourchette de 103&amp;nbsp;500 à 154&amp;nbsp;000 CHF. Ce sont des projections de cabinet (P25 / P50 / P75), en francs suisses, non comparables directement aux montants français.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quel salaire pour un ingénieur IA au Luxembourg ?
&lt;/h3&gt;

&lt;p&gt;Selon le cabinet Morgan Philips, cité par &lt;a href="https://paperjam.lu/article/les-experts-en-ia-peuvent-gagner-jusqua-200-000-euros-au-luxembourg" rel="noopener noreferrer"&gt;Paperjam&lt;/a&gt; en septembre 2026&amp;nbsp;: de 75&amp;nbsp;000 à 95&amp;nbsp;000&amp;nbsp;€ par an pour un AI/ML Engineer de 3 à 6&amp;nbsp;ans d'expérience, de 95&amp;nbsp;000 à 135&amp;nbsp;000&amp;nbsp;€ au-delà, hors primes.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones, réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse de sources publiques consultées le 9 novembre 2026 et relues le 13 novembre 2026&amp;nbsp;: étude de l'Apec, grilles des cabinets Silkhom, Michael Page, Robert Half, Hays et Morgan Philips, statistiques de Guichet-Emplois et du Bureau of Labor Statistics, données autodéclarées de Levels.fyi. Les pages du BLS et de Levels.fyi refusent les requêtes automatisées simples (erreur 403)&amp;nbsp;: leurs chiffres ont été lus par un outil de lecture web, sans contournement. Les chiffres de cabinets sont signalés comme tels, avec leur périmètre. Les écarts en pourcentage sont nos calculs. Aucune enquête maison, aucun lien affilié, aucune relation commerciale avec les sources citées.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un chiffre périmé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 13 novembre 2026.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>salaire</category>
      <category>intelligenceartificielle</category>
      <category>machinelearning</category>
      <category>carriere</category>
    </item>
    <item>
      <title>VPS pas cher en novembre 2026 : 8 hébergeurs comparés au prix officiel</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Sat, 14 Nov 2026 11:05:30 +0000</pubDate>
      <link>https://dev.to/neurau_tech/vps-pas-cher-en-novembre-2026-8-hebergeurs-compares-au-prix-officiel-25k6</link>
      <guid>https://dev.to/neurau_tech/vps-pas-cher-en-novembre-2026-8-hebergeurs-compares-au-prix-officiel-25k6</guid>
      <description>&lt;h2&gt;
  
  
  Le comparatif en une minute
&lt;/h2&gt;

&lt;p&gt;Un VPS pas cher s'affiche entre 2 et 6&amp;nbsp;€ HT par mois en novembre 2026 pour 2 à 8&amp;nbsp;Go de RAM (hors Scaleway Stardust, plus petite). Ce sont des prix d'appel&amp;nbsp;: sur deux ans, le prix réel est souvent bien plus haut. Nous avons relu le 13 novembre 2026 les pages officielles de huit hébergeurs&amp;nbsp;: OVHcloud, Hetzner, Scaleway, IONOS, LWS, Hostinger, Contabo et Infomaniak.&lt;/p&gt;

&lt;p&gt;Nous avons noté prix, engagement, frais, IPv4, centres de données, Windows et sauvegardes, puis calculé le coût sur 24&amp;nbsp;mois. Aucun serveur n'a été loué ni testé.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le prix d'appel le plus bas est celui de Scaleway Stardust, environ 0,44&amp;nbsp;€ HT par mois, mais l'IPv4 coûte en plus environ 3,65&amp;nbsp;€ HT par mois (notre calcul).&lt;/li&gt;
&lt;li&gt;Sur 24&amp;nbsp;mois, OVHcloud VPS-1 revient à 91,44&amp;nbsp;€ HT et LWS VPS M à 464,76&amp;nbsp;€ HT (notre calcul), alors que LWS affiche un prix d'appel de 4,99&amp;nbsp;€ HT pour 8&amp;nbsp;Go.&lt;/li&gt;
&lt;li&gt;Par Go de RAM, Contabo arrive en tête au prix d'appel, que son prix de 4,40&amp;nbsp;€ soit HT ou TTC.&lt;/li&gt;
&lt;li&gt;Hostinger facture 5,49&amp;nbsp;€ HT par mois sur 24&amp;nbsp;mois payés d'avance, puis 11,99&amp;nbsp;€ HT par mois.&lt;/li&gt;
&lt;li&gt;Le 13 novembre, l'entrée de gamme de Hetzner et les VPS Windows de LWS étaient toujours indisponibles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Le tableau des VPS pas cher, relevé le 13 novembre 2026
&lt;/h2&gt;

&lt;p&gt;Le premier tableau compare le VPS pas cher le plus accessible de chaque hébergeur, d'après les pages officielles consultées le 13 novembre 2026. HT ou TTC&amp;nbsp;: comme sur la page. Le total sur 24&amp;nbsp;mois est notre calcul, hors TVA, frais de mise en service compris quand ils sont chiffrés.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offre&lt;/th&gt;
&lt;th&gt;Prix affiché&lt;/th&gt;
&lt;th&gt;Engagement&lt;/th&gt;
&lt;th&gt;Mise en service&lt;/th&gt;
&lt;th&gt;Prix ensuite&lt;/th&gt;
&lt;th&gt;Total 24&amp;nbsp;mois (notre calcul)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud VPS-1&lt;/td&gt;
&lt;td&gt;3,81&amp;nbsp;€ HT (4,57&amp;nbsp;€ TTC)&lt;/td&gt;
&lt;td&gt;12&amp;nbsp;mois payés d'avance&amp;nbsp;; 4,49&amp;nbsp;€ HT sans engagement&lt;/td&gt;
&lt;td&gt;0&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;Non relevé sur la page&lt;/td&gt;
&lt;td&gt;91,44&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hetzner CX23&lt;/td&gt;
&lt;td&gt;5,99&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;Aucun, facturation à l'heure&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;5,99&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;143,76&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway DEV1-S&lt;/td&gt;
&lt;td&gt;6,55&amp;nbsp;€ HT environ, IPv4 en plus&lt;/td&gt;
&lt;td&gt;Aucun, facturation à l'heure&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;Identique&lt;/td&gt;
&lt;td&gt;Environ 245&amp;nbsp;€ HT avec IPv4, hors stockage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway Stardust1-S&lt;/td&gt;
&lt;td&gt;0,44&amp;nbsp;€ HT environ, IPv4 en plus&lt;/td&gt;
&lt;td&gt;Aucun, facturation à l'heure&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;Identique&lt;/td&gt;
&lt;td&gt;Environ 98&amp;nbsp;€ HT avec IPv4, hors stockage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IONOS VPS S+&lt;/td&gt;
&lt;td&gt;2&amp;nbsp;€ HT (2,40&amp;nbsp;€ TTC) pendant 3&amp;nbsp;mois&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;€, HT ou TTC non précisé&lt;/td&gt;
&lt;td&gt;5&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;121&amp;nbsp;€ HT, frais inclus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LWS VPS M&lt;/td&gt;
&lt;td&gt;4,99&amp;nbsp;€ HT (5,96&amp;nbsp;€ TTC) le 1er mois&lt;/td&gt;
&lt;td&gt;Sans engagement&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;19,99&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;464,76&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hostinger KVM 1&lt;/td&gt;
&lt;td&gt;5,49&amp;nbsp;€ HT par mois&lt;/td&gt;
&lt;td&gt;24&amp;nbsp;mois payés d'avance (131,76&amp;nbsp;€ HT)&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;11,99&amp;nbsp;€ HT par mois&lt;/td&gt;
&lt;td&gt;131,76&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contabo Cloud VPS 4&lt;/td&gt;
&lt;td&gt;4,40&amp;nbsp;€, base de TVA non établie&lt;/td&gt;
&lt;td&gt;Abonnement de 24&amp;nbsp;mois&lt;/td&gt;
&lt;td&gt;0&amp;nbsp;€ sur 24&amp;nbsp;mois&amp;nbsp;; montant non relevé en mensuel&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;105,60&amp;nbsp;€, base de TVA non établie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infomaniak VPS Lite&lt;/td&gt;
&lt;td&gt;CHF 2.70 HT&lt;/td&gt;
&lt;td&gt;12&amp;nbsp;mois payés d'avance&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;Non calculé (francs suisses)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offre&lt;/th&gt;
&lt;th&gt;vCPU / RAM&lt;/th&gt;
&lt;th&gt;Disque&lt;/th&gt;
&lt;th&gt;Trafic&lt;/th&gt;
&lt;th&gt;IPv4&lt;/th&gt;
&lt;th&gt;Centres de données&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud VPS-1&lt;/td&gt;
&lt;td&gt;2 / 4&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;Illimité, 500&amp;nbsp;Mbit/s (500&amp;nbsp;Go par mois en Asie-Pacifique)&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;France, Canada, Europe, Asie-Pacifique&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hetzner CX23&lt;/td&gt;
&lt;td&gt;2 / 4&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;To&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;Allemagne, Finlande&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway DEV1-S&lt;/td&gt;
&lt;td&gt;2 / 2&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;Non inclus&lt;/td&gt;
&lt;td&gt;Inclus, 200&amp;nbsp;Mbit/s&lt;/td&gt;
&lt;td&gt;En option&lt;/td&gt;
&lt;td&gt;France, Pays-Bas, Pologne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway Stardust1-S&lt;/td&gt;
&lt;td&gt;1 / 1&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;Non inclus&lt;/td&gt;
&lt;td&gt;Inclus, 100&amp;nbsp;Mbit/s&lt;/td&gt;
&lt;td&gt;En option&lt;/td&gt;
&lt;td&gt;France, Pays-Bas, Pologne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IONOS VPS S+&lt;/td&gt;
&lt;td&gt;1 / 2&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;60&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;Illimité, 1 Gbit/s&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;Allemagne, Espagne, Royaume-Uni, États-Unis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LWS VPS M&lt;/td&gt;
&lt;td&gt;4 / 8&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;120&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;Illimité, 200&amp;nbsp;Mbit/s&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;France&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hostinger KVM 1&lt;/td&gt;
&lt;td&gt;1 / 4&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;50&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;4&amp;nbsp;To&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;France, Europe, Asie, Amériques&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contabo Cloud VPS 4&lt;/td&gt;
&lt;td&gt;4 / 8&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;100&amp;nbsp;Go SSD&lt;/td&gt;
&lt;td&gt;Illimité, 200&amp;nbsp;Mbit/s&lt;/td&gt;
&lt;td&gt;Incluse&lt;/td&gt;
&lt;td&gt;Europe, Royaume-Uni, États-Unis, Asie, Australie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infomaniak VPS Lite&lt;/td&gt;
&lt;td&gt;1 / 2&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;Go NVMe&lt;/td&gt;
&lt;td&gt;Illimité, 500&amp;nbsp;Mbit/s&lt;/td&gt;
&lt;td&gt;Non relevé (absente de la page)&lt;/td&gt;
&lt;td&gt;Suisse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources dans la section suivante&amp;nbsp;; les francs suisses d'Infomaniak ne sont pas convertis.&lt;/p&gt;




&lt;h2&gt;
  
  
  Offre par offre : ce que dit chaque page
&lt;/h2&gt;

&lt;p&gt;Chaque hébergeur VPS présente ses prix à sa façon.&lt;/p&gt;

&lt;h3&gt;
  
  
  OVHcloud : un prix bas qui suppose 12 mois d'avance
&lt;/h3&gt;

&lt;p&gt;Le VPS-1 d'OVHcloud démarre à 3,81&amp;nbsp;€ HT par mois, soit 4,57&amp;nbsp;€ TTC, avec une sauvegarde quotidienne des dernières 24&amp;nbsp;heures et l'IPv4 incluses (&lt;a href="https://www.ovhcloud.com/fr/vps/" rel="noopener noreferrer"&gt;page VPS d'OVHcloud&lt;/a&gt;, consultée le 13 novembre 2026). En Asie-Pacifique (Mumbai, Singapour, Sydney), son trafic est plafonné à 500&amp;nbsp;Go par mois.&lt;/p&gt;

&lt;p&gt;Le reste vient d'une source technique&amp;nbsp;: le &lt;a href="https://eu.api.ovh.com/1.0/order/catalog/public/vps?ovhSubsidiary=FR" rel="noopener noreferrer"&gt;catalogue public d'OVHcloud&lt;/a&gt;, l'interface que lit son site de commande, consulté le même jour. Il donne trois tarifs HT pour le VPS-1&amp;nbsp;: 4,49&amp;nbsp;€ sans engagement, 4,26&amp;nbsp;€ avec 6&amp;nbsp;mois et 3,81&amp;nbsp;€ avec 12&amp;nbsp;mois payés d'avance, sans frais d'installation, et liste les centres de données&amp;nbsp;: Gravelines, Strasbourg, Roubaix, Beauharnois (Canada), d'autres pays européens et l'Asie-Pacifique.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hetzner : bon rapport, toujours indisponible
&lt;/h3&gt;

&lt;p&gt;Le CX23 de Hetzner coûte 5,99&amp;nbsp;€ HT par mois ou 0,0096&amp;nbsp;€ HT de l'heure, IPv4 incluse, facturé à l'heure jusqu'à la suppression du serveur (&lt;a href="https://www.hetzner.com/cloud/cost-optimized/" rel="noopener noreferrer"&gt;page Cost-Optimized de Hetzner&lt;/a&gt;, consultée le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;Le CX23 n'est proposé qu'à Nuremberg et à Helsinki. Le 9 puis le 13 novembre, toute la gamme portait le message «&amp;nbsp;This product is currently unavailable. Please check back later&amp;nbsp;». La nouvelle CPX02, 1&amp;nbsp;vCPU et 1&amp;nbsp;Go, était aussi indisponible&amp;nbsp;; son prix est passé de 6,49&amp;nbsp;€ HT le 9 novembre à 5,49&amp;nbsp;€ HT le 13 (&lt;a href="https://www.hetzner.com/cloud/regular-performance/" rel="noopener noreferrer"&gt;page Regular Performance&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaleway : l'instance la moins chère, l'IPv4 en plus
&lt;/h3&gt;

&lt;p&gt;Scaleway facture la Stardust1-S 0,0006&amp;nbsp;€ HT de l'heure, environ 0,44&amp;nbsp;€ par mois selon la page, et la DEV1-S environ 6,55&amp;nbsp;€ HT par mois (&lt;a href="https://www.scaleway.com/en/pricing/virtual-instances/" rel="noopener noreferrer"&gt;tarifs des instances Scaleway&lt;/a&gt;, consultés le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;Le trafic sortant est compris, pas le stockage ni l'IPv4. La &lt;a href="https://www.scaleway.com/en/pricing/network/" rel="noopener noreferrer"&gt;page de tarifs réseau&lt;/a&gt;, consultée le même jour, facture l'IPv4 d'une instance 0,005&amp;nbsp;€ HT de l'heure, soit environ 3,65&amp;nbsp;€ HT sur 730&amp;nbsp;heures (notre calcul). Les zones sont Paris, Amsterdam et Varsovie.&lt;/p&gt;

&lt;h3&gt;
  
  
  IONOS : 2 € pendant trois mois
&lt;/h3&gt;

&lt;p&gt;IONOS affiche le VPS S+ à 2&amp;nbsp;€ HT par mois (2,40&amp;nbsp;€ TTC) «&amp;nbsp;pendant 3&amp;nbsp;mois&amp;nbsp;», puis 5&amp;nbsp;€ HT (&lt;a href="https://www.ionos.fr/serveurs/vps" rel="noopener noreferrer"&gt;page VPS d'IONOS&lt;/a&gt;, consultée le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;La page indique «&amp;nbsp;Mise en service&amp;nbsp;: 10&amp;nbsp;€&amp;nbsp;» sans préciser HT ou TTC, et une garantie «&amp;nbsp;satisfait ou remboursé&amp;nbsp;» de 30&amp;nbsp;jours. Nous n'y avons pas trouvé de durée d'engagement. Une IPv4 supplémentaire coûte 5&amp;nbsp;€ HT.&lt;/p&gt;

&lt;h3&gt;
  
  
  LWS : un premier mois à 4,99 €, puis 19,99 €
&lt;/h3&gt;

&lt;p&gt;LWS affiche son VPS M à 4,99&amp;nbsp;€ HT, avec «&amp;nbsp;5,96&amp;nbsp;€ TTC&amp;nbsp;» (&lt;a href="https://www.lws.fr/serveur_dedie_linux.php" rel="noopener noreferrer"&gt;page VPS Linux de LWS&lt;/a&gt;, consultée le 13 novembre 2026). À 20&amp;nbsp;% de TVA, 4,99&amp;nbsp;€ HT donnent 5,99&amp;nbsp;€ TTC (notre calcul)&amp;nbsp;: nous reprenons le chiffre de la page sans pouvoir expliquer l'écart.&lt;/p&gt;

&lt;p&gt;La note de bas de page précise que ce prix ne vaut que le premier mois, puis 19,99&amp;nbsp;€ HT, pour les nouveaux clients et un seul serveur en promotion. Le VPS S, sans promotion, coûte 9,99&amp;nbsp;€ HT pour 2 vCores et 4&amp;nbsp;Go. Les offres sont sans engagement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hostinger : 24 mois payés d'avance
&lt;/h3&gt;

&lt;p&gt;Hostinger affiche le KVM 1 à 5,49&amp;nbsp;€ par mois, avec la mention «&amp;nbsp;Vous payez aujourd'hui 131,76&amp;nbsp;€ pour 24&amp;nbsp;mois. Le contrat se renouvelle automatiquement à 11,99&amp;nbsp;€/mois pour la même durée&amp;nbsp;» (&lt;a href="https://www.hostinger.com/fr/vps" rel="noopener noreferrer"&gt;page VPS d'Hostinger&lt;/a&gt;, consultée le 13 novembre 2026). Le pied de page indique que les prix n'incluent pas la TVA.&lt;/p&gt;

&lt;p&gt;La page annonce un tarif «&amp;nbsp;Black Friday&amp;nbsp;» sans afficher de date de fin. La &lt;a href="https://www.hostinger.com/support/1583267-where-are-hostinger-servers-located/" rel="noopener noreferrer"&gt;page d'aide sur les centres de données&lt;/a&gt;, mise à jour le 11 novembre 2026, cite pour les VPS la France, l'Allemagne, la Lituanie, le Royaume-Uni, l'Asie et les Amériques.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contabo : beaucoup de RAM, TVA à vérifier
&lt;/h3&gt;

&lt;p&gt;Contabo affiche le Cloud VPS 4 à 4,40&amp;nbsp;€ par mois «&amp;nbsp;for the first 24 months&amp;nbsp;», avec un prix barré de 5,50&amp;nbsp;€ (&lt;a href="https://contabo.com/en/vps/" rel="noopener noreferrer"&gt;page Cloud VPS de Contabo&lt;/a&gt;, consultée le 13 novembre 2026). Une note précise qu'il s'agit du «&amp;nbsp;tarif mensuel effectif pour un abonnement de 24&amp;nbsp;mois, taxes applicables incluses&amp;nbsp;» (notre traduction).&lt;/p&gt;

&lt;p&gt;La version servie était celle d'Andorre («&amp;nbsp;AD&amp;nbsp;»), sans TVA chez Contabo&amp;nbsp;: pour un client français, nous n'avons pas pu établir si 4,40&amp;nbsp;€ est HT ou TTC. La FAQ cite des frais de mise en service en contrat mensuel, sans montant, et aucun pour les contrats plus longs. Le prix après 24&amp;nbsp;mois n'est pas indiqué.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infomaniak, o2switch, PulseHeberg, DigitalOcean et Vultr
&lt;/h3&gt;

&lt;p&gt;Infomaniak vend un VPS Lite à CHF 2.70 HT par mois, engagement annuel payé en une fois (&lt;a href="https://www.infomaniak.com/fr/hebergement/vps-lite" rel="noopener noreferrer"&gt;page VPS Lite d'Infomaniak&lt;/a&gt;, consultée le 13 novembre 2026). La page ne mentionne ni l'IPv4 ni le prix de renouvellement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.o2switch.fr/" rel="noopener noreferrer"&gt;o2switch&lt;/a&gt; ne vend pas de VPS. PulseHeberg et Vultr ont bloqué notre lecture&amp;nbsp;: non vérifiés. &lt;a href="https://www.digitalocean.com/pricing/droplets" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; n'affiche que des dollars.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le moins cher par Go de RAM (notre calcul)
&lt;/h2&gt;

&lt;p&gt;La RAM est la ressource qui manque en premier sur un VPS pas cher. Nous divisons le prix mensuel affiché par la RAM, au prix d'appel puis au prix suivant. Tous les prix sont HT, sauf Contabo, dont la base de TVA n'est pas établie. Si ses 4,40&amp;nbsp;€ incluent 20&amp;nbsp;% de TVA, le prix HT est d'environ 3,67&amp;nbsp;€, soit environ 0,46&amp;nbsp;€ HT par Go (notre calcul)&amp;nbsp;: Contabo reste premier dans les deux cas.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offre&lt;/th&gt;
&lt;th&gt;Prix d'appel par Go de RAM&lt;/th&gt;
&lt;th&gt;Prix suivant par Go&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Contabo Cloud VPS 4&lt;/td&gt;
&lt;td&gt;0,55&amp;nbsp;€ (0,46&amp;nbsp;€ HT si TTC)&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LWS VPS M&lt;/td&gt;
&lt;td&gt;0,62&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;2,50&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud VPS-1&lt;/td&gt;
&lt;td&gt;0,95&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;1,12&amp;nbsp;€ HT sans engagement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IONOS VPS S+&lt;/td&gt;
&lt;td&gt;1,00&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;2,50&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hostinger KVM 1&lt;/td&gt;
&lt;td&gt;1,37&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;3,00&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hetzner CX23&lt;/td&gt;
&lt;td&gt;1,50&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;1,50&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway DEV1-S avec IPv4&lt;/td&gt;
&lt;td&gt;5,10&amp;nbsp;€ HT&lt;/td&gt;
&lt;td&gt;5,10&amp;nbsp;€ HT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq2i2o6uje4l9le0468yj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq2i2o6uje4l9le0468yj.webp" alt="Classement d'un VPS pas cher par prix mensuel par Go de RAM&amp;nbsp;: Contabo 0,55&amp;nbsp;€, LWS 0,62&amp;nbsp;€, OVHcloud 0,95&amp;nbsp;€, IONOS 1,00&amp;nbsp;€, Hostinger 1,37&amp;nbsp;€, Hetzner 1,50&amp;nbsp;€, Scaleway DEV1-S avec IPv4 5,10&amp;nbsp;€, au 13 novembre 2026" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le classement change après la promotion&amp;nbsp;: LWS, deuxième au prix d'appel, devient l'un des plus chers par Go dès le deuxième mois. OVHcloud et Hetzner restent stables. Pour Scaleway, nous avons ajouté l'IPv4 (3,65&amp;nbsp;€ HT) aux 6,55&amp;nbsp;€ HT de la DEV1-S, sans le stockage.&lt;/p&gt;




&lt;h2&gt;
  
  
  VPS Windows : le surcoût de la licence
&lt;/h2&gt;

&lt;p&gt;La licence Microsoft est facturée en plus, et l'entrée de gamme n'est souvent pas éligible.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hébergeur&lt;/th&gt;
&lt;th&gt;Ce que disent les pages le 13 novembre 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud&lt;/td&gt;
&lt;td&gt;Windows Server à partir du VPS-2, affiché 7,21&amp;nbsp;€ HT avec 12&amp;nbsp;mois d'engagement sur la page VPS. L'option Windows à 8&amp;nbsp;€ HT par mois figure seulement dans le catalogue public. Absent du VPS-1.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IONOS&lt;/td&gt;
&lt;td&gt;Windows M+ à 14&amp;nbsp;€ HT pendant 3&amp;nbsp;mois puis 22&amp;nbsp;€ HT, contre 4&amp;nbsp;€ puis 12&amp;nbsp;€ HT pour le même serveur sous Linux (&lt;a href="https://www.ionos.fr/serveurs/vps-windows" rel="noopener noreferrer"&gt;page VPS Windows d'IONOS&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LWS&lt;/td&gt;
&lt;td&gt;VPS Windows dès 9,99&amp;nbsp;€ HT, les quatre offres «&amp;nbsp;Plus en stock temporairement&amp;nbsp;» (&lt;a href="https://www.lws.fr/vps-windows.php" rel="noopener noreferrer"&gt;page VPS Windows de LWS&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;POP2-2C-8G-WIN à environ 133,08&amp;nbsp;€ HT par mois, contre environ 53,66&amp;nbsp;€ HT sous Linux (&lt;a href="https://www.scaleway.com/en/pricing/virtual-instances/" rel="noopener noreferrer"&gt;tarifs des instances Scaleway&lt;/a&gt;, 13 novembre 2026).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contabo&lt;/td&gt;
&lt;td&gt;Licence fournie obligatoirement, «&amp;nbsp;frais mensuels déterminés par la taille du VPS&amp;nbsp;» (notre traduction), montant non relevé (&lt;a href="https://contabo.com/en/windows-servers-vps/" rel="noopener noreferrer"&gt;page Windows de Contabo&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hetzner, Hostinger, Infomaniak&lt;/td&gt;
&lt;td&gt;Non relevé&amp;nbsp;: aucun prix de licence sur les pages lues.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Chez IONOS, l'écart est de 10&amp;nbsp;€ HT par mois après la promotion (notre calcul). Pour un serveur web, un VPS Linux reste moins cher.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sauvegardes et snapshots : inclus ou payants
&lt;/h2&gt;

&lt;p&gt;La sauvegarde change le coût réel. Un snapshot est une copie manuelle&amp;nbsp;; une sauvegarde automatique est planifiée par l'hébergeur. Pages consultées le 13 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OVHcloud.&lt;/strong&gt; Sauvegarde quotidienne incluse, Premium sur 7&amp;nbsp;jours à partir de 1,10&amp;nbsp;€ HT par mois, snapshot à partir de 0,30&amp;nbsp;€ HT (&lt;a href="https://www.ovhcloud.com/fr/vps/" rel="noopener noreferrer"&gt;page VPS&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hetzner.&lt;/strong&gt; Sauvegardes à partir de 1,0980&amp;nbsp;€ HT par mois selon l'instance, snapshots à 0,0143&amp;nbsp;€ HT par Go et par mois (&lt;a href="https://www.hetzner.com/cloud/cost-optimized/" rel="noopener noreferrer"&gt;page Cost-Optimized&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaleway.&lt;/strong&gt; Snapshots à environ 0,03&amp;nbsp;€ HT par Go et par mois, approximation de la &lt;a href="https://www.scaleway.com/en/pricing/virtual-instances/" rel="noopener noreferrer"&gt;page de tarifs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hostinger.&lt;/strong&gt; «&amp;nbsp;Sauvegardes hebdomadaires gratuites&amp;nbsp;» (&lt;a href="https://www.hostinger.com/fr/vps" rel="noopener noreferrer"&gt;page VPS&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LWS.&lt;/strong&gt; Snapshot inclus, «&amp;nbsp;Sauvegarde PRO&amp;nbsp;» sur NAS en option (&lt;a href="https://www.lws.fr/serveur_dedie_linux.php" rel="noopener noreferrer"&gt;page VPS Linux&lt;/a&gt;), qui avertit que son système «&amp;nbsp;ne garantit pas vos données à 100&amp;nbsp;%&amp;nbsp;».&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contabo.&lt;/strong&gt; Un snapshot inclus&amp;nbsp;; sauvegarde automatique en option, prix non relevé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IONOS.&lt;/strong&gt; Renvoie à son offre Cloud Backup, prix non relevé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infomaniak VPS Lite.&lt;/strong&gt; Pas de snapshot, selon sa FAQ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gardez aussi une copie hors de l'hébergeur&amp;nbsp;: elle seule protège d'une fermeture de compte ou d'un incident de centre de données.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quel VPS pour quel usage
&lt;/h2&gt;

&lt;p&gt;Le bon choix d'un VPS pas cher dépend de ce que vous allez faire tourner. Ce tableau est une grille de lecture&amp;nbsp;: aucun processeur ni débit n'a été testé.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;th&gt;Ce qui compte&lt;/th&gt;
&lt;th&gt;Offres relevées qui collent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Débutant ou test&lt;/td&gt;
&lt;td&gt;Payer peu, pouvoir tout supprimer&lt;/td&gt;
&lt;td&gt;Hetzner (facturation à l'heure, si disponible), Scaleway Stardust, Oracle Always Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site personnel ou blog&lt;/td&gt;
&lt;td&gt;Pas de promotion limitée, centre de données en France, sauvegarde&lt;/td&gt;
&lt;td&gt;OVHcloud VPS-1 (sauvegarde quotidienne incluse), LWS VPS S (9,99&amp;nbsp;€ HT, sans promotion)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker ou API&lt;/td&gt;
&lt;td&gt;4&amp;nbsp;Go de RAM minimum, IPv4 incluse&lt;/td&gt;
&lt;td&gt;OVHcloud VPS-1, Hetzner CX23 si disponible, Contabo Cloud VPS 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPN personnel&lt;/td&gt;
&lt;td&gt;Trafic généreux, pays du serveur, petit prix&lt;/td&gt;
&lt;td&gt;IONOS VPS S+, Hostinger KVM 1, OVHcloud VPS-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serveur de jeu&lt;/td&gt;
&lt;td&gt;RAM, centre de données proche des joueurs&lt;/td&gt;
&lt;td&gt;Contabo Cloud VPS 4 ou LWS VPS M (8&amp;nbsp;Go, 200&amp;nbsp;Mbit/s annoncés), OVHcloud VPS-2 (8&amp;nbsp;Go, 1 Gbit/s annoncé)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;Licence incluse ou non, offre en stock&lt;/td&gt;
&lt;td&gt;IONOS Windows M+, OVHcloud VPS-2 avec option Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pour un conteneur derrière un nom de domaine, notre tutoriel &lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt; puis celui sur le &lt;a href="https://neurautech.com/nginx-reverse-proxy-docker-compose/" rel="noopener noreferrer"&gt;reverse proxy Nginx avec Docker Compose&lt;/a&gt; couvrent l'installation. Pour un VPN, notre comparatif &lt;a href="https://neurautech.com/vpn-gratuit-vs-payant-lequel-choisir-honnete-2026/" rel="noopener noreferrer"&gt;VPN gratuit ou payant&lt;/a&gt; aide à décider si l'auto-hébergement vaut le coup.&lt;/p&gt;

&lt;p&gt;Pour comparer avec une plateforme gérée (PaaS, base managée), notre guide de l'&lt;a href="https://neurautech.com/hebergement-cloud-pour-developpeurs/" rel="noopener noreferrer"&gt;hébergement cloud pour développeurs&lt;/a&gt; compare ces plateformes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les pièges des promotions
&lt;/h2&gt;

&lt;p&gt;Un VPS pas cher l'est rarement sur la durée&amp;nbsp;: les pages relevées montrent cinq mécanismes qui font monter la facture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ts72hpd8xkzghj73gni.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ts72hpd8xkzghj73gni.webp" alt="Graphique en haltères&amp;nbsp;: prix d'appel et prix suivant de quatre VPS, LWS VPS M de 4,99 à 19,99&amp;nbsp;€ HT, Hostinger KVM 1 de 5,49 à 11,99&amp;nbsp;€ HT, IONOS VPS S+ de 2 à 5&amp;nbsp;€ HT, OVHcloud VPS-1 de 3,81 à 4,49&amp;nbsp;€ HT sans engagement" width="799" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;La promotion d'un mois.&lt;/strong&gt; LWS passe de 4,99&amp;nbsp;€ HT à 19,99&amp;nbsp;€ HT au deuxième mois&amp;nbsp;: 464,76&amp;nbsp;€ HT sur 24&amp;nbsp;mois (notre calcul).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le paiement d'avance.&lt;/strong&gt; Hostinger demande 131,76&amp;nbsp;€ HT pour 24&amp;nbsp;mois, puis 11,99&amp;nbsp;€ HT par mois&amp;nbsp;; le tarif de 3,81&amp;nbsp;€ HT d'OVHcloud suppose 12&amp;nbsp;mois payés d'avance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La promotion de trois mois.&lt;/strong&gt; IONOS passe de 2&amp;nbsp;€ à 5&amp;nbsp;€ HT au quatrième mois, avec 10&amp;nbsp;€ de mise en service affichés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L'IPv4 en option.&lt;/strong&gt; Chez Scaleway, l'adresse coûte plus que la plus petite instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le HT.&lt;/strong&gt; Hetzner, Hostinger, Scaleway et Infomaniak affichent du HT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les prix TTC affichés par OVHcloud, IONOS et LWS supposent la TVA française de 20&amp;nbsp;%, qu'OVHcloud dit appliquer par défaut&amp;nbsp;; la doctrine fiscale officielle (&lt;a href="https://bofip.impots.gouv.fr/bofip/1380-PGP.html/identifiant=BOI-TVA-LIQ-10-20250514" rel="noopener noreferrer"&gt;BOFiP&lt;/a&gt;) donne le coefficient de conversion pour ce taux. En Belgique, en Suisse ou au Canada, le taux diffère, et un professionnel peut selon sa situation être facturé HT ou récupérer la TVA. Avant de valider, faites le calcul sur 24&amp;nbsp;mois avec le prix suivant.&lt;/p&gt;




&lt;h2&gt;
  
  
  VPS gratuit : les offres réelles et leurs limites
&lt;/h2&gt;

&lt;p&gt;Un VPS gratuit sans limite de durée existe, mais il est petit, soumis à conditions et parfois introuvable (pages relues le 13 novembre 2026).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oracle Cloud Always Free.&lt;/strong&gt; La &lt;a href="https://docs.oracle.com/en-us/iaas/Content/FreeTier/freetier_topic-Always_Free_Resources.htm" rel="noopener noreferrer"&gt;documentation d'Oracle&lt;/a&gt;, relue le 13 novembre, donne «&amp;nbsp;les 1&amp;nbsp;500 premières heures d'OCPU et 9&amp;nbsp;000&amp;nbsp;Go-heures par mois&amp;nbsp;» sur les instances Arm Ampere A1, soit «&amp;nbsp;pour les comptes Always Free, l'équivalent de 2 OCPU et 12&amp;nbsp;Go de mémoire&amp;nbsp;» (notre traduction). S'y ajoutent deux instances AMD de 1/8 d'OCPU et 1&amp;nbsp;Go de RAM, 200&amp;nbsp;Go de stockage en bloc et 10&amp;nbsp;To de trafic sortant par mois. Trois limites&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;les instances doivent être créées dans la région d'origine du compte, qui ne peut plus être changée ensuite selon la &lt;a href="https://docs.oracle.com/en-us/iaas/Content/GSG/Reference/faq.htm" rel="noopener noreferrer"&gt;FAQ d'Oracle&lt;/a&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;une instance est jugée inactive si, sur 7&amp;nbsp;jours, le CPU au 95e centile, le réseau et, pour A1, la mémoire restent sous 20&amp;nbsp;%, et Oracle peut alors la récupérer&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;l'erreur «&amp;nbsp;out of host capacity&amp;nbsp;» signale un manque temporaire de machines gratuites dans la région.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La &lt;a href="https://docs.oracle.com/en-us/iaas/Content/FreeTier/freetier.htm" rel="noopener noreferrer"&gt;page Free Tier d'Oracle&lt;/a&gt; précise que la plupart des utilisateurs doivent fournir un numéro de mobile et une carte bancaire, non débitée sans passage à l'offre payante. L'essai donne 300&amp;nbsp;$ de crédits pour 30&amp;nbsp;jours au plus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Cloud.&lt;/strong&gt; Le &lt;a href="https://docs.cloud.google.com/free/docs/free-cloud-features" rel="noopener noreferrer"&gt;niveau gratuit de Google&lt;/a&gt; inclut une instance e2-micro par mois, dans trois régions des États-Unis seulement, avec 30&amp;nbsp;Go de disque et 1&amp;nbsp;Go de trafic sortant depuis l'Amérique du Nord. Le crédit d'essai est de 300&amp;nbsp;$ sur 90&amp;nbsp;jours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS.&lt;/strong&gt; La &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;page de l'offre gratuite d'AWS&lt;/a&gt; annonce jusqu'à 200&amp;nbsp;$ de crédits et un compte fermé au bout de 6&amp;nbsp;mois. Ce n'est pas un VPS gratuit permanent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Premiers réglages de sécurité d'un VPS
&lt;/h2&gt;

&lt;p&gt;Un VPS pas cher exposé sur Internet reçoit des tentatives de connexion dès sa mise en ligne. L'ordre à suivre sur Debian ou Ubuntu&amp;nbsp;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mettre le système à jour&lt;/strong&gt; avec &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;, puis installer &lt;code&gt;unattended-upgrades&lt;/code&gt; pour les correctifs de sécurité automatiques. Notre point sur les &lt;a href="https://neurautech.com/failles-de-securite-novembre-2026/" rel="noopener noreferrer"&gt;failles de sécurité de novembre 2026&lt;/a&gt; liste les mises à jour prioritaires.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Créer un utilisateur et passer SSH en clés.&lt;/strong&gt; Notre guide des &lt;a href="https://neurautech.com/commandes-linux-de-base/" rel="noopener noreferrer"&gt;commandes Linux de base&lt;/a&gt; explique &lt;code&gt;ssh&lt;/code&gt;, &lt;code&gt;sudo&lt;/code&gt; et les droits de fichiers&amp;nbsp;; les commandes propres au serveur sont ci-dessous.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activer un pare-feu&lt;/strong&gt; qui n'ouvre que SSH, HTTP et HTTPS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activer la double authentification sur le compte de l'hébergeur&lt;/strong&gt; (&lt;a href="https://neurautech.com/double-authentification/" rel="noopener noreferrer"&gt;notre guide&lt;/a&gt;)&amp;nbsp;: il donne accès à la console et aux sauvegardes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Si vous installez WordPress&lt;/strong&gt;, appliquez notre liste pour &lt;a href="https://neurautech.com/securiser-wordpress/" rel="noopener noreferrer"&gt;sécuriser WordPress&lt;/a&gt;, puis testez une restauration.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser deploy &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; usermod -aG sudo deploy
ssh-copy-id deploy@IP_DU_SERVEUR        &lt;span class="c"&gt;# depuis votre poste&lt;/span&gt;
&lt;span class="c"&gt;# dans /etc/ssh/sshd_config ET les fichiers de /etc/ssh/sshd_config.d/ :&lt;/span&gt;
&lt;span class="c"&gt;#   PasswordAuthentication no&lt;/span&gt;
sshd -T &lt;span class="o"&gt;|&lt;/span&gt; grep -i passwordauthentication   &lt;span class="c"&gt;# doit afficher "no"&lt;/span&gt;
systemctl restart ssh
apt install ufw                             &lt;span class="c"&gt;# absent par défaut sur Debian&lt;/span&gt;
ufw allow OpenSSH &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw allow 80,443/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sur de nombreuses images cloud, un fichier de &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; (souvent &lt;code&gt;50-cloud-init.conf&lt;/code&gt;) réactive les mots de passe&amp;nbsp;: modifiez-le aussi, puis vérifiez avec &lt;code&gt;sshd -T&lt;/code&gt;. Deux précautions évitent de perdre l'accès. Testez la connexion par clé dans une deuxième session avant de désactiver les mots de passe, et autorisez SSH avant d'activer le pare-feu.&lt;/p&gt;

&lt;p&gt;Avec Docker, un port publié contourne ufw&amp;nbsp;: la &lt;a href="https://docs.docker.com/engine/network/packet-filtering-firewalls/" rel="noopener noreferrer"&gt;documentation de Docker&lt;/a&gt; indique que ce trafic est détourné avant les règles du pare-feu. Publiez donc vos conteneurs sur &lt;code&gt;127.0.0.1&lt;/code&gt; derrière le reverse proxy, comme le permet l'option &lt;code&gt;-p 127.0.0.1:8080:80&lt;/code&gt; (&lt;a href="https://docs.docker.com/engine/network/port-publishing/" rel="noopener noreferrer"&gt;publication de ports&lt;/a&gt;), ou filtrez avec le pare-feu réseau de l'hébergeur.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Les éléments suivants sont absents ou incertains&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PulseHeberg et Vultr.&lt;/strong&gt; Leurs pages ont bloqué notre lecture automatique&amp;nbsp;; nous ne l'avons pas contournée.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La TVA chez Contabo.&lt;/strong&gt; La page annonce des «&amp;nbsp;taxes applicables incluses&amp;nbsp;», mais la version servie était codée «&amp;nbsp;AD&amp;nbsp;»&amp;nbsp;: la base pour un client français n'est pas établie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plusieurs montants.&lt;/strong&gt; Chez Contabo&amp;nbsp;: frais mensuels, Windows, sauvegarde, prix après 24&amp;nbsp;mois. Chez IONOS&amp;nbsp;: engagement, sauvegarde, HT ou TTC des 10&amp;nbsp;€. Chez Infomaniak&amp;nbsp;: renouvellement et IPv4. Frais de mise en service de Hetzner, Scaleway, LWS et Hostinger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les dates.&lt;/strong&gt; Retour en stock de Hetzner et des VPS Windows de LWS, fin de l'offre «&amp;nbsp;Black Friday&amp;nbsp;» d'Hostinger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L'écart de LWS&lt;/strong&gt; entre 4,99&amp;nbsp;€ HT et les 5,96&amp;nbsp;€ TTC affichés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les performances réelles.&lt;/strong&gt; Nous n'avons loué ni mesuré aucun serveur&amp;nbsp;: vCPU et débit sont ceux annoncés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La page commerciale d'Oracle Cloud&lt;/strong&gt;, qui a refusé notre lecture&amp;nbsp;; les conditions citées viennent de sa documentation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quel est le VPS pas cher le plus fiable pour débuter ?
&lt;/h3&gt;

&lt;p&gt;L'OVHcloud VPS-1 combine un prix sans promotion limitée (3,81&amp;nbsp;€ HT avec 12&amp;nbsp;mois d'engagement, 4,49&amp;nbsp;€ HT sans), un centre de données en France et une sauvegarde quotidienne incluse, selon la &lt;a href="https://www.ovhcloud.com/fr/vps/" rel="noopener noreferrer"&gt;page VPS d'OVHcloud&lt;/a&gt; au 13 novembre 2026. C'est une lecture des pages, pas un test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Existe-t-il un VPS gratuit sans limite de durée ?
&lt;/h3&gt;

&lt;p&gt;Oui, l'offre Always Free d'Oracle Cloud, l'équivalent de 2 OCPU et 12&amp;nbsp;Go de RAM sur processeur Arm selon la &lt;a href="https://docs.oracle.com/en-us/iaas/Content/FreeTier/freetier_topic-Always_Free_Resources.htm" rel="noopener noreferrer"&gt;documentation d'Oracle&lt;/a&gt;. La plupart des inscriptions demandent une carte bancaire, la région d'origine ne peut plus être changée, et une instance inactive 7&amp;nbsp;jours peut être récupérée.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quel hébergeur VPS a des serveurs en France ?
&lt;/h3&gt;

&lt;p&gt;Parmi les offres relevées, OVHcloud (Gravelines, Strasbourg, Roubaix), LWS, Scaleway (Paris) et Hostinger proposent la France. IONOS propose l'Allemagne, l'Espagne, le Royaume-Uni et les États-Unis, Hetzner l'Allemagne et la Finlande pour son entrée de gamme, Infomaniak la Suisse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combien coûte un VPS Windows pas cher ?
&lt;/h3&gt;

&lt;p&gt;Comptez au moins 14&amp;nbsp;€ HT par mois chez IONOS pendant 3&amp;nbsp;mois, puis 22&amp;nbsp;€ HT, selon la &lt;a href="https://www.ionos.fr/serveurs/vps-windows" rel="noopener noreferrer"&gt;page VPS Windows d'IONOS&lt;/a&gt;. Chez OVHcloud, il faut un VPS-2 à 7,21&amp;nbsp;€ HT avec engagement, plus 8&amp;nbsp;€ HT par mois pour l'option Windows selon son catalogue public. Les offres Windows de LWS étaient en rupture le 13 novembre 2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse fondée exclusivement sur les pages de tarifs officielles des hébergeurs, le catalogue public d'OVHcloud et la documentation d'Oracle, de Google, d'AWS et de Docker, relevés le 9 novembre puis relus le 13 novembre 2026. Les pages ont été lues dans leur version française quand elle existe (OVHcloud, IONOS, LWS, Hostinger, Infomaniak) et anglaise sinon (Hetzner, Scaleway, Contabo)&amp;nbsp;; OVHcloud applique par défaut la TVA française, Contabo a servi sa version «&amp;nbsp;AD&amp;nbsp;».&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculs et indépendance.&lt;/strong&gt; Les prix sont repris tels qu'affichés, sans conversion de devise&amp;nbsp;; les calculs par Go, sur 24&amp;nbsp;mois et pour l'IPv4 de Scaleway sont les nôtres. Aucun serveur n'a été loué ni testé, aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur aux hébergeurs mentionnés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un prix périmé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 13 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image&amp;nbsp;: Winston Chen (Unsplash License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vps</category>
      <category>hebergement</category>
      <category>serveurlinux</category>
      <category>ovhcloud</category>
    </item>
    <item>
      <title>Node.js 26 LTS : nouveautés, calendrier et migration</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 13 Nov 2026 21:40:20 +0000</pubDate>
      <link>https://dev.to/neurau_tech/nodejs-26-lts-nouveautes-calendrier-et-migration-4ilc</link>
      <guid>https://dev.to/neurau_tech/nodejs-26-lts-nouveautes-calendrier-et-migration-4ilc</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Node.js 26 est devenu une version LTS (support à long terme) le 28 octobre 2026, avec la version 26.13.0 et le nom de code «&amp;nbsp;Lithium&amp;nbsp;». Sorti le 5 mai 2026, il sera maintenu jusqu'au 30 avril 2029. C'est aussi la dernière ligne publiée selon l'ancien rythme pair et impair&amp;nbsp;: à partir de Node.js 27, chaque version majeure deviendra LTS.&lt;/p&gt;

&lt;p&gt;Cet article fait le point pour un développeur qui tourne sur Node.js 22 ou 24. Il repose sur les sources officielles de Node.js, de Docker et des gestionnaires de versions, consultées le 9 novembre 2026. Nous n'avons pas installé Node.js 26 pour cet article&amp;nbsp;: les exemples de code viennent de la documentation et n'ont pas été exécutés.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 26 est en LTS active depuis le 28 octobre 2026 (version 26.13.0), passera en maintenance le 20 octobre 2027 et arrivera en fin de vie le 30 avril 2029.&lt;/li&gt;
&lt;li&gt;Le moteur V8 passe en 14.6, l'API Temporal est activée par défaut, et npm 11.20.0 est livré avec la version 26.13.0.&lt;/li&gt;
&lt;li&gt;Corepack n'est plus distribué avec Node.js depuis la version 25&amp;nbsp;: un &lt;code&gt;corepack enable&lt;/code&gt; dans un Dockerfile ou un pipeline de CI échouera s'il n'est pas installé à part.&lt;/li&gt;
&lt;li&gt;Plusieurs API sont retirées, dont &lt;code&gt;response.writeHeader()&lt;/code&gt; et les modules &lt;code&gt;_stream_*&lt;/code&gt;, et les modules natifs doivent être recompilés.&lt;/li&gt;
&lt;li&gt;Une publication de sécurité est annoncée pour le 11 novembre 2026 sur les lignes 26, 24 et 22&amp;nbsp;: prévoyez de mettre à jour dès sa sortie.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Node.js 26 LTS : les dates et les versions
&lt;/h2&gt;

&lt;p&gt;Le calendrier officiel fixe trois dates pour Node.js 26&amp;nbsp;: LTS active le 28 octobre 2026, maintenance le 20 octobre 2027, fin de vie le 30 avril 2029 (&lt;a href="https://github.com/nodejs/Release" rel="noopener noreferrer"&gt;calendrier du groupe Release&lt;/a&gt;, consulté le 9 novembre 2026). Les notes de la version 26.13.0 le confirment&amp;nbsp;: elle ne change rien par rapport à 26.12.1, à part les métadonnées qui marquent la ligne comme LTS (&lt;a href="https://nodejs.org/en/blog/release/v26.13.0" rel="noopener noreferrer"&gt;notes de version 26.13.0&lt;/a&gt;, 28 octobre 2026).&lt;/p&gt;

&lt;p&gt;Les lignes 22 et 24 restent supportées, mais en maintenance seulement&amp;nbsp;: correctifs critiques et sécurité. Node.js 24 «&amp;nbsp;Krypton&amp;nbsp;» y est passé le 20 octobre 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ligne&lt;/th&gt;
&lt;th&gt;Statut au 9 novembre 2026&lt;/th&gt;
&lt;th&gt;Dernière version&lt;/th&gt;
&lt;th&gt;V8&lt;/th&gt;
&lt;th&gt;npm livré&lt;/th&gt;
&lt;th&gt;Fin de vie&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 22 «&amp;nbsp;Jod&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;LTS en maintenance&lt;/td&gt;
&lt;td&gt;22.23.4 (20 octobre)&lt;/td&gt;
&lt;td&gt;12.4&lt;/td&gt;
&lt;td&gt;10.9.9&lt;/td&gt;
&lt;td&gt;30 avril 2027&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 24 «&amp;nbsp;Krypton&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;LTS en maintenance&lt;/td&gt;
&lt;td&gt;24.22.2 (27 octobre)&lt;/td&gt;
&lt;td&gt;13.6&lt;/td&gt;
&lt;td&gt;11.19.1&lt;/td&gt;
&lt;td&gt;30 avril 2028&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 26 «&amp;nbsp;Lithium&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;LTS active&lt;/td&gt;
&lt;td&gt;26.13.0 (28 octobre)&lt;/td&gt;
&lt;td&gt;14.6&lt;/td&gt;
&lt;td&gt;11.20.0&lt;/td&gt;
&lt;td&gt;30 avril 2029&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 27&lt;/td&gt;
&lt;td&gt;Alpha&lt;/td&gt;
&lt;td&gt;27.0.0-alpha.0.0.0 (numéro officiel)&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;Non relevé&lt;/td&gt;
&lt;td&gt;30 avril 2030 (prévu)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Les versions, les numéros de V8 et de npm viennent de l'&lt;a href="https://nodejs.org/dist/index.json" rel="noopener noreferrer"&gt;index officiel des versions&lt;/a&gt; et les dates de fin de vie du &lt;a href="https://github.com/nodejs/Release" rel="noopener noreferrer"&gt;calendrier du groupe Release&lt;/a&gt;, relevés le 9 novembre 2026.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwqs5z8f03razp5xont0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwqs5z8f03razp5xont0.webp" alt="Frise du support de Node.js 22, 24, 26 et 27&amp;nbsp;: Node.js 26 en LTS active du 28 octobre 2026 au 20 octobre 2027, puis en maintenance jusqu'au 30 avril 2029" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selon l'&lt;a href="https://nodejs.org/en/blog/announcements/evolving-the-nodejs-release-schedule" rel="noopener noreferrer"&gt;annonce du projet Node.js&lt;/a&gt; du 10 mars 2026, il n'y aura plus qu'une version majeure par an, en avril, promue LTS en octobre. Une phase Alpha de six mois remplace les versions impaires&amp;nbsp;: celle de Node.js 27 s'est ouverte le 28 octobre 2026, et sa première version, numérotée officiellement 27.0.0-alpha.0.0.0, est datée du 29 octobre par l'index. Ces nouvelles lignes auront 30&amp;nbsp;mois de LTS active, sans phase de maintenance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce qui change depuis Node.js 24
&lt;/h2&gt;

&lt;p&gt;La plupart des ruptures entre Node.js 24 et 26 datent de Node.js 25. Les points ci-dessous viennent des journaux de modifications de &lt;a href="https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V25.md" rel="noopener noreferrer"&gt;Node.js 25&lt;/a&gt; et de &lt;a href="https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V26.md" rel="noopener noreferrer"&gt;Node.js 26&lt;/a&gt;, et de la documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  V8 14.6 et Temporal activé par défaut
&lt;/h3&gt;

&lt;p&gt;Node.js 26 embarque V8 14.6, la version de Chromium 146, et active par défaut l'API Temporal, qui remplace avantageusement l'objet &lt;code&gt;Date&lt;/code&gt; pour les dates, les fuseaux et les durées (&lt;a href="https://nodejs.org/en/blog/release/v26.0.0" rel="noopener noreferrer"&gt;notes de version 26.0.0&lt;/a&gt;, 5 mai 2026). V8 14.6 apporte aussi &lt;code&gt;Map.prototype.getOrInsert()&lt;/code&gt;, &lt;code&gt;getOrInsertComputed()&lt;/code&gt; et &lt;code&gt;Iterator.concat()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Un exemple écrit d'après la &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal" rel="noopener noreferrer"&gt;documentation de Temporal sur MDN&lt;/a&gt;, non exécuté&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;aujourdHui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plainDateISO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;echeance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aujourdHui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;months&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;echeance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si vous découvrez ces notions, notre guide pour &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;apprendre JavaScript&lt;/a&gt; reprend les bases du langage avant ces nouvelles API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Corepack n'est plus livré
&lt;/h3&gt;

&lt;p&gt;C'est la réponse à la recherche «&amp;nbsp;node 26 corepack&amp;nbsp;»&amp;nbsp;: Corepack n'est plus distribué avec Node.js depuis la version 25.0.0. Le journal de Node.js 25.0.0 contient le commit «&amp;nbsp;build: stop distributing Corepack&amp;nbsp;», confirmé par la &lt;a href="https://github.com/nodejs/node/blob/main/doc/contributing/distribution.md" rel="noopener noreferrer"&gt;documentation de distribution&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pour continuer à l'utiliser, le &lt;a href="https://github.com/nodejs/corepack" rel="noopener noreferrer"&gt;dépôt de Corepack&lt;/a&gt; indique de l'installer avec npm, puis de l'activer (commandes non exécutées)&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm install -g corepack
corepack &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  TypeScript : le retrait des types est stable
&lt;/h3&gt;

&lt;p&gt;Node.js exécute directement les fichiers &lt;code&gt;.ts&lt;/code&gt; qui n'utilisent que de la syntaxe effaçable&amp;nbsp;: les types sont remplacés par des espaces, sans vérification. Cette fonction est stable depuis Node.js 25.2.0 et 24.12.0, d'après la &lt;a href="https://nodejs.org/api/typescript.html" rel="noopener noreferrer"&gt;documentation TypeScript de Node.js&lt;/a&gt;. En revanche, l'option &lt;code&gt;--experimental-transform-types&lt;/code&gt;, qui transformait la syntaxe non effaçable, est supprimée dans Node.js 26. Restent donc refusés les &lt;code&gt;enum&lt;/code&gt;, les &lt;code&gt;namespace&lt;/code&gt; qui contiennent du code exécutable, les propriétés de paramètres et les alias d'import&amp;nbsp;; un &lt;code&gt;namespace&lt;/code&gt; qui ne contient que des types reste accepté.&lt;/p&gt;

&lt;p&gt;Node.js ignore &lt;code&gt;tsconfig.json&lt;/code&gt; et ne vérifie aucun type&amp;nbsp;: &lt;code&gt;tsc&lt;/code&gt; reste nécessaire en CI. Notre guide pour &lt;a href="https://neurautech.com/apprendre-typescript/" rel="noopener noreferrer"&gt;apprendre TypeScript&lt;/a&gt; détaille l'option &lt;code&gt;erasableSyntaxOnly&lt;/code&gt;, qui fait refuser par le compilateur la syntaxe que Node.js ne sait pas effacer.&lt;/p&gt;

&lt;h3&gt;
  
  
  require(esm) n'est plus expérimental
&lt;/h3&gt;

&lt;p&gt;Charger un module ECMAScript avec &lt;code&gt;require()&lt;/code&gt; n'est plus expérimental depuis Node.js 25.4.0, selon la &lt;a href="https://nodejs.org/api/modules.html" rel="noopener noreferrer"&gt;documentation des modules&lt;/a&gt;. Pour un projet CommonJS qui dépend d'une bibliothèque publiée uniquement en ESM, c'est la fin d'un contournement fréquent. Les modules qui utilisent &lt;code&gt;await&lt;/code&gt; au niveau supérieur restent exclus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le modèle de permissions s'étoffe
&lt;/h3&gt;

&lt;p&gt;Le modèle de permissions, activé avec &lt;code&gt;--permission&lt;/code&gt;, est stable depuis Node.js 23.5.0 et 22.13.0. Depuis, il a gagné &lt;code&gt;--allow-net&lt;/code&gt; (Node.js 25.0.0, encore en développement actif), un mode d'audit &lt;code&gt;--permission-audit&lt;/code&gt; (25.8.0) qui journalise les violations sans bloquer, et &lt;code&gt;process.permission.drop()&lt;/code&gt; (26.3.0 et 24.20.0) pour renoncer à un droit en cours d'exécution (&lt;a href="https://nodejs.org/api/permissions.html" rel="noopener noreferrer"&gt;documentation des permissions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Ce n'est pas une protection contre du code malveillant, prévient la documentation. Depuis Node.js 24.2.0 et 22.17.0, le point d'entrée, ici &lt;code&gt;index.js&lt;/code&gt;, est autorisé en lecture sans option (&lt;a href="https://nodejs.org/api/cli.html#--allow-fs-read" rel="noopener noreferrer"&gt;documentation de &lt;code&gt;--allow-fs-read&lt;/code&gt;&lt;/a&gt;)&amp;nbsp;; les autres fichiers lus doivent être déclarés, un chemin par option, car la virgule n'est plus acceptée comme séparateur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node --permission --allow-fs-read=./config --allow-net index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test runner, fetch, WebSocket et SQLite
&lt;/h3&gt;

&lt;p&gt;Le test runner intégré, stable, gagne &lt;code&gt;--test-randomize&lt;/code&gt; (26.1.0) pour mélanger l'ordre des tests, &lt;code&gt;context.log()&lt;/code&gt; (26.6.0) et &lt;code&gt;--test-coverage-include-all&lt;/code&gt; (26.7.0). La couverture de code reste marquée expérimentale dans la &lt;a href="https://nodejs.org/api/test.html" rel="noopener noreferrer"&gt;documentation du test runner&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;fetch&lt;/strong&gt; est stable depuis Node.js 21 et repose sur Undici, passé en version 8 avec Node.js 26.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSocket&lt;/strong&gt; est un global stable depuis Node.js 22.4.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;node:sqlite&lt;/strong&gt; est en «&amp;nbsp;release candidate&amp;nbsp;» depuis 25.7.0 (&lt;a href="https://nodejs.org/api/sqlite.html" rel="noopener noreferrer"&gt;documentation SQLite&lt;/a&gt;). Dans 26.11.0, &lt;code&gt;DatabaseSync&lt;/code&gt; est renommée &lt;code&gt;Database&lt;/code&gt;&amp;nbsp;; l'ancien nom reste un alias déprécié.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ce qui reste expérimental
&lt;/h3&gt;

&lt;p&gt;Ces ajouts sont marqués expérimentaux dans la documentation&amp;nbsp;: à éviter en production.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;node:ffi&lt;/code&gt;, pour appeler des bibliothèques natives (26.1.0), une API que la documentation dit dangereuse.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;node:vfs&lt;/code&gt;, un système de fichiers virtuel (26.4.0).&lt;/li&gt;
&lt;li&gt;Les Web Workers, derrière &lt;code&gt;--experimental-web-worker&lt;/code&gt; (26.9.0).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;URLPattern&lt;/code&gt;, global depuis Node.js 24.0.0 mais toujours expérimental.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Les API retirées et les ruptures à vérifier
&lt;/h2&gt;

&lt;p&gt;Les retraits sont peu nombreux mais concrets&amp;nbsp;: un appel à une API supprimée lève une erreur au lieu d'un simple avertissement. Pour &lt;code&gt;writeHeader()&lt;/code&gt;, l'&lt;a href="https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V26.md#26.0.0" rel="noopener noreferrer"&gt;entrée du journal de Node.js 26.0.0&lt;/a&gt; parle de &lt;code&gt;http.Server.prototype&lt;/code&gt;, mais la &lt;a href="https://nodejs.org/api/deprecations.html#dep0063-serverresponseprototypewriteheader" rel="noopener noreferrer"&gt;dépréciation DEP0063&lt;/a&gt; précise qu'il s'agit de la méthode de &lt;code&gt;ServerResponse&lt;/code&gt;, la réponse HTTP. Le tableau reprend les principaux, d'après les notes de &lt;a href="https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V25.md" rel="noopener noreferrer"&gt;Node.js 25.0.0&lt;/a&gt;, de &lt;a href="https://nodejs.org/en/blog/release/v26.0.0" rel="noopener noreferrer"&gt;Node.js 26.0.0&lt;/a&gt; et la &lt;a href="https://nodejs.org/api/deprecations.html" rel="noopener noreferrer"&gt;liste des dépréciations&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Changement&lt;/th&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Remplacement indiqué&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;response.writeHeader()&lt;/code&gt; (&lt;code&gt;ServerResponse&lt;/code&gt;) supprimée, DEP0063&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;response.writeHead()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modules &lt;code&gt;_stream_wrap&lt;/code&gt;, &lt;code&gt;_stream_readable&lt;/code&gt; et quatre autres supprimés&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;node:stream&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Option &lt;code&gt;--experimental-transform-types&lt;/code&gt; supprimée&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;Un outil tiers comme &lt;code&gt;tsx&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;module.register()&lt;/code&gt; dépréciée à l'exécution (DEP0205)&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;module.registerHooks()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Balises GCM courtes sans &lt;code&gt;authTagLength&lt;/code&gt; (DEP0182) en fin de vie&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;Préciser &lt;code&gt;authTagLength&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passer un &lt;code&gt;CryptoKey&lt;/code&gt; aux API &lt;code&gt;node:crypto&lt;/code&gt; (DEP0203) déprécié&lt;/td&gt;
&lt;td&gt;26.0.0&lt;/td&gt;
&lt;td&gt;Voir la liste des dépréciations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;SlowBuffer&lt;/code&gt; supprimée&lt;/td&gt;
&lt;td&gt;25.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Buffer.allocUnsafeSlow()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;fs.F_OK&lt;/code&gt;, &lt;code&gt;fs.R_OK&lt;/code&gt;, &lt;code&gt;fs.W_OK&lt;/code&gt;, &lt;code&gt;fs.X_OK&lt;/code&gt; supprimées&lt;/td&gt;
&lt;td&gt;25.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fs.constants&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corepack retiré de la distribution&lt;/td&gt;
&lt;td&gt;25.0.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -g corepack&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Trois ruptures ne se voient pas dans le code. D'abord, les modules natifs doivent être recompilés&amp;nbsp;: &lt;code&gt;NODE_MODULE_VERSION&lt;/code&gt; passe à 147 dans Node.js 26.0.0. Ensuite, depuis Node.js 25, les binaires officiels pour Linux sont liés à &lt;code&gt;libatomic&lt;/code&gt;, que certaines distributions demandent d'installer à part, préviennent les &lt;a href="https://nodejs.org/en/blog/release/v26.13.0" rel="noopener noreferrer"&gt;notes de la version 26.13.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enfin, la compilation depuis les sources exige désormais GCC 13.2 au minimum.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sécurité : 26.12.1 et la publication du 11 novembre
&lt;/h2&gt;

&lt;p&gt;La dernière version de sécurité de la ligne 26 est 26.12.1, publiée le 21 octobre 2026. Le même bulletin renvoie vers 24.22.1 et 22.23.4 pour les deux autres lignes, que l'&lt;a href="https://nodejs.org/dist/index.json" rel="noopener noreferrer"&gt;index officiel&lt;/a&gt; date du 20 octobre. Ce bulletin corrige notamment quatre failles de gravité élevée, dont une écriture hors limites dans le décodeur Brotli (CVE-2026-111497) (&lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;bulletin d'octobre de Node.js&lt;/a&gt;, 21 octobre 2026). Comme 26.13.0 reprend 26.12.1 à l'identique, la version LTS inclut ces correctifs.&lt;/p&gt;

&lt;p&gt;Une nouvelle publication est annoncée pour le mercredi 11 novembre 2026 sur les lignes 26, 24 et 22, avec une gravité maximale «&amp;nbsp;élevée&amp;nbsp;» sur chacune (&lt;a href="https://nodejs.org/en/blog/vulnerability/november-2026-security-releases" rel="noopener noreferrer"&gt;annonce de Node.js&lt;/a&gt;, 3 novembre 2026). Le 9 novembre, elle n'était pas encore publiée&amp;nbsp;: les numéros de version ne sont donc pas connus.&lt;/p&gt;

&lt;p&gt;Nous ne détaillons pas ces failles ici. Notre &lt;a href="https://neurautech.com/failles-de-securite-novembre-2026/" rel="noopener noreferrer"&gt;veille des failles de sécurité de novembre 2026&lt;/a&gt; reprendra ces failles une par une après leur publication, avec les versions à installer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Images Docker : node:26, slim et alpine
&lt;/h2&gt;

&lt;p&gt;Les étiquettes &lt;code&gt;latest&lt;/code&gt;, &lt;code&gt;current&lt;/code&gt;, &lt;code&gt;slim&lt;/code&gt; et &lt;code&gt;alpine&lt;/code&gt; de l'image officielle &lt;code&gt;node&lt;/code&gt; suivent la ligne stable la plus récente&amp;nbsp;: elles pointent vers Node.js 26 depuis la &lt;a href="https://github.com/docker-library/official-images/commit/a4555756f6" rel="noopener noreferrer"&gt;mise à jour du 6 mai 2026&lt;/a&gt; qui a ajouté 26.0.0. Le passage en LTS a déplacé les étiquettes &lt;code&gt;lts&lt;/code&gt;, &lt;code&gt;lts-slim&lt;/code&gt; et &lt;code&gt;lts-alpine&lt;/code&gt;, qui désignaient Node.js 24&amp;nbsp;: elles pointent vers la ligne 26 depuis la &lt;a href="https://github.com/docker-library/official-images/commit/ab8a9d5fa6" rel="noopener noreferrer"&gt;mise à jour du 28 octobre 2026&lt;/a&gt;, d'après le &lt;a href="https://github.com/docker-library/official-images/blob/master/library/node" rel="noopener noreferrer"&gt;fichier des images officielles&lt;/a&gt;. Un Dockerfile sur &lt;code&gt;node:lts&lt;/code&gt; a donc changé de version majeure sans modification de votre part.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Étiquette&lt;/th&gt;
&lt;th&gt;Base&lt;/th&gt;
&lt;th&gt;Architectures&lt;/th&gt;
&lt;th&gt;Pour quel usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;node:26&lt;/code&gt; ou &lt;code&gt;node:26-trixie&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Debian 13 «&amp;nbsp;trixie&amp;nbsp;» complète&lt;/td&gt;
&lt;td&gt;amd64, arm64v8, ppc64le, s390x&lt;/td&gt;
&lt;td&gt;Étape de compilation, outils inclus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node:26-slim&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debian 13 «&amp;nbsp;trixie&amp;nbsp;» allégée&lt;/td&gt;
&lt;td&gt;amd64, arm64v8, ppc64le, s390x&lt;/td&gt;
&lt;td&gt;Image d'exécution par défaut&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node:26-bookworm-slim&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debian 12 «&amp;nbsp;bookworm&amp;nbsp;» allégée&lt;/td&gt;
&lt;td&gt;amd64, arm64v8, ppc64le&lt;/td&gt;
&lt;td&gt;Rester sur Debian 12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node:26-alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Alpine 3.24&lt;/td&gt;
&lt;td&gt;amd64, arm64v8&lt;/td&gt;
&lt;td&gt;Taille minimale, musl au lieu de glibc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node:26.13.0-slim&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Version figée&lt;/td&gt;
&lt;td&gt;Comme &lt;code&gt;26-slim&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Builds reproductibles&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La &lt;a href="https://hub.docker.com/_/node" rel="noopener noreferrer"&gt;page de l'image &lt;code&gt;node&lt;/code&gt; sur Docker Hub&lt;/a&gt; rappelle qu'Alpine utilise la bibliothèque C musl, source d'incompatibilités avec certains modules natifs. Node.js 26.11.0 a toutefois promu Alpine Linux au niveau 2 de support. Les variantes slim, elles, ne contiennent que le strict nécessaire pour exécuter Node.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fomar0xqh6kmvuzkd9vpc.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fomar0xqh6kmvuzkd9vpc.webp" alt="Graphique en barres&amp;nbsp;: taille compressée des images Docker node:26, node:26-slim et node:26-alpine pour amd64, relevée sur Docker Hub le 9 novembre 2026" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selon l'API publique de Docker Hub, le 9 novembre 2026, &lt;code&gt;node:26&lt;/code&gt; pèse 444,9&amp;nbsp;Mo compressés pour amd64, &lt;code&gt;node:26-slim&lt;/code&gt; 85,7&amp;nbsp;Mo et &lt;code&gt;node:26-alpine&lt;/code&gt; 62,9&amp;nbsp;Mo, contre 81,0&amp;nbsp;Mo pour &lt;code&gt;node:24-slim&lt;/code&gt;. Décompressées, les images sont plus lourdes.&lt;/p&gt;

&lt;p&gt;Un Dockerfile en deux étapes, construit d'après la documentation de l'image et non exécuté. L'étape de compilation part de l'image complète, qui contient les outils nécessaires aux modules natifs&amp;nbsp;; l'image finale, en variante slim, reprend les dépendances déjà installées (après &lt;code&gt;npm prune --omit=dev&lt;/code&gt;) au lieu de les réinstaller&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remplacez 26.13.0 par la version de sécurité du 11 novembre dès sa sortie&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; node:26.13.0 AS build
&lt;span class="k"&gt;WORKDIR&lt;/span&gt; /app
&lt;span class="k"&gt;COPY&lt;/span&gt; package*.json ./
&lt;span class="k"&gt;RUN&lt;/span&gt; npm ci
&lt;span class="k"&gt;COPY&lt;/span&gt; . .
&lt;span class="k"&gt;RUN&lt;/span&gt; npm run build
&lt;span class="k"&gt;RUN&lt;/span&gt; npm prune --omit=dev

&lt;span class="k"&gt;FROM&lt;/span&gt; node:26.13.0-slim
&lt;span class="k"&gt;WORKDIR&lt;/span&gt; /app
&lt;span class="k"&gt;ENV&lt;/span&gt; &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="k"&gt;COPY&lt;/span&gt; --from=build /app/package*.json ./
&lt;span class="k"&gt;COPY&lt;/span&gt; --from=build /app/node_modules ./node_modules
&lt;span class="k"&gt;COPY&lt;/span&gt; --from=build /app/dist ./dist
&lt;span class="k"&gt;USER&lt;/span&gt; node
&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;, &lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si les étapes multiples ou les couches sont nouvelles pour vous, commencez par notre tutoriel &lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Migrer depuis Node.js 22 ou 24 : la checklist
&lt;/h2&gt;

&lt;p&gt;La migration vers Node.js 26 se prépare en six étapes. Les commandes viennent des documentations de chaque outil et n'ont pas été exécutées pour cet article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Installez Node.js 26 en local.&lt;/strong&gt; Avec &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;nvm&lt;/a&gt;, &lt;code&gt;nvm install 26&lt;/code&gt;, ou &lt;code&gt;nvm install --reinstall-packages-from=current 'lts/*'&lt;/code&gt; pour récupérer vos paquets globaux. Avec &lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;fnm&lt;/a&gt;, &lt;code&gt;fnm install 26&lt;/code&gt; puis &lt;code&gt;fnm use 26&lt;/code&gt;. Avec &lt;a href="https://mise.jdx.dev/lang/node.html" rel="noopener noreferrer"&gt;mise&lt;/a&gt;, &lt;code&gt;mise use node@26&lt;/code&gt;, qui écrit la version dans &lt;code&gt;mise.toml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Si vous utilisez Volta, &lt;code&gt;volta install node@26&lt;/code&gt; reste possible, mais son &lt;a href="https://github.com/volta-cli/volta" rel="noopener noreferrer"&gt;dépôt officiel&lt;/a&gt; indique que l'outil n'est plus maintenu et recommande de migrer vers mise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Fixez la version dans le projet.&lt;/strong&gt; Un fichier &lt;code&gt;.nvmrc&lt;/code&gt; contenant &lt;code&gt;26&lt;/code&gt; est lu par nvm à chaque &lt;code&gt;nvm use&lt;/code&gt; ou &lt;code&gt;nvm install&lt;/code&gt; (&lt;a href="https://github.com/nvm-sh/nvm#nvmrc" rel="noopener noreferrer"&gt;documentation de nvm&lt;/a&gt;)&amp;nbsp;; nvm ne lit pas &lt;code&gt;.node-version&lt;/code&gt;. fnm lit les deux fichiers, tout comme l'option &lt;code&gt;node-version-file&lt;/code&gt; de &lt;code&gt;actions/setup-node&lt;/code&gt;, et mise les lit une fois l'option &lt;code&gt;idiomatic_version_file_enable_tools&lt;/code&gt; activée (&lt;a href="https://mise.jdx.dev/lang/node.html" rel="noopener noreferrer"&gt;documentation de mise&lt;/a&gt;). Dans &lt;code&gt;package.json&lt;/code&gt;, le champ &lt;code&gt;engines&lt;/code&gt; déclare les versions acceptées&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;"engines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;=22"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sans l'option &lt;code&gt;engine-strict&lt;/code&gt;, npm ne fait qu'avertir quand la version ne correspond pas, d'après la &lt;a href="https://docs.npmjs.com/cli/configuring-npm/package-json/#engines" rel="noopener noreferrer"&gt;documentation de &lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt;. Relevez la borne à &lt;code&gt;&amp;gt;=24&lt;/code&gt; ou &lt;code&gt;&amp;gt;=26&lt;/code&gt; le jour où vous retirez une ligne de la matrice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Élargissez la matrice de CI.&lt;/strong&gt; Avec l'action &lt;code&gt;actions/setup-node&lt;/code&gt;, testez sur les lignes encore supportées avant de couper l'ancienne&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v7&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node-version }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notre &lt;a href="https://neurautech.com/github-actions-tutoriel/" rel="noopener noreferrer"&gt;tutoriel GitHub Actions&lt;/a&gt; monte justement une matrice Node.js 24 et 26 pour une API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cherchez les API retirées.&lt;/strong&gt; Lancez vos tests avec &lt;code&gt;node --throw-deprecation&lt;/code&gt; pour transformer chaque avertissement en erreur, puis cherchez &lt;code&gt;writeHeader&lt;/code&gt;, &lt;code&gt;_stream_&lt;/code&gt;, &lt;code&gt;SlowBuffer&lt;/code&gt;, &lt;code&gt;fs.F_OK&lt;/code&gt;, &lt;code&gt;module.register&lt;/code&gt; et &lt;code&gt;--experimental-transform-types&lt;/code&gt; dans le code et les scripts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Remplacez &lt;code&gt;corepack enable&lt;/code&gt;.&lt;/strong&gt; Dans les Dockerfile et les pipelines, ajoutez &lt;code&gt;npm install -g corepack&lt;/code&gt; avant, ou installez directement votre gestionnaire de paquets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Recompilez et mettez à jour les images.&lt;/strong&gt; Relancez &lt;code&gt;npm ci&lt;/code&gt;, qui supprime &lt;code&gt;node_modules&lt;/code&gt; avant d'installer et recompile ainsi les modules natifs, figez l'image Docker sur &lt;code&gt;26.13.0-slim&lt;/code&gt; ou sur la version de sécurité du 11 novembre, et vérifiez la présence de &lt;code&gt;libatomic&lt;/code&gt; sur vos serveurs Linux hors conteneur.&lt;/p&gt;

&lt;p&gt;Pour une API Express, notre guide pour &lt;a href="https://neurautech.com/creer-une-api-rest-avec-node-js-et-express-en-2026/" rel="noopener noreferrer"&gt;créer une API REST avec Node.js et Express&lt;/a&gt; vise déjà Node.js 24 ou plus. Côté front, notre article sur &lt;a href="https://neurautech.com/next-js/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; indique la version minimale de Node.js exigée par Next.js 16.&lt;/p&gt;




&lt;h2&gt;
  
  
  Faut-il passer à Node.js 26 maintenant ?
&lt;/h2&gt;

&lt;p&gt;Pour un nouveau projet, oui&amp;nbsp;: Node.js 26 est la seule ligne en LTS active, celle qui reçoit les nouveautés validées par l'équipe de publication jusqu'au 20 octobre 2027. Son support court jusqu'au 30 avril 2029, un an de plus que Node.js 24 selon le &lt;a href="https://github.com/nodejs/Release" rel="noopener noreferrer"&gt;calendrier officiel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pour un projet en production sur Node.js 24, rien ne presse&amp;nbsp;: la ligne 24 reste supportée jusqu'au 30 avril 2028 et reçoit les mêmes correctifs de sécurité. Planifiez la migration après un passage complet de vos tests en CI.&lt;/p&gt;

&lt;p&gt;Pour un projet sur Node.js 22, la date à retenir est le 30 avril 2027, fin de vie de la ligne. Il reste moins de six mois. Passer directement à Node.js 26 évite une seconde migration en 2028, à condition de traiter en une fois les ruptures de quatre versions majeures, de 23 à 26.&lt;/p&gt;

&lt;p&gt;Dans tous les cas, attendez la publication du 11 novembre 2026 pour figer une version dans vos images, plutôt que de déployer 26.13.0 deux jours avant un correctif de sécurité annoncé.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Cet article est une synthèse documentaire, sans test sur machine. Les points suivants sont absents ou incertains&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Les performances.&lt;/strong&gt; Nous n'avons mené aucun banc d'essai et n'avons pas trouvé de mesure indépendante comparant Node.js 24 et 26.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le contenu de la publication du 11 novembre.&lt;/strong&gt; Ni les failles ni les numéros de version n'étaient publiés le 9 novembre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le comportement exact de &lt;code&gt;localStorage&lt;/code&gt;, activé par défaut depuis Node.js 25, sans &lt;code&gt;--localstorage-file&lt;/code&gt;.&lt;/strong&gt; Le journal de Node.js 26.0.0 et la documentation de la version 26.13.0 décrivent deux comportements différents. Testez-le si vous en dépendez.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le rétroportage vers Node.js 24.&lt;/strong&gt; Certaines nouveautés citées existent aussi dans des versions 24.x récentes, comme &lt;code&gt;process.permission.drop()&lt;/code&gt;. Nous n'avons pas vérifié chaque fonction une par une.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quand Node.js 26 est-il passé en LTS ?
&lt;/h3&gt;

&lt;p&gt;Le 28 octobre 2026, avec la version 26.13.0 et le nom de code «&amp;nbsp;Lithium&amp;nbsp;», selon les &lt;a href="https://nodejs.org/en/blog/release/v26.13.0" rel="noopener noreferrer"&gt;notes de version officielles&lt;/a&gt;. La ligne passera en maintenance le 20 octobre 2027 et sera en fin de vie le 30 avril 2029.&lt;/p&gt;

&lt;h3&gt;
  
  
  Corepack est-il encore inclus dans Node.js 26 ?
&lt;/h3&gt;

&lt;p&gt;Non. Corepack n'est plus distribué avec Node.js depuis la version 25.0.0, d'après le &lt;a href="https://github.com/nodejs/corepack" rel="noopener noreferrer"&gt;dépôt de Corepack&lt;/a&gt;. Installez-le avec &lt;code&gt;npm install -g corepack&lt;/code&gt;, puis lancez &lt;code&gt;corepack enable&lt;/code&gt;, ou installez pnpm et Yarn par un autre moyen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quelle image Docker choisir pour Node.js 26 ?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;node:26-slim&lt;/code&gt; est le bon choix par défaut pour exécuter une application&amp;nbsp;: 85,7&amp;nbsp;Mo compressés pour amd64 sur &lt;a href="https://hub.docker.com/_/node" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; le 9 novembre 2026, contre 444,9&amp;nbsp;Mo pour l'image complète. &lt;code&gt;node:26-alpine&lt;/code&gt; est plus légère, mais utilise musl, ce qui peut gêner des modules natifs. En production, figez une version précise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js 26 exécute-t-il TypeScript sans compilation ?
&lt;/h3&gt;

&lt;p&gt;En partie. Node.js exécute les fichiers &lt;code&gt;.ts&lt;/code&gt; qui n'utilisent que de la syntaxe effaçable, sans vérifier les types, une fonction stable selon la &lt;a href="https://nodejs.org/api/typescript.html" rel="noopener noreferrer"&gt;documentation TypeScript de Node.js&lt;/a&gt;. Les &lt;code&gt;enum&lt;/code&gt;, les &lt;code&gt;namespace&lt;/code&gt; contenant du code exécutable et les propriétés de paramètres sont refusés, car l'option &lt;code&gt;--experimental-transform-types&lt;/code&gt; a été supprimée dans Node.js 26.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;. Pour vous entraîner sur les bases du langage, voyez aussi nos &lt;a href="https://neurautech.com/exercices-javascript-corriges/" rel="noopener noreferrer"&gt;exercices JavaScript corrigés&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Analyse fondée exclusivement sur des sources publiques consultées le 9 novembre 2026&amp;nbsp;: notes de version, journaux, documentation et bulletins de sécurité de Node.js, calendrier du groupe Release, images officielles Docker, documentations de nvm, fnm, mise, Volta, Corepack et npm. Node.js 26 n'a pas été installé et aucun code n'a été exécuté. Aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur aux projets mentionnés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou une version périmée&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 9 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image&amp;nbsp;: İsmail Enes Ayhan (Unsplash License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>lts</category>
      <category>docker</category>
    </item>
    <item>
      <title>Meilleur LLM local : 8 modèles mesurés sur un portable de 8 Go</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Sat, 07 Nov 2026 12:54:33 +0000</pubDate>
      <link>https://dev.to/neurau_tech/meilleur-llm-local-8-modeles-mesures-sur-un-portable-de-8-go-4l74</link>
      <guid>https://dev.to/neurau_tech/meilleur-llm-local-8-modeles-mesures-sur-un-portable-de-8-go-4l74</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Le meilleur LLM local dépend d'abord de votre machine, et la plupart des comparatifs n'en mesurent aucune. Nous avons donc fait tourner 8 modèles open-weight récents avec Ollama sur un portable ordinaire, sans carte graphique dédiée et avec 8&amp;nbsp;Go de mémoire, les 6 et 7 novembre 2026. Chaque modèle a reçu les mêmes consignes&amp;nbsp;: 6 exercices de code vérifiés par des tests unitaires, 8 questions en français à réponse connue et un résumé noté sur une grille fixée à l'avance. Nous les avons ensuite confrontées aux chiffres publiés.&lt;/p&gt;

&lt;p&gt;Sur cette machine, Gemma 4 E2B est le seul à réussir tous les tests de code et toutes les questions, au prix de 47&amp;nbsp;secondes de chargement. Ministral 3 3B le suit (5 tests de code sur 6, 8 questions sur 8) et se charge en 17&amp;nbsp;secondes. En vitesse, l'écart reste faible&amp;nbsp;: de 5 à 7,5&amp;nbsp;tokens par seconde en génération.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sur un portable à 8&amp;nbsp;Go sans GPU, les modèles de 1,9 à 4,6&amp;nbsp;milliards de paramètres (selon Ollama) génèrent entre 5,0 et 7,5&amp;nbsp;tokens par seconde (médiane de 3 exécutions, sur secteur).&lt;/li&gt;
&lt;li&gt;Gemma 4 E2B réussit 6 tests de code sur 6 et 8 questions sur 8&amp;nbsp;; Ministral 3 3B et Qwen3.5 4B réussissent 5 tests sur 6. Llama 3.2 3B et Qwen3.5 2B n'en réussissent qu'un.&lt;/li&gt;
&lt;li&gt;La lecture du prompt est le vrai goulot&amp;nbsp;: 14 à 43&amp;nbsp;tokens par seconde, soit 15 à 45&amp;nbsp;secondes d'attente pour un texte de 600&amp;nbsp;tokens.&lt;/li&gt;
&lt;li&gt;Des mesures publiées sur des portables à 16 et 32&amp;nbsp;Go sont plus rapides&amp;nbsp;: processeur, système et mémoire diffèrent, le manque de mémoire est une explication probable. Notre 7B a planté une fois et n'a pas dépassé 2&amp;nbsp;tokens par seconde (mesure indicative).&lt;/li&gt;
&lt;li&gt;Ce sont les résultats d'une machine et d'un petit jeu de tests, pas un classement général.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;L'installation d'Ollama, la quantification et l'API locale sont expliquées dans notre guide &lt;a href="https://neurautech.com/llm-local-ollama/" rel="noopener noreferrer"&gt;LLM local avec Ollama&lt;/a&gt;. Cet article ne les répète pas&amp;nbsp;: il donne des mesures.&lt;/p&gt;




&lt;h2&gt;
  
  
  La machine et les 8 modèles
&lt;/h2&gt;

&lt;p&gt;Nous avons choisi un portable courant, sans carte graphique dédiée. Pour choisir une machine plus adaptée, voyez notre comparatif du &lt;a href="https://neurautech.com/meilleur-laptop-pour-developpeur-tous-budgets-2026/" rel="noopener noreferrer"&gt;meilleur laptop pour développeur&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Élément&lt;/th&gt;
&lt;th&gt;Valeur relevée le 6 novembre 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ordinateur&lt;/td&gt;
&lt;td&gt;Huawei NBLB-WAX9N (portable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processeur&lt;/td&gt;
&lt;td&gt;Intel Core i5-10210U, 4 cœurs, 8 threads, 1,6 GHz de base&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mémoire&lt;/td&gt;
&lt;td&gt;8&amp;nbsp;Go de DDR4-2667 (2 barrettes de 4&amp;nbsp;Go)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphique&lt;/td&gt;
&lt;td&gt;Intel UHD Graphics intégré, écarté par Ollama&amp;nbsp;: calcul sur le processeur seul&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Système&lt;/td&gt;
&lt;td&gt;Windows 11 Famille, build 26300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logiciel&lt;/td&gt;
&lt;td&gt;Ollama 0.40.15, archive officielle pour Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Applications ouvertes&lt;/td&gt;
&lt;td&gt;VS Code, Chrome et un terminal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Les modèles viennent de la &lt;a href="https://ollama.com/library" rel="noopener noreferrer"&gt;bibliothèque Ollama&lt;/a&gt;, consultée le 6 novembre 2026&amp;nbsp;: des familles récentes qui tiennent dans 8&amp;nbsp;Go, avec l'étiquette par défaut de &lt;code&gt;ollama pull&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Étiquette Ollama&lt;/th&gt;
&lt;th&gt;Paramètres&lt;/th&gt;
&lt;th&gt;Quantification&lt;/th&gt;
&lt;th&gt;Téléchargement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 2B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.5:2b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1,9 Md&lt;/td&gt;
&lt;td&gt;Q8_0&lt;/td&gt;
&lt;td&gt;2,7&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 3B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,1 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;1,9&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama 3.2 3B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;llama3.2:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,2 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;2,0&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ministral 3 3B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ministral-3:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,8 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;3,0&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phi-4-mini&lt;/td&gt;
&lt;td&gt;&lt;code&gt;phi4-mini&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,8 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;2,5&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 4B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.5:4b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4,2 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;3,3&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gemma4:e2b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4,6 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;4,6&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 7B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:7b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,6 Md&lt;/td&gt;
&lt;td&gt;Q4_K_M&lt;/td&gt;
&lt;td&gt;4,7&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Paramètres et quantification sont ceux que renvoie Ollama. Gemma 4 E2B pèse plus que son nom ne le laisse penser&amp;nbsp;: sa &lt;a href="https://ai.google.dev/gemma/docs/core/model_card_4" rel="noopener noreferrer"&gt;fiche officielle&lt;/a&gt; indique 2,3&amp;nbsp;milliards de paramètres effectifs mais 5,1&amp;nbsp;milliards avec les tables d'embeddings.&lt;/p&gt;

&lt;h2&gt;
  
  
  La méthode
&lt;/h2&gt;

&lt;p&gt;Les réglages étaient identiques pour tous&amp;nbsp;: température 0, graine fixée à 42, contexte de 4&amp;nbsp;096&amp;nbsp;tokens, mode «&amp;nbsp;réflexion&amp;nbsp;» désactivé (&lt;code&gt;think: false&lt;/code&gt;), un seul modèle chargé à la fois. Les durées viennent de l'API locale d'Ollama (&lt;a href="https://docs.ollama.com/api/usage" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vitesse.&lt;/strong&gt; La même question («&amp;nbsp;Explique en cinq phrases à un développeur débutant ce qu'est un index dans une base de données relationnelle&amp;nbsp;») a été posée trois fois, modèle déchargé avant chaque essai&amp;nbsp;: le chargement est mesuré à froid. Pour la lecture d'un long prompt, le texte à résumer (environ 600&amp;nbsp;tokens) a été envoyé trois fois, modèle déchargé pour éviter le cache. Nous publions la médiane.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code.&lt;/strong&gt; Six fonctions Python, chacune vérifiée par des tests unitaires exécutés sur la machine&amp;nbsp;: &lt;code&gt;fizzbuzz&lt;/code&gt;, validation de parenthèses, chiffres romains, fusion d'intervalles, conversion d'une durée comme «&amp;nbsp;1h30m15s&amp;nbsp;» en secondes, mots les plus fréquents d'un texte français. C'est le niveau de nos &lt;a href="https://neurautech.com/exercices-python-debutant-corriges/" rel="noopener noreferrer"&gt;exercices Python corrigés&lt;/a&gt;, pas celui d'un projet réel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions en français.&lt;/strong&gt; Huit questions à réponse unique&amp;nbsp;: capitale de l'Australie, heure d'arrivée d'un train, règle de trois, plus grand nombre premier sous 50, auteur des «&amp;nbsp;Misérables&amp;nbsp;», énigme «&amp;nbsp;Marie a 3 frères, chacun a 2 sœurs&amp;nbsp;», prise de la Bastille, baisse puis hausse de 25&amp;nbsp;%. Le modèle devait finir par une ligne «&amp;nbsp;Réponse&amp;nbsp;: ...&amp;nbsp;», lue automatiquement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résumé.&lt;/strong&gt; Un compte rendu de réunion fictif, à résumer en 80&amp;nbsp;mots. La grille, fixée avant les mesures, donne 5&amp;nbsp;points&amp;nbsp;: décision, date, budget, risque principal, et 100&amp;nbsp;mots au plus en français. Les réponses étaient plafonnées à 128&amp;nbsp;tokens pour la vitesse, 450 pour le code, 160 pour les questions et 200 pour le résumé.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vitesse : ce que donne un CPU seul
&lt;/h2&gt;

&lt;p&gt;Sur ce processeur, aucun modèle ne dépasse 7,5&amp;nbsp;tokens par seconde en génération. Mesures du 7 novembre 2026, dans une même session, sur secteur du début à la fin de chaque modèle.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Chargement à froid&lt;/th&gt;
&lt;th&gt;Lecture du prompt long&lt;/th&gt;
&lt;th&gt;Génération&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 2B&lt;/td&gt;
&lt;td&gt;10,9 s&lt;/td&gt;
&lt;td&gt;19,9 tok/s&lt;/td&gt;
&lt;td&gt;7,5 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 3B&lt;/td&gt;
&lt;td&gt;9,0 s&lt;/td&gt;
&lt;td&gt;24,8 tok/s&lt;/td&gt;
&lt;td&gt;6,7 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ministral 3 3B&lt;/td&gt;
&lt;td&gt;16,7 s&lt;/td&gt;
&lt;td&gt;20,0 tok/s&lt;/td&gt;
&lt;td&gt;6,4 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;47,5 s&lt;/td&gt;
&lt;td&gt;43,0 tok/s&lt;/td&gt;
&lt;td&gt;6,3 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama 3.2 3B&lt;/td&gt;
&lt;td&gt;8,7 s&lt;/td&gt;
&lt;td&gt;23,1 tok/s&lt;/td&gt;
&lt;td&gt;6,1 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phi-4-mini&lt;/td&gt;
&lt;td&gt;8,8 s&lt;/td&gt;
&lt;td&gt;18,2 tok/s&lt;/td&gt;
&lt;td&gt;6,1 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 4B&lt;/td&gt;
&lt;td&gt;11,1 s&lt;/td&gt;
&lt;td&gt;13,7 tok/s&lt;/td&gt;
&lt;td&gt;5,0 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Médiane de 3 exécutions. Mesures NeurauTech du 7 novembre 2026, Ollama 0.40.15, Core i5-10210U, 8&amp;nbsp;Go, sur secteur. Avec 3 exécutions seulement, un écart de moins de 1&amp;nbsp;token par seconde entre deux modèles n'est pas significatif. Qwen2.5-Coder 7B est traité à part, plus bas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcfvgswpm5jshkw6iqxx.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcfvgswpm5jshkw6iqxx.webp" alt="Graphique en barres&amp;nbsp;: vitesse de génération médiane de 7 modèles sur un portable sans GPU, de 5,0&amp;nbsp;tokens par seconde pour Qwen3.5 4B à 7,5 pour Qwen3.5 2B" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La lecture du prompt compte plus que la génération&amp;nbsp;: à 14 à 43&amp;nbsp;tokens par seconde, un texte de 600&amp;nbsp;tokens impose 15 à 45&amp;nbsp;secondes d'attente avant le premier mot. Un assistant de code qui envoie un fichier entier, ou un système &lt;a href="https://neurautech.com/rag-retrieval-augmented-generation/" rel="noopener noreferrer"&gt;RAG&lt;/a&gt; qui ajoute des passages au prompt, devient vite pénible sur ce type de machine. Gemma 4 E2B lit le prompt 1,7 fois plus vite que le suivant (médiane de 43,0 contre 24,8&amp;nbsp;tokens par seconde, avec des essais de 38 à 83&amp;nbsp;tokens par seconde), ce qui compense en partie son chargement.&lt;/p&gt;

&lt;p&gt;Le chargement prend 9 à 17&amp;nbsp;secondes, mais 47,5&amp;nbsp;secondes pour Gemma 4 E2B. Ollama garde le modèle chargé 5&amp;nbsp;minutes après la dernière requête (réglage &lt;code&gt;OLLAMA_KEEP_ALIVE&lt;/code&gt; par défaut, relevé dans le journal du serveur)&amp;nbsp;: ce délai ne se paie qu'au premier appel ou après une pause. Une première série faite en partie sur batterie a été écartée, car les vitesses n'étaient pas comparables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qualité : code exécuté, questions et résumé
&lt;/h2&gt;

&lt;p&gt;Gemma 4 E2B est le seul modèle sans faute sur nos tests. Ces scores ne dépendent pas de l'alimentation&amp;nbsp;: avec une température de 0 et une graine fixe, le résumé, répété sur batterie puis sur secteur, est resté identique mot pour mot&amp;nbsp;; code et questions n'ont été passés qu'une fois.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Code (tests réussis)&lt;/th&gt;
&lt;th&gt;Questions en français&lt;/th&gt;
&lt;th&gt;Résumé (grille sur 5)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;6 / 6&lt;/td&gt;
&lt;td&gt;8 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ministral 3 3B&lt;/td&gt;
&lt;td&gt;5 / 6&lt;/td&gt;
&lt;td&gt;8 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 4B&lt;/td&gt;
&lt;td&gt;5 / 6&lt;/td&gt;
&lt;td&gt;7 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 3B&lt;/td&gt;
&lt;td&gt;4 / 6&lt;/td&gt;
&lt;td&gt;8 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phi-4-mini&lt;/td&gt;
&lt;td&gt;2 / 6&lt;/td&gt;
&lt;td&gt;7 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 2B&lt;/td&gt;
&lt;td&gt;1 / 6&lt;/td&gt;
&lt;td&gt;6 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama 3.2 3B&lt;/td&gt;
&lt;td&gt;1 / 6&lt;/td&gt;
&lt;td&gt;5 / 8&lt;/td&gt;
&lt;td&gt;5 / 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 7B&lt;/td&gt;
&lt;td&gt;Non mesuré&lt;/td&gt;
&lt;td&gt;Non mesuré&lt;/td&gt;
&lt;td&gt;Non mesuré&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Mesures NeurauTech, 6 et 7 novembre 2026. Température 0, graine 42, contexte 4&amp;nbsp;096&amp;nbsp;tokens. Les scores de six modèles viennent de la première série (6 et 7 novembre)&amp;nbsp;: Gemma 4 E2B, Qwen2.5-Coder 3B, Qwen3.5 2B et Qwen3.5 4B y ont tourné sur batterie, Llama 3.2 3B et Phi-4-mini sur secteur. Seule la vitesse de cette série a été écartée. Ministral 3 3B a été noté le 7 novembre sur secteur. Le test de qualité de Qwen2.5-Coder 7B a été arrêté avant la fin.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxu199rn086ilgpb0u9w.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxu199rn086ilgpb0u9w.webp" alt="Graphique à points&amp;nbsp;: part des tests de code, des questions et des points de résumé réussis par chaque modèle, pour trouver le meilleur LLM local sur un portable de 8&amp;nbsp;Go" width="799" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le code départage les modèles.&lt;/strong&gt; Seul Gemma 4 E2B a réussi la conversion de durée («&amp;nbsp;1h30m15s&amp;nbsp;» en secondes)&amp;nbsp;; Qwen2.5-Coder 3B, Qwen3.5 4B et Ministral 3 3B ont écrit des fonctions qui plantent sur cette entrée. Les petits généralistes font des erreurs plus basiques&amp;nbsp;: Qwen3.5 2B accepte «&amp;nbsp;(]&amp;nbsp;» comme une expression bien parenthésée, Phi-4-mini rend deux fois du code qui ne compile pas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les questions piègent surtout sur le raisonnement.&lt;/strong&gt; L'énigme des sœurs (réponse&amp;nbsp;: 2) a été manquée par Qwen3.5 2B, qui répond 4, et par Llama 3.2 3B, qui répond 7. Phi-4-mini annonce 60 euros au lieu de 75 pour la baisse puis la hausse de 25&amp;nbsp;%. Trois échecs tiennent à nos règles&amp;nbsp;: Llama 3.2 3B a écrit deux fois «&amp;nbsp;Réponse&amp;nbsp;: ...&amp;nbsp;» au lieu de recopier sa bonne réponse (capitale et Bastille), et Qwen3.5 4B a dépassé le plafond de 160&amp;nbsp;tokens avant de conclure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le résumé ne départage personne&amp;nbsp;:&lt;/strong&gt; 5 sur 5 pour tous, notre grille était trop facile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mémoire : la vraie limite d'un portable de 8 Go
&lt;/h2&gt;

&lt;p&gt;Sur 8&amp;nbsp;Go partagés avec Windows, VS Code et Chrome, un modèle 7B ne passe pas confortablement. Au premier essai sur secteur, Qwen2.5-Coder 7B s'est chargé en 113&amp;nbsp;secondes et a généré à 1,2&amp;nbsp;token par seconde, puis le processus d'inférence d'Ollama s'est arrêté au rechargement suivant («&amp;nbsp;connexion fermée de force par l'hôte distant&amp;nbsp;»). Au second essai, il a tenu trois chargements (54 à 87&amp;nbsp;secondes) pour 1,0 à 2,0&amp;nbsp;tokens par seconde. Le premier essai n'a donné qu'une exécution et l'ordinateur a été débranché pendant le second&amp;nbsp;: tous ces chiffres sont indicatifs.&lt;/p&gt;

&lt;p&gt;Pour les modèles de 1,9 à 4,6&amp;nbsp;milliards de paramètres (selon Ollama), le pic de mémoire occupé par Ollama est resté entre 2,1 et 3,2&amp;nbsp;Go. Pendant chaque test, la mémoire disponible du système est tombée à presque zéro selon notre relevé, Windows compressant et déplaçant le reste vers le disque.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbugzpnoe8yuuvmuir8g9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbugzpnoe8yuuvmuir8g9.webp" alt="Nuage de points&amp;nbsp;: pic de mémoire occupé par Ollama et vitesse de génération pour 7 modèles locaux, de 2,1 à 3,2&amp;nbsp;Go" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette mesure (mémoire de travail des processus Ollama, relevée toutes les 0,25 seconde) sous-estime la place réelle quand Windows manque de mémoire&amp;nbsp;: Gemma 4 E2B, avec un fichier de 4,6&amp;nbsp;Go, n'affiche que 2,5&amp;nbsp;Go de pic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nos mesures face aux chiffres publiés
&lt;/h2&gt;

&lt;p&gt;Les chiffres publiés montrent des vitesses plus élevées sur d'autres machines, mieux dotées en mémoire, et les scores des éditeurs nuancent notre classement en code. Lus le 7 novembre 2026, ils sont présentés à part, car les conditions diffèrent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vitesse sur processeur seul.&lt;/strong&gt; Nous n'avons trouvé que deux mesures publiées avec un matériel précis. Système, logiciel, mémoire et méthode diffèrent des nôtres&amp;nbsp;: la comparaison n'est qu'indicative.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Machine&lt;/th&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Génération&lt;/th&gt;
&lt;th&gt;Lecture du prompt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NeurauTech, 7 nov. 2026&lt;/td&gt;
&lt;td&gt;i5-10210U, 8&amp;nbsp;Go DDR4, Windows, Ollama 0.40.15&lt;/td&gt;
&lt;td&gt;Llama 3.2 3B (Q4_K_M)&lt;/td&gt;
&lt;td&gt;6,1 tok/s&lt;/td&gt;
&lt;td&gt;23,1 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://jtmoulia.srht.site/log/2024-11-16/" rel="noopener noreferrer"&gt;jtmoulia&lt;/a&gt;, 16 nov. 2024&lt;/td&gt;
&lt;td&gt;i7-1185G7, 32&amp;nbsp;Go DDR4, Linux, Ollama 0.4.2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;llama3.2:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;14 tok/s&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://jtmoulia.srht.site/log/2024-11-16/" rel="noopener noreferrer"&gt;jtmoulia&lt;/a&gt;, 16 nov. 2024&lt;/td&gt;
&lt;td&gt;Même portable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:7b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 tok/s&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.mgroeber.de/benchmarking-llamacpp-on-legacy-hardware-2.html" rel="noopener noreferrer"&gt;Marcus Groeber&lt;/a&gt;, 2 févr. 2026&lt;/td&gt;
&lt;td&gt;i7-8550U, 16&amp;nbsp;Go, llama.cpp, 8 threads&lt;/td&gt;
&lt;td&gt;Llama 7B (Q4_0)&lt;/td&gt;
&lt;td&gt;6,37 tok/s&lt;/td&gt;
&lt;td&gt;16,29 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le portable de jtmoulia, mesuré avec une seule consigne et une méthode non détaillée, avait 32&amp;nbsp;Go&amp;nbsp;: il génère plus de deux fois plus vite que nous sur Llama 3.2 3B. Le portable de Marcus Groeber, un processeur de 2018 avec 16&amp;nbsp;Go, obtient 6,37&amp;nbsp;tokens par seconde avec un modèle 7B dans l'outil de mesure &lt;code&gt;llama-bench&lt;/code&gt; de llama.cpp. Nous ne pouvons pas isoler la cause&amp;nbsp;: processeur, système, logiciel et mémoire diffèrent. La mémoire est une piste probable, car la mémoire disponible tombait à presque zéro pendant nos tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scores publiés par les éditeurs.&lt;/strong&gt; Ces chiffres viennent des fiches officielles et ne sont pas vérifiés de façon indépendante. Ils sont obtenus dans des conditions que les fiches ne détaillent pas toujours (quantification, mode «&amp;nbsp;réflexion&amp;nbsp;»), sur des tests qui changent d'un éditeur à l'autre&amp;nbsp;: ne comparez que des scores du même test.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Code (score publié par l'éditeur)&lt;/th&gt;
&lt;th&gt;Connaissances&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 4B&lt;/td&gt;
&lt;td&gt;LiveCodeBench v6&amp;nbsp;: 55,8&lt;/td&gt;
&lt;td&gt;MMLU-Pro&amp;nbsp;: 79,1&amp;nbsp;; MMMLU&amp;nbsp;: 76,1&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/Qwen/Qwen3.5-4B" rel="noopener noreferrer"&gt;Fiche Qwen&lt;/a&gt;, consultée le 7 nov. 2026, mode non précisé (réflexion par défaut)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;LiveCodeBench v6&amp;nbsp;: 44,0&amp;nbsp;%&lt;/td&gt;
&lt;td&gt;MMLU Pro&amp;nbsp;: 60,0&amp;nbsp;%&amp;nbsp;; MMMLU&amp;nbsp;: 67,4&amp;nbsp;%&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://ai.google.dev/gemma/docs/core/model_card_4" rel="noopener noreferrer"&gt;Fiche Google&lt;/a&gt;, consultée le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3.5 2B&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;td&gt;MMLU-Pro&amp;nbsp;: 55,3 sans réflexion, 66,5 avec&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/Qwen/Qwen3.5-2B" rel="noopener noreferrer"&gt;Fiche Qwen&lt;/a&gt;, consultée le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 3B&lt;/td&gt;
&lt;td&gt;HumanEval&amp;nbsp;: 84,1&amp;nbsp;; MBPP&amp;nbsp;: 73,6&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://arxiv.org/abs/2409.12186" rel="noopener noreferrer"&gt;Rapport technique&lt;/a&gt;, v3 du 12 nov. 2024, consulté le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder 7B&lt;/td&gt;
&lt;td&gt;HumanEval&amp;nbsp;: 88,4&amp;nbsp;; MBPP&amp;nbsp;: 83,5&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://arxiv.org/abs/2409.12186" rel="noopener noreferrer"&gt;Rapport technique&lt;/a&gt;, v3 du 12 nov. 2024, consulté le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phi-4-mini&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;td&gt;MMLU&amp;nbsp;: 67,3&amp;nbsp;; MMLU multilingue&amp;nbsp;: 49,3&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/microsoft/Phi-4-mini-instruct" rel="noopener noreferrer"&gt;Fiche Microsoft&lt;/a&gt;, février 2025, consultée le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama 3.2 3B&lt;/td&gt;
&lt;td&gt;Non publié&lt;/td&gt;
&lt;td&gt;MMLU&amp;nbsp;: 63,4&amp;nbsp;; MMLU en français&amp;nbsp;: 54,6&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/meta-llama/Llama-3.2-3B-Instruct" rel="noopener noreferrer"&gt;Fiche Meta&lt;/a&gt;, septembre 2024, consultée le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ministral 3 3B&lt;/td&gt;
&lt;td&gt;Non publié pour la version Instruct&lt;/td&gt;
&lt;td&gt;Arena Hard&amp;nbsp;: 0,305&amp;nbsp;; WildBench&amp;nbsp;: 56,8&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512" rel="noopener noreferrer"&gt;Fiche Mistral AI&lt;/a&gt;, consultée le 7 nov. 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Trois enseignements. D'abord, selon leurs éditeurs, Qwen3.5 4B devance Gemma 4 E2B sur LiveCodeBench v6 (55,8 contre 44,0), l'inverse de notre petit test. La fiche de Qwen3.5 4B ne précise pas le mode utilisé et indique que le modèle réfléchit par défaut&amp;nbsp;; nous avions coupé ce mode. Ensuite, le mode réflexion pèse lourd&amp;nbsp;: Qwen publie pour Qwen3.5 2B un MMLU-Pro de 55,3 sans réflexion et 66,5 avec. Enfin, les éditeurs ne mesurent pas tous de la même façon&amp;nbsp;: Meta donne 63,4 au MMLU pour Llama 3.2 3B, la fiche de Phi-4-mini lui attribue 65,0.&lt;/p&gt;

&lt;p&gt;Côté classements indépendants, la page des petits modèles open source d'&lt;a href="https://artificialanalysis.ai/models/open-source/small" rel="noopener noreferrer"&gt;Artificial Analysis&lt;/a&gt;, consultée le 7 novembre 2026, couvre les modèles de 4 à 40&amp;nbsp;milliards de paramètres et affiche les 12 premiers de son indice de progression, de Nanbeige4.3-33B (306&amp;nbsp;points) à Qwen3.6 35B A3B sans réflexion (246&amp;nbsp;points). Aucun des modèles que nous avons mesurés ne figure parmi ces 12, et la page de &lt;a href="https://artificialanalysis.ai/models/gemma-4-e2b" rel="noopener noreferrer"&gt;Gemma 4 E2B&lt;/a&gt; n'affiche pas de score.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quel est le meilleur LLM local selon l'usage
&lt;/h2&gt;

&lt;p&gt;Sur cette machine, le meilleur LLM local polyvalent est Gemma 4 E2B, si vous acceptez 47&amp;nbsp;secondes de chargement. Les chiffres publiés ne changent pas ce choix, mais ils ajoutent une option pour le code.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;th&gt;Notre choix sur ce portable&lt;/th&gt;
&lt;th&gt;Pourquoi&lt;/th&gt;
&lt;th&gt;Alternative&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coder&lt;/td&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;6 tests sur 6, lecture de prompt la plus rapide&lt;/td&gt;
&lt;td&gt;Qwen3.5 4B&amp;nbsp;: 55,8 sur LiveCodeBench v6 selon Qwen (mode non précisé, réflexion par défaut), plus lent si la réflexion est active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discuter en français&lt;/td&gt;
&lt;td&gt;Gemma 4 E2B&lt;/td&gt;
&lt;td&gt;8 questions sur 8, dont l'énigme des sœurs&lt;/td&gt;
&lt;td&gt;Ministral 3 3B (8 sur 8, chargement en 17 s)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portable avec peu de RAM&lt;/td&gt;
&lt;td&gt;Qwen2.5-Coder 3B&lt;/td&gt;
&lt;td&gt;Plus petit fichier (1,9&amp;nbsp;Go) et pic mesuré le plus bas (2,1&amp;nbsp;Go), 4 tests de code sur 6, chargement en 9 s&lt;/td&gt;
&lt;td&gt;Qwen3.5 4B si 1&amp;nbsp;Go de plus est libre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;À éviter sur 8&amp;nbsp;Go&lt;/td&gt;
&lt;td&gt;Qwen2.5-Coder 7B&lt;/td&gt;
&lt;td&gt;Un plantage d'Ollama, 1 à 2 tok/s (indicatif)&lt;/td&gt;
&lt;td&gt;Mesures publiées&amp;nbsp;: 6 à 8 tok/s pour un 7B avec 16 ou 32&amp;nbsp;Go&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Pour coder,&lt;/strong&gt; le meilleur LLM local sur 8&amp;nbsp;Go reste un complément aux assistants en ligne&amp;nbsp;: à 6&amp;nbsp;tokens par seconde, une réponse de 300&amp;nbsp;tokens prend environ 50&amp;nbsp;secondes. Le mode réflexion de Qwen3.5 4B, actif par défaut selon sa fiche, ajoute des tokens avant chaque réponse&amp;nbsp;: nous ne l'avons pas mesuré, mais chacun allonge l'attente. Les études sur le gain de productivité sont résumées dans notre article sur &lt;a href="https://neurautech.com/comment-utiliser-lia-pour-coder-3x-plus-vite/" rel="noopener noreferrer"&gt;l'IA pour coder plus vite&lt;/a&gt;&amp;nbsp;; pour l'éditeur de code, le guide Ollama détaille l'extension Continue, et nos &lt;a href="https://neurautech.com/raccourcis-vs-code/" rel="noopener noreferrer"&gt;raccourcis VS Code&lt;/a&gt; font gagner du temps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour discuter en français,&lt;/strong&gt; les erreurs relevées viennent surtout du raisonnement&amp;nbsp;; nous n'avons pas noté la qualité du français. Gemma 4 E2B, Ministral 3 3B et Qwen2.5-Coder 3B ont fait 8 sur 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour un portable avec peu de mémoire,&lt;/strong&gt; fermez le navigateur avant de charger le modèle, gardez un contexte de 4&amp;nbsp;096&amp;nbsp;tokens et préférez un modèle de 3&amp;nbsp;milliards de paramètres. Si vous achetez une machine pour l'IA locale, visez au moins 16&amp;nbsp;Go&amp;nbsp;: sur 8&amp;nbsp;Go, notre système manquait de mémoire pendant chaque test, et les mesures publiées sur 16 et 32&amp;nbsp;Go sont plus rapides, sur d'autres processeurs. Pour relier ensuite le modèle à vos outils, notre guide du &lt;a href="https://neurautech.com/serveur-mcp/" rel="noopener noreferrer"&gt;serveur MCP&lt;/a&gt; explique le protocole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les limites de ce banc d'essai
&lt;/h2&gt;

&lt;p&gt;Ce banc d'essai ne remplace pas un classement général&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Une seule machine, non isolée.&lt;/strong&gt; VS Code et Chrome restaient ouverts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un petit échantillon.&lt;/strong&gt; Six exercices de code et huit questions montrent les grands écarts, pas les petits&amp;nbsp;: un exercice de plus peut inverser deux lignes du tableau.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Des étiquettes par défaut.&lt;/strong&gt; Qwen3.5 2B est livré en Q8_0, les autres en Q4_K_M&amp;nbsp;: c'est ce qu'obtient l'utilisateur, mais la quantification n'est pas égale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Réflexion désactivée.&lt;/strong&gt; Qwen3.5 et Gemma 4 savent «&amp;nbsp;réfléchir&amp;nbsp;» avant de répondre. Nous avons coupé ce mode pour comparer à réglages égaux, alors que certains scores publiés l'utilisent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Des mesures publiées sur processeur pour Gemma 4, Qwen3.5 ou Ministral 3&lt;/strong&gt;&amp;nbsp;: nous n'en avons trouvé aucune avec un matériel précis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le classement de LiveCodeBench&lt;/strong&gt;&amp;nbsp;: sa page publique ne s'est pas chargée lors de notre consultation, nous n'avons donc pas pu y situer ces modèles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le mode des scores de Qwen3.5 4B&lt;/strong&gt;&amp;nbsp;: sa fiche ne dit pas s'ils ont été obtenus avec ou sans réflexion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le GPU intégré&lt;/strong&gt;&amp;nbsp;: Ollama l'écarte par défaut, et nous n'avons pas activé le réglage &lt;code&gt;OLLAMA_IGPU_ENABLE&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quel est le meilleur LLM local pour un PC avec 8 Go de RAM ?
&lt;/h3&gt;

&lt;p&gt;Sur notre portable de 8&amp;nbsp;Go sans GPU, Gemma 4 E2B a réussi tous nos tests de code et toutes nos questions en français, à 6,3&amp;nbsp;tokens par seconde. Si la mémoire est très juste, Qwen2.5-Coder 3B a le plus petit fichier (1,9&amp;nbsp;Go) et le pic mesuré le plus bas (2,1&amp;nbsp;Go), et reste correct en code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quel LLM local choisir pour coder ?
&lt;/h3&gt;

&lt;p&gt;Sur notre machine, Gemma 4 E2B (6 tests sur 6), puis Ministral 3 3B et Qwen3.5 4B (5 sur 6). Selon Qwen, Qwen3.5 4B obtient 55,8 sur LiveCodeBench v6, contre 44,0&amp;nbsp;% pour Gemma 4 E2B selon Google. La fiche de Qwen ne précise pas le mode utilisé, et le modèle réfléchit par défaut, ce qui ralentit chaque réponse sur un processeur seul.&lt;/p&gt;

&lt;h3&gt;
  
  
  Un LLM local est-il assez rapide sans carte graphique ?
&lt;/h3&gt;

&lt;p&gt;Pour des questions courtes, oui&amp;nbsp;: à 5 à 7,5&amp;nbsp;tokens par seconde, une réponse de 300&amp;nbsp;tokens arrive en 40 à 60&amp;nbsp;secondes. Avec de longs documents, la lecture du prompt (14 à 43&amp;nbsp;tokens par seconde ici) devient le facteur limitant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peut-on faire tourner un modèle 7B avec 8 Go de RAM ?
&lt;/h3&gt;

&lt;p&gt;Sur notre machine, pas de façon fiable&amp;nbsp;: Qwen2.5-Coder 7B a fait planter Ollama une fois et n'a pas dépassé 2&amp;nbsp;tokens par seconde (mesure indicative). Sur une machine mieux dotée, un portable à 32&amp;nbsp;Go, le même modèle a été mesuré à 8&amp;nbsp;tokens par seconde&amp;nbsp;; processeur et système y étaient aussi différents.&lt;/p&gt;

&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Mesures prises les 6 et 7 novembre 2026 sur le portable de l'auteur décrit plus haut, avec Ollama 0.40.15 et un script Python. Chaque chiffre retenu vient d'une seule série de mesures&amp;nbsp;; rien n'a été remesuré après le 7 novembre. Nos vitesses ont été mesurées sur secteur le 7 novembre (sauf le second essai, indicatif, de Qwen2.5-Coder 7B)&amp;nbsp;; une première série en partie sur batterie a été écartée pour la vitesse. Les fichiers téléchargés (8 modèles, 24,7&amp;nbsp;Go, et Ollama) ont été supprimés ensuite. Chiffres des éditeurs et des tiers lus le 7 novembre 2026. Aucun lien affilié.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou une mesure à refaire&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 7 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image&amp;nbsp;: Adhitya Sibikumar (Unsplash License). Graphiques&amp;nbsp;: NeurauTech, à partir de nos mesures.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>llmlocal</category>
      <category>ollama</category>
      <category>benchmark</category>
      <category>intelligenceartificielle</category>
    </item>
    <item>
      <title>Claude Code vs Cursor, Copilot et Codex : prix et limites en novembre 2026</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Sat, 07 Nov 2026 11:08:26 +0000</pubDate>
      <link>https://dev.to/neurau_tech/claude-code-vs-cursor-copilot-et-codex-prix-et-limites-en-novembre-2026-3o15</link>
      <guid>https://dev.to/neurau_tech/claude-code-vs-cursor-copilot-et-codex-prix-et-limites-en-novembre-2026-3o15</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Le match Claude Code vs Cursor a changé de règles. Depuis le 12 octobre 2026, Cursor se vend dans «&amp;nbsp;The X Subscription&amp;nbsp;» de SpaceX, avec les modèles Grok inclus et les modèles de Claude, GPT ou Gemini facturés au prix de l'API. GitHub Copilot compte en crédits depuis le 1er juin, et Anthropic a renommé ses offres Max fin octobre.&lt;/p&gt;

&lt;p&gt;Nous comparons Claude Code, Cursor, GitHub Copilot, OpenAI Codex et, en appoint, Gemini CLI. Chaque prix et chaque limite ont été relus les 6 et 7 novembre 2026 sur la page officielle liée, sauf mention explicite de la presse. Montants en dollars hors taxes&amp;nbsp;: aucune page chargée depuis la France n'affichait d'euros. Synthèse documentaire, sans compte ouvert.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;À l'entrée&amp;nbsp;: Copilot Pro 10&amp;nbsp;$, Cursor Plus 8&amp;nbsp;$ (modèles Grok seulement), Claude Pro 20&amp;nbsp;$ avec Claude Code, ChatGPT Plus 20&amp;nbsp;$ avec Codex.&lt;/li&gt;
&lt;li&gt;Chez Cursor, Claude, GPT et Gemini ne sont plus inclus&amp;nbsp;: à partir de Premium (30&amp;nbsp;$), ils sont payés au prix de l'API dès la première requête.&lt;/li&gt;
&lt;li&gt;Les unités diffèrent&amp;nbsp;: fenêtres de 5&amp;nbsp;heures chez Anthropic et OpenAI, crédits à 0,01&amp;nbsp;$ chez GitHub, réserve hebdomadaire partagée avec Grok chez Cursor.&lt;/li&gt;
&lt;li&gt;Pour 5 développeurs facturés au mois, l'entrée de gamme va de 95&amp;nbsp;$ (Copilot Business) à 150&amp;nbsp;$ (Cursor Teams, hors modèles tiers).&lt;/li&gt;
&lt;li&gt;Sur les offres individuelles, l'entraînement sur vos échanges dépend d'un réglage chez Anthropic, Cursor et GitHub&amp;nbsp;; la page équivalente d'OpenAI n'a pas pu être lue. Les offres professionnelles d'Anthropic, de GitHub et d'OpenAI l'excluent par défaut.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Claude Code vs Cursor : le tableau de référence au 6 novembre 2026
&lt;/h2&gt;

&lt;p&gt;Voici les offres de chaque outil telles qu'affichées le 6 novembre 2026, en prix mensuel&amp;nbsp;; détails et sources suivent.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;OpenAI Codex&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gratuit&lt;/td&gt;
&lt;td&gt;Non (Claude Free n'inclut pas Claude Code)&lt;/td&gt;
&lt;td&gt;Free, usage limité&lt;/td&gt;
&lt;td&gt;Free, 2&amp;nbsp;000 complétions par mois&lt;/td&gt;
&lt;td&gt;Free, GPT-6 Luna dans l'application de bureau, en déploiement progressif&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entrée payante&lt;/td&gt;
&lt;td&gt;Pro, 20&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Plus, 8&amp;nbsp;$, Grok seulement&lt;/td&gt;
&lt;td&gt;Pro, 10&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Plus (ChatGPT), 20&amp;nbsp;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offres hautes&lt;/td&gt;
&lt;td&gt;Max 100&amp;nbsp;$, Ultra 200&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Premium 30&amp;nbsp;$, Super 100&amp;nbsp;$, Ultra 200&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Pro+ 39&amp;nbsp;$, Max 100&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Pro 100, 200 ou 500&amp;nbsp;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remise annuelle affichée&lt;/td&gt;
&lt;td&gt;Pro et Team&lt;/td&gt;
&lt;td&gt;Plus, Premium, Super, Ultra&lt;/td&gt;
&lt;td&gt;Aucune&lt;/td&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Équipe, par siège et par mois&lt;/td&gt;
&lt;td&gt;Team 25&amp;nbsp;$, siège premium 125&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Teams 30, 100 ou 200&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Business 19&amp;nbsp;$, Enterprise 39&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Business 25&amp;nbsp;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unité de mesure&lt;/td&gt;
&lt;td&gt;Plafond par 5&amp;nbsp;heures et par semaine&lt;/td&gt;
&lt;td&gt;Réserve hebdomadaire partagée avec Grok&lt;/td&gt;
&lt;td&gt;Crédits IA, 1&amp;nbsp;crédit = 0,01&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Messages par 5&amp;nbsp;heures, plafond hebdomadaire possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Où il tourne&lt;/td&gt;
&lt;td&gt;Terminal, VS Code, JetBrains, application de bureau, web&lt;/td&gt;
&lt;td&gt;Éditeur, CLI, agents cloud, iOS&lt;/td&gt;
&lt;td&gt;IDE, CLI, github.com, agent cloud&lt;/td&gt;
&lt;td&gt;CLI, extension IDE, application de bureau, cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;td&gt;Oui&lt;/td&gt;
&lt;td&gt;Oui&lt;/td&gt;
&lt;td&gt;Oui&lt;/td&gt;
&lt;td&gt;Oui&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: pages de &lt;a href="https://claude.com/pricing" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, de &lt;a href="https://cursor.com/docs/models-and-pricing" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;, de &lt;a href="https://docs.github.com/en/copilot/get-started/plans" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; et de &lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;Codex&lt;/a&gt;. Pour le protocole MCP, voyez notre &lt;a href="https://neurautech.com/serveur-mcp/" rel="noopener noreferrer"&gt;tutoriel sur les serveurs MCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Les modèles ne départagent plus ces outils. La &lt;a href="https://github.com/features/copilot/plans" rel="noopener noreferrer"&gt;page des offres de Copilot&lt;/a&gt; liste 35 modèles, dont Claude Opus 5.5, GPT-6.1 Sol, Gemini 4 Argon et Grok 4.7. Comparer Claude Code vs Cursor, c'est comparer une manière de travailler et une facturation. Voir notre &lt;a href="https://neurautech.com/chatgpt-vs-claude-vs-gemini-lequel-choisir/" rel="noopener noreferrer"&gt;comparatif ChatGPT, Claude et Gemini&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce qui a changé depuis juin
&lt;/h2&gt;

&lt;p&gt;Cinq changements datent des cinq derniers mois.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1er juin, GitHub.&lt;/strong&gt; Les requêtes premium deviennent des crédits IA calculés sur les tokens, aux tarifs API de chaque modèle, et le repli sur un modèle moins cher disparaît (&lt;a href="https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/" rel="noopener noreferrer"&gt;annonce de GitHub&lt;/a&gt;, 27 avril 2026). L'offre Max à 100&amp;nbsp;$ arrive le même jour (&lt;a href="https://github.blog/news-insights/company-news/github-copilot-individual-plans-introducing-flex-allotments-in-pro-and-pro-and-a-new-max-plan/" rel="noopener noreferrer"&gt;blog GitHub&lt;/a&gt;, 12 mai 2026).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;14 août, Cursor.&lt;/strong&gt; Cursor annonce que son rachat par SpaceX est finalisé (&lt;a href="https://cursor.com/blog/joining-spacex" rel="noopener noreferrer"&gt;blog de Cursor&lt;/a&gt;, 14 août 2026).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12 octobre, Cursor.&lt;/strong&gt; «&amp;nbsp;The X Subscription&amp;nbsp;» regroupe Cursor, Grok et X Premium&amp;nbsp;; les anciennes offres Pro, Pro+ et Ultra restent pour les clients existants (&lt;a href="https://cursor.com/docs/models-and-pricing" rel="noopener noreferrer"&gt;documentation de Cursor&lt;/a&gt;). La date vient de la presse&amp;nbsp;: &lt;a href="https://thenewstack.io/x-subscription-cursor-pricing/" rel="noopener noreferrer"&gt;The New Stack&lt;/a&gt;, 13 octobre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;14 octobre, OpenAI.&lt;/strong&gt; GPT-5.5 est retiré de Codex pour les connexions avec un compte ChatGPT (&lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;page des prix de Codex&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30 octobre, Anthropic.&lt;/strong&gt; Max 5x devient Max, Max 20x devient Ultra, et les comptes Ultra vérifiés n'ont plus de limite sur 5&amp;nbsp;heures. Les noms et la limite figurent sur la &lt;a href="https://claude.com/pricing" rel="noopener noreferrer"&gt;page des prix de Claude&lt;/a&gt;&amp;nbsp;; la date vient de la presse&amp;nbsp;: &lt;a href="https://letsdatascience.com/news/anthropic-removes-five-hour-claude-limit-for-verified-ultra-56c3c5dc" rel="noopener noreferrer"&gt;Let's Data Science&lt;/a&gt;, 30 octobre 2026.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;À noter aussi&amp;nbsp;: le 29 octobre 2026, deux versions piégées de l'extension «&amp;nbsp;Anthropic.claude-code&amp;nbsp;» (2.1.312 et 2.1.313), non développées par Anthropic, ont circulé environ onze heures sur la place de marché d'extensions de Cursor, avec une porte dérobée SSH (&lt;a href="https://cursor.com/blog/claude-code-extension-security-notice" rel="noopener noreferrer"&gt;avis de sécurité de Cursor&lt;/a&gt;, 29 octobre 2026).&lt;/p&gt;




&lt;h2&gt;
  
  
  Claude Code : des plafonds sur 5 heures et sur la semaine
&lt;/h2&gt;

&lt;p&gt;Claude Code est inclus dans les abonnements Claude payants, avec des limites partagées avec le chat. Anthropic indique 20&amp;nbsp;$ par mois pour Pro, ou 17&amp;nbsp;$ par mois avec l'abonnement annuel de 200&amp;nbsp;$, 100&amp;nbsp;$ pour Max et 200&amp;nbsp;$ pour Ultra, ces deux derniers au mois seulement (&lt;a href="https://claude.com/pricing" rel="noopener noreferrer"&gt;prix de Claude&lt;/a&gt;, relus les 6 et 7 novembre 2026). L'offre gratuite n'inclut pas Claude Code.&lt;/p&gt;

&lt;p&gt;Une précision avant le tableau&amp;nbsp;: Fable est le modèle haut de gamme d'Anthropic, lancé le 9 juin 2026 et mis à jour en Fable 5.1 le 1er septembre (&lt;a href="https://support.claude.com/en/articles/12138966-release-notes" rel="noopener noreferrer"&gt;notes de version de Claude&lt;/a&gt;, lues le 7 novembre 2026). Il a son propre décompte. Les limites sont exprimées en multiples de Pro, sans nombre de messages&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offre&lt;/th&gt;
&lt;th&gt;Prix par mois&lt;/th&gt;
&lt;th&gt;Limite par 5&amp;nbsp;heures&lt;/th&gt;
&lt;th&gt;Limite par semaine&lt;/th&gt;
&lt;th&gt;Fable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;td&gt;Payé en crédits d'usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max&lt;/td&gt;
&lt;td&gt;100&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;5x&lt;/td&gt;
&lt;td&gt;5x&lt;/td&gt;
&lt;td&gt;Jusqu'à 50&amp;nbsp;% de la limite hebdomadaire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra&lt;/td&gt;
&lt;td&gt;200&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Aucune (compte vérifié)&lt;/td&gt;
&lt;td&gt;10x&lt;/td&gt;
&lt;td&gt;Jusqu'à 50&amp;nbsp;% de la limite hebdomadaire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team, siège standard&lt;/td&gt;
&lt;td&gt;25&amp;nbsp;$ (20&amp;nbsp;$ en annuel)&lt;/td&gt;
&lt;td&gt;Plus que Pro&lt;/td&gt;
&lt;td&gt;Plus que Pro&lt;/td&gt;
&lt;td&gt;Non précisé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team, siège premium&lt;/td&gt;
&lt;td&gt;125&amp;nbsp;$ (100&amp;nbsp;$ en annuel)&lt;/td&gt;
&lt;td&gt;5x le siège standard&lt;/td&gt;
&lt;td&gt;5x le siège standard&lt;/td&gt;
&lt;td&gt;50&amp;nbsp;% de la limite hebdomadaire&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Selon la même page, Max et Ultra incluent aussi 100&amp;nbsp;$ et 200&amp;nbsp;$ par mois de crédits pour l'API d'Anthropic. Enterprise coûte 20&amp;nbsp;$ par siège et par mois en annuel, 20 sièges minimum, plus l'usage aux tarifs API.&lt;/p&gt;

&lt;p&gt;Les offres payantes donnent accès à Opus, Sonnet et Haiku. Claude Code tourne dans le terminal, dans VS Code et JetBrains, dans l'application de bureau et sur le web (&lt;a href="https://code.claude.com/docs/en/overview" rel="noopener noreferrer"&gt;documentation de Claude Code&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Piège&amp;nbsp;: si &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; est définie, Claude Code facture l'usage à l'API au lieu de l'abonnement (&lt;a href="https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-max-or-ultra-plan" rel="noopener noreferrer"&gt;centre d'aide d'Anthropic&lt;/a&gt;). L'abonnement couvre aussi l'extension dans VS Code et Cursor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verdict&amp;nbsp;:&lt;/strong&gt; un prix fixe, mais sans compteur en messages&amp;nbsp;: on découvre son plafond en l'atteignant.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cursor : un abonnement X, Grok inclus, le reste au prix API
&lt;/h2&gt;

&lt;p&gt;Depuis octobre, Cursor se vend dans «&amp;nbsp;The X Subscription&amp;nbsp;», qui inclut aussi Grok et X Premium. La documentation de Cursor liste Plus à 8&amp;nbsp;$, Premium à 30&amp;nbsp;$, Super à 100&amp;nbsp;$ et Ultra à 200&amp;nbsp;$ par mois, ou 80&amp;nbsp;$, 300&amp;nbsp;$, 1&amp;nbsp;000&amp;nbsp;$ et 2&amp;nbsp;000&amp;nbsp;$ par an (&lt;a href="https://cursor.com/docs/models-and-pricing" rel="noopener noreferrer"&gt;documentation des prix de Cursor&lt;/a&gt;, relue les 6 et 7 novembre 2026). La page précise que ces prix n'incluent pas les taxes, comme la TVA.&lt;/p&gt;

&lt;p&gt;La réserve hebdomadaire, partagée avec les applications Grok, couvre les modèles maison (Grok 4.7, 4.6, 4.5 et Composer 2.5). Premium donne 4 fois l'usage de Plus, Super 15 fois, Ultra 50 fois. Discuter avec Grok entame donc ce qui reste pour coder.&lt;/p&gt;

&lt;p&gt;Les modèles tiers sont absents de Plus et Free. À partir de Premium, Claude, GPT et Gemini sont facturés au prix public de l'API dès la première requête, sur un crédit prépayé. Les agents cloud, l'hébergement de code Origin et la revue de code Bugbot demandent aussi Premium.&lt;/p&gt;

&lt;p&gt;En équipe, chaque siège coûte 30&amp;nbsp;$, 100&amp;nbsp;$ ou 200&amp;nbsp;$ par mois&amp;nbsp;; la documentation n'affiche pas de prix annuel pour Teams. Sur Teams et Enterprise, les modèles tiers éligibles supportent en plus un «&amp;nbsp;Cursor Token Rate&amp;nbsp;» de 0,25&amp;nbsp;$ par million de tokens. Cursor fonctionne dans son éditeur, en ligne de commande, en agents cloud et sur iOS, et prend en charge MCP (&lt;a href="https://cursor.com/docs/mcp" rel="noopener noreferrer"&gt;documentation MCP de Cursor&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verdict&amp;nbsp;:&lt;/strong&gt; l'usage de Grok et de Composer est inclus, sans quota publié en messages. Pour Claude ou GPT dans Cursor, comptez l'abonnement plus la facture API. Matt Palmer, chargé de l'expérience développeur chez SpaceXAI, l'écrit lui-même, cité par &lt;a href="https://thenewstack.io/x-subscription-cursor-pricing/" rel="noopener noreferrer"&gt;The New Stack&lt;/a&gt;&amp;nbsp;: «&amp;nbsp;si la plupart de votre usage porte sur des modèles tiers, les nouvelles offres pourraient vous coûter plus cher&amp;nbsp;» (notre traduction).&lt;/p&gt;




&lt;h2&gt;
  
  
  GitHub Copilot : des crédits IA facturés au centime
&lt;/h2&gt;

&lt;p&gt;Les offres individuelles de Copilot coûtent 10&amp;nbsp;$ (Pro), 39&amp;nbsp;$ (Pro+) et 100&amp;nbsp;$ (Max) par mois. Les offres d'organisation coûtent 19&amp;nbsp;$ (Business) et 39&amp;nbsp;$ (Enterprise) par siège et par mois (&lt;a href="https://docs.github.com/en/copilot/get-started/plans" rel="noopener noreferrer"&gt;documentation des offres Copilot&lt;/a&gt;, relue les 6 et 7 novembre 2026). Aucun prix annuel n'y figure. Copilot Student est gratuit pour les étudiants vérifiés.&lt;/p&gt;

&lt;p&gt;Un crédit vaut 0,01&amp;nbsp;$. Chaque offre inclut une base égale à son prix, plus une part variable que GitHub appelle «&amp;nbsp;flex&amp;nbsp;» et qu'il se réserve de modifier&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offre&lt;/th&gt;
&lt;th&gt;Prix&lt;/th&gt;
&lt;th&gt;Crédits de base&lt;/th&gt;
&lt;th&gt;Part flex&lt;/th&gt;
&lt;th&gt;Total mensuel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;000&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro+&lt;/td&gt;
&lt;td&gt;39&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;3&amp;nbsp;900&lt;/td&gt;
&lt;td&gt;3&amp;nbsp;100&lt;/td&gt;
&lt;td&gt;7&amp;nbsp;000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max&lt;/td&gt;
&lt;td&gt;100&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;000&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;000&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;td&gt;19&amp;nbsp;$ par siège&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;900, mis en commun&lt;/td&gt;
&lt;td&gt;Aucune&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;900 par siège&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;39&amp;nbsp;$ par siège&lt;/td&gt;
&lt;td&gt;3&amp;nbsp;900, mis en commun&lt;/td&gt;
&lt;td&gt;Aucune&lt;/td&gt;
&lt;td&gt;3&amp;nbsp;900 par siège&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz90xgt7cqw3dg3f7v6ln.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz90xgt7cqw3dg3f7v6ln.webp" alt="Prix et crédits inclus des offres GitHub Copilot au 6 novembre 2026" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les complétions ne consomment pas de crédits sur les offres payantes&amp;nbsp;; chat, agents, revue de code et CLI en consomment, selon le modèle et la tâche. La revue de code consomme en plus des minutes GitHub Actions (&lt;a href="https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/" rel="noopener noreferrer"&gt;annonce de GitHub&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;L'agent cloud, qui transforme une issue en pull request, est inclus dès Pro. Confier une tâche à un agent tiers comme Claude ou Codex demande Pro+ ou Max, en préversion. MCP est pris en charge en mode agent, y compris sur Free (&lt;a href="https://github.com/features/copilot/plans" rel="noopener noreferrer"&gt;page des offres Copilot&lt;/a&gt;). Selon l'annonce de GitHub, les abonnés annuels Pro et Pro+ gardent les requêtes premium jusqu'à leur échéance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verdict&amp;nbsp;:&lt;/strong&gt; la facturation la plus lisible, chaque crédit ayant une valeur en dollars. La part flex, elle, peut baisser.&lt;/p&gt;




&lt;h2&gt;
  
  
  OpenAI Codex : inclus dans ChatGPT
&lt;/h2&gt;

&lt;p&gt;Codex est inclus dans les offres ChatGPT, dont il partage les limites. Plus coûte 20&amp;nbsp;$, Pro est proposé à 100&amp;nbsp;$, 200&amp;nbsp;$ ou 500&amp;nbsp;$ par mois, et Business coûte 25&amp;nbsp;$ par utilisateur au mois ou 20&amp;nbsp;$ en annuel, à partir de 2 utilisateurs (&lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;page des prix de Codex&lt;/a&gt;, relue les 6 et 7 novembre 2026).&lt;/p&gt;

&lt;p&gt;OpenAI est le seul à publier des fourchettes&amp;nbsp;: messages locaux estimés par 5&amp;nbsp;heures sur Plus et Business standard.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modèle&lt;/th&gt;
&lt;th&gt;Messages locaux par 5&amp;nbsp;heures (Plus)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Astra&lt;/td&gt;
&lt;td&gt;5 à 45&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol&lt;/td&gt;
&lt;td&gt;15 à 160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Sol&lt;/td&gt;
&lt;td&gt;15 à 150&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra&lt;/td&gt;
&lt;td&gt;35 à 285&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Luna&lt;/td&gt;
&lt;td&gt;350 à 3&amp;nbsp;000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ce ne sont pas des limites fixes&amp;nbsp;; un plafond hebdomadaire peut s'ajouter. Les offres Pro n'ont pas de limite sur 5&amp;nbsp;heures. Les modes Fast et Ultrafast consomment 2,5 et 8 fois plus vite.&lt;/p&gt;

&lt;p&gt;Codex tourne en CLI, en IDE, sur bureau et dans le cloud, avec MCP. Avec une clé API, il perd les fonctions cloud, et l'usage est facturé aux tarifs API. Voir aussi &lt;a href="https://neurautech.com/gpt-6-changements-developpeurs/" rel="noopener noreferrer"&gt;ce que GPT-6 change pour les développeurs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verdict&amp;nbsp;:&lt;/strong&gt; des fourchettes publiées pour prévoir, mais des limites partagées avec ChatGPT, et GPT-5.5 retiré de Codex depuis le 14 octobre.&lt;/p&gt;




&lt;h2&gt;
  
  
  Gemini CLI : l'option gratuite à quotas
&lt;/h2&gt;

&lt;p&gt;Gemini CLI, l'outil de Google sous licence Apache-2.0, annonce 1&amp;nbsp;000&amp;nbsp;requêtes par jour avec un compte Google personnel, 1&amp;nbsp;500 avec Google AI Pro et 2&amp;nbsp;000 avec Google AI Ultra. Avec une clé API gratuite, la limite tombe à 250&amp;nbsp;requêtes par jour, sur le modèle Flash seulement (&lt;a href="https://geminicli.com/docs/resources/quota-and-pricing/" rel="noopener noreferrer"&gt;quotas de Gemini CLI&lt;/a&gt;, lus le 7 novembre 2026).&lt;/p&gt;

&lt;p&gt;Il prend en charge MCP. Nous n'avons pas relu les prix des abonnements Google. Voyez aussi notre sélection d'&lt;a href="https://neurautech.com/les-10-meilleurs-outils-ia-gratuits-pour-dev-2026/" rel="noopener noreferrer"&gt;outils IA gratuits pour développeurs&lt;/a&gt;, ou un &lt;a href="https://neurautech.com/llm-local-ollama/" rel="noopener noreferrer"&gt;LLM local avec Ollama&lt;/a&gt; si votre code ne doit pas quitter votre machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Confidentialité : qui peut entraîner sur votre code
&lt;/h2&gt;

&lt;p&gt;Sur les offres individuelles, l'usage de vos échanges pour l'entraînement dépend d'un réglage chez Anthropic, Cursor et GitHub&amp;nbsp;; pour OpenAI, la page d'aide a refusé notre accès automatisé. Dans le duel Claude Code vs Cursor, la règle est donc la même&amp;nbsp;: un réglage à vérifier. Voici ce que disent les pages officielles, lues les 6 et 7 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Outil&lt;/th&gt;
&lt;th&gt;Offres individuelles&lt;/th&gt;
&lt;th&gt;Offres équipe et entreprise&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Entraînement si le réglage d'amélioration du modèle est activé&amp;nbsp;; conservation 5&amp;nbsp;ans dans ce cas, 30&amp;nbsp;jours sinon&lt;/td&gt;
&lt;td&gt;Pas d'entraînement par défaut&amp;nbsp;; conservation 30&amp;nbsp;jours&amp;nbsp;; zéro conservation possible sur Enterprise éligible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;Pas d'entraînement avec le mode confidentialité&amp;nbsp;; sans lui, Cursor peut stocker et entraîner&lt;/td&gt;
&lt;td&gt;Mode confidentialité activable par un administrateur pour l'équipe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;Entraînement possible, refus dans les réglages&amp;nbsp;; jamais sur le code des dépôts d'organisations payantes&lt;/td&gt;
&lt;td&gt;Pas d'entraînement sur ces données (accord DPA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;td&gt;Hors de la garantie «&amp;nbsp;pas d'entraînement par défaut&amp;nbsp;» du tableau de Codex&amp;nbsp;; page d'aide sur les contrôles de données non lue&lt;/td&gt;
&lt;td&gt;Pas d'entraînement par défaut sur Business, Enterprise et API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.claude.com/docs/en/data-usage" rel="noopener noreferrer"&gt;données de Claude Code&lt;/a&gt;, &lt;a href="https://cursor.com/data-use" rel="noopener noreferrer"&gt;données de Cursor&lt;/a&gt;, &lt;a href="https://copilot.github.trust.page/faq" rel="noopener noreferrer"&gt;FAQ de confiance de Copilot&lt;/a&gt; (lue le 7 novembre 2026) et &lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;tableau des fonctions de Codex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Trois exceptions comptent. Chez Anthropic, une conversation signalée par les systèmes de sécurité est conservée jusqu'à 2&amp;nbsp;ans, et les retours envoyés (pouce, rapport de bug) 5&amp;nbsp;ans (&lt;a href="https://privacy.claude.com/en/articles/10023548-how-long-do-you-store-my-data" rel="noopener noreferrer"&gt;centre de confidentialité d'Anthropic&lt;/a&gt;, lu le 7 novembre 2026).&lt;/p&gt;

&lt;p&gt;Chez GitHub, Claude Fable entraîne une conservation par Anthropic pour ses filtres de sécurité&amp;nbsp;; les entreprises peuvent demander une conservation nulle jusqu'à fin 2026, après quoi un nouveau dispositif d'Anthropic sera requis (&lt;a href="https://docs.github.com/en/copilot/get-started/plans" rel="noopener noreferrer"&gt;documentation GitHub&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Chez Cursor, la politique de confidentialité, mise à jour le 11 octobre 2026, autorise le partage des «&amp;nbsp;données personnelles&amp;nbsp;» avec des sociétés affiliées, y compris celles placées dans vos requêtes, mais ne vise pas les comptes fournis par un employeur (&lt;a href="https://cursor.com/privacy" rel="noopener noreferrer"&gt;politique de Cursor&lt;/a&gt;, lue le 7 novembre 2026). Clause courante, que nous n'avons pas comparée chez les autres éditeurs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le coût réel pour 1 développeur et pour 5
&lt;/h2&gt;

&lt;p&gt;Montants publics hors taxes, au mois, sans remise.&lt;/p&gt;

&lt;p&gt;Pour un développeur seul&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Codex&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Léger&lt;/td&gt;
&lt;td&gt;Pro, 20&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Plus, 8&amp;nbsp;$ (Grok seulement)&lt;/td&gt;
&lt;td&gt;Pro, 10&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Plus, 20&amp;nbsp;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avec les modèles de pointe&lt;/td&gt;
&lt;td&gt;Pro, 20&amp;nbsp;$ (Fable en crédits d'usage en plus)&lt;/td&gt;
&lt;td&gt;Premium, 30&amp;nbsp;$ + usage API des modèles tiers&lt;/td&gt;
&lt;td&gt;Pro 10&amp;nbsp;$ ou Pro+ 39&amp;nbsp;$ (tokens déduits des crédits)&lt;/td&gt;
&lt;td&gt;Plus, 20&amp;nbsp;$ (GPT-6 Astra&amp;nbsp;: 5 à 45 messages par 5 h)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intensif&lt;/td&gt;
&lt;td&gt;Max 100&amp;nbsp;$ ou Ultra 200&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Super 100&amp;nbsp;$ ou Ultra 200&amp;nbsp;$ + usage API des modèles tiers&lt;/td&gt;
&lt;td&gt;Max, 100&amp;nbsp;$&lt;/td&gt;
&lt;td&gt;Pro, 100&amp;nbsp;$ à 500&amp;nbsp;$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Un scénario chiffré.&lt;/strong&gt; Prenons une session d'agent qui consomme 2&amp;nbsp;millions de tokens en entrée et 200&amp;nbsp;000 en sortie sur Claude Sonnet 5.5, facturé 2&amp;nbsp;$ et 10&amp;nbsp;$ par million à l'API (&lt;a href="https://platform.claude.com/docs/en/about-claude/pricing#model-pricing" rel="noopener noreferrer"&gt;tarifs de l'API d'Anthropic&lt;/a&gt;, lus le 7 novembre 2026). Au prix API, cela fait 4&amp;nbsp;$ + 2&amp;nbsp;$ = 6&amp;nbsp;$, sans cache.&lt;/p&gt;

&lt;p&gt;Chez Cursor Premium, ces 6&amp;nbsp;$ s'ajoutent aux 30&amp;nbsp;$ de l'abonnement. Chez Copilot, qui décompte aux tarifs API de chaque modèle, la session consomme environ 600&amp;nbsp;crédits, soit 40&amp;nbsp;% des 1&amp;nbsp;500&amp;nbsp;crédits de Pro. Chez Claude Pro, elle entre dans un plafond dont la part consommée n'est pas publiée. Codex n'est pas comparable directement&amp;nbsp;: Sonnet n'y est pas proposé, et son coût dépend des fourchettes de messages de GPT-6 publiées par OpenAI.&lt;/p&gt;

&lt;p&gt;Pour une équipe de 5 en facturation mensuelle, le premier niveau d'équipe donne&amp;nbsp;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwqaqyi5ao5pr3to42ue.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwqaqyi5ao5pr3to42ue.webp" alt="Claude Code vs Cursor, Copilot et Codex&amp;nbsp;: coût mensuel de l'offre d'équipe pour 5 développeurs, de 95 à 150 dollars" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Notre calcul.&lt;/strong&gt; Entrée&amp;nbsp;: Copilot Business 5 × 19&amp;nbsp;$ = 95&amp;nbsp;$&amp;nbsp;; Claude Team standard 5 × 25&amp;nbsp;$ = 125&amp;nbsp;$ (100&amp;nbsp;$ en annuel)&amp;nbsp;; ChatGPT Business 5 × 25&amp;nbsp;$ = 125&amp;nbsp;$ (100&amp;nbsp;$ en annuel)&amp;nbsp;; Cursor Teams 5 × 30&amp;nbsp;$ = 150&amp;nbsp;$, plus les modèles tiers au prix API et 0,25&amp;nbsp;$ par million de tokens. Haut de gamme&amp;nbsp;: Copilot Enterprise 5 × 39&amp;nbsp;$ = 195&amp;nbsp;$&amp;nbsp;; Cursor Teams (siège à 100&amp;nbsp;$)&amp;nbsp;: 5 × 100&amp;nbsp;$ = 500&amp;nbsp;$&amp;nbsp;; Claude Team premium 5 × 125&amp;nbsp;$ = 625&amp;nbsp;$&amp;nbsp;; ChatGPT Enterprise sur devis.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Quel outil pour quel profil
&lt;/h2&gt;

&lt;p&gt;Recommandations tirées des pages officielles, pas d'un banc d'essai&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Étudiant.&lt;/strong&gt; Copilot Student est gratuit pour les étudiants vérifiés, et Gemini CLI offre 1&amp;nbsp;000&amp;nbsp;requêtes par jour avec un compte Google.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freelance, prix fixe.&lt;/strong&gt; Claude Pro ou ChatGPT Plus, à 20&amp;nbsp;$, incluent Claude Code ou Codex dans un plafond, sans facture variable, hors Fable et crédits d'usage activés. Notre article sur le &lt;a href="https://neurautech.com/freelance-et-ia/" rel="noopener noreferrer"&gt;freelance et l'IA&lt;/a&gt; aide à refacturer ce coût.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freelance, facture mesurée.&lt;/strong&gt; Copilot facture au crédit, ce qui rend chaque session lisible&amp;nbsp;; Pro+ (39&amp;nbsp;$) donne 7&amp;nbsp;000&amp;nbsp;crédits contre 1&amp;nbsp;500 pour Pro, et l'accès aux agents tiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utilisateur de Cursor.&lt;/strong&gt; Plus à 8&amp;nbsp;$ suffit si Grok et Composer vous conviennent&amp;nbsp;; Premium à 30&amp;nbsp;$ plus l'API si vous voulez Claude ou GPT dans l'éditeur, avec agents cloud et Bugbot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Équipe.&lt;/strong&gt; Partez des modèles dont l'équipe a besoin, car les quatre outils ont une CLI. Par siège et par mois&amp;nbsp;: Copilot Business 19&amp;nbsp;$, Claude Team et ChatGPT Business 25&amp;nbsp;$, Cursor Teams 30&amp;nbsp;$ plus les modèles tiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entreprise.&lt;/strong&gt; Regardez la conservation des données, SCIM et les journaux d'audit, listés pour les offres Enterprise de &lt;a href="https://claude.com/pricing" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, de &lt;a href="https://cursor.com/pricing" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; et d'&lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;. Claude (20&amp;nbsp;$ par siège plus l'usage API) et GitHub (39&amp;nbsp;$ par siège, sur GitHub Enterprise Cloud) affichent un prix&amp;nbsp;; Cursor et OpenAI passent par un devis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans le duel Claude Code vs Cursor, Cursor est un éditeur dérivé de VS Code, alors que Claude Code se greffe sur votre éditeur. Voyez notre comparatif des &lt;a href="https://neurautech.com/meilleurs-ide-editeurs-code-2026-comparatif/" rel="noopener noreferrer"&gt;IDE et éditeurs de code&lt;/a&gt;, nos &lt;a href="https://neurautech.com/raccourcis-vs-code/" rel="noopener noreferrer"&gt;raccourcis VS Code&lt;/a&gt; et notre guide pour &lt;a href="https://neurautech.com/comment-utiliser-lia-pour-coder-3x-plus-vite/" rel="noopener noreferrer"&gt;coder plus vite avec l'IA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nous ne publions pas de classement&amp;nbsp;: les scores des éditeurs mesurent un modèle, pas l'outil.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous avons exécuté
&lt;/h2&gt;

&lt;p&gt;Le 6 novembre 2026, sans compte, sous Windows 11 et Node.js 22.15.0&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm view @anthropic-ai/claude-code version              &lt;span class="c"&gt;# 2.1.318&lt;/span&gt;
npm view @openai/codex version                          &lt;span class="c"&gt;# 0.167.0&lt;/span&gt;
npm view @github/copilot version                        &lt;span class="c"&gt;# 1.0.106&lt;/span&gt;
npm view @google/gemini-cli version                     &lt;span class="c"&gt;# 0.67.0&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; @anthropic-ai/claude-code@2.1.318 &lt;span class="nt"&gt;--version&lt;/span&gt;   &lt;span class="c"&gt;# 2.1.318 (Claude Code)&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; @openai/codex@0.167.0 &lt;span class="nt"&gt;--version&lt;/span&gt;              &lt;span class="c"&gt;# codex-cli 0.167.0&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; @github/copilot@1.0.106 &lt;span class="nt"&gt;--version&lt;/span&gt;            &lt;span class="c"&gt;# GitHub Copilot CLI 1.0.106.&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; @google/gemini-cli@0.67.0 &lt;span class="nt"&gt;--version&lt;/span&gt;          &lt;span class="c"&gt;# 0.67.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nous avons aussi lancé &lt;code&gt;--help&lt;/code&gt;&amp;nbsp;: les quatre CLI listent une commande &lt;code&gt;mcp&lt;/code&gt;. La CLI de Cursor, installée par script, n'a pas été lancée. Cela prouve que les outils s'installent, pas qu'ils codent bien.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Plusieurs points restent ouverts au 7 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Les prix en euros.&lt;/strong&gt; Aucune page officielle n'en affichait. The Next Web rapporte 90&amp;nbsp;€ et 180&amp;nbsp;€ pour Claude Max et Ultra en Europe, montants non vus chez Anthropic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les réglages d'entraînement par défaut.&lt;/strong&gt; Les pages lues d'Anthropic et de Cursor n'indiquent pas l'état par défaut du réglage individuel&amp;nbsp;; la page d'aide d'OpenAI sur les contrôles de données a refusé notre accès automatisé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le partage de données entre Cursor et les autres sociétés de SpaceX&lt;/strong&gt;, au-delà de la clause générale sur les affiliés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le nombre réel de messages&lt;/strong&gt; inclus chez Anthropic et Cursor, qui ne publient que des multiples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SCIM et journaux d'audit chez GitHub&lt;/strong&gt;, et le prix de GitHub Enterprise Cloud requis par Copilot Enterprise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La qualité du code produit.&lt;/strong&gt; Aucun test n'a été mené, et aucun score de performance n'est cité.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Claude Code vs Cursor : lequel est le moins cher ?
&lt;/h3&gt;

&lt;p&gt;À l'entrée, Cursor Plus coûte 8&amp;nbsp;$ contre 20&amp;nbsp;$ pour Claude Pro, mais Plus ne donne accès qu'aux modèles Grok. Pour utiliser Claude dans Cursor, il faut Premium à 30&amp;nbsp;$ plus l'usage au prix de l'API (&lt;a href="https://cursor.com/docs/models-and-pricing" rel="noopener noreferrer"&gt;documentation de Cursor&lt;/a&gt;). Avec Claude Pro, Claude Code fonctionne sans facture API, dans les limites de Pro&amp;nbsp;; Fable y est facturé en crédits d'usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combien coûte GitHub Copilot en euros ?
&lt;/h3&gt;

&lt;p&gt;Aucun prix en euros n'est affiché&amp;nbsp;: 10&amp;nbsp;$ pour Pro, 39&amp;nbsp;$ pour Pro+, 100&amp;nbsp;$ pour Max, 19&amp;nbsp;$ par siège pour Business (&lt;a href="https://docs.github.com/en/copilot/get-started/plans" rel="noopener noreferrer"&gt;documentation GitHub&lt;/a&gt;). Le montant prélevé dépend du change et des taxes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peut-on utiliser Claude Code dans Cursor ?
&lt;/h3&gt;

&lt;p&gt;Oui, selon le &lt;a href="https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-max-or-ultra-plan" rel="noopener noreferrer"&gt;centre d'aide d'Anthropic&lt;/a&gt;. Attention aux versions 2.1.312 et 2.1.313 de l'extension, non publiées par Anthropic, apparues le 29 octobre 2026 sur la place de marché de Cursor. L'&lt;a href="https://cursor.com/blog/claude-code-extension-security-notice" rel="noopener noreferrer"&gt;avis de Cursor&lt;/a&gt; indique de chercher la clé SSH nommée «&amp;nbsp;svc-telemetry&amp;nbsp;» dans le fichier &lt;code&gt;authorized_keys&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Codex est-il gratuit ?
&lt;/h3&gt;

&lt;p&gt;En partie&amp;nbsp;: l'offre gratuite donne GPT-6 Luna dans l'application de bureau, en déploiement progressif. Le CLI, l'extension IDE et le cloud commencent avec Plus à 20&amp;nbsp;$ (&lt;a href="https://learn.chatgpt.com/docs/pricing" rel="noopener noreferrer"&gt;page des prix de Codex&lt;/a&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il publie sur NeurauTech des guides et des comparatifs pour les développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse des pages de prix, de la documentation et des journaux des modifications d'Anthropic, de Cursor, de GitHub, d'OpenAI et de Google, consultés les 6 et 7 novembre 2026, complétés par la presse quand l'éditeur ne date pas un changement. La rédaction de cet article a été assistée par des agents IA (Claude, d'Anthropic), l'un des éditeurs comparés&amp;nbsp;; les prix et limites viennent des pages officielles citées. Aucun test d'usage&amp;nbsp;: seules les commandes &lt;code&gt;npm view&lt;/code&gt;, &lt;code&gt;--version&lt;/code&gt; et &lt;code&gt;--help&lt;/code&gt; ci-dessus ont été exécutées, le 6 novembre 2026. Aucun lien n'est affilié.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un prix périmé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 7 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image&amp;nbsp;: Alberlan Barros via Pexels (Pexels License). Graphiques&amp;nbsp;: NeurauTech, à partir des pages de prix citées.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>cursor</category>
      <category>githubcopilot</category>
      <category>codex</category>
    </item>
    <item>
      <title>Next.js c'est quoi ? Version 16, rendu, cache et premier projet</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 15:55:26 +0000</pubDate>
      <link>https://dev.to/neurau_tech/nextjs-cest-quoi-version-16-rendu-cache-et-premier-projet-1foh</link>
      <guid>https://dev.to/neurau_tech/nextjs-cest-quoi-version-16-rendu-cache-et-premier-projet-1foh</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Next.js est un framework web construit sur React et maintenu par Vercel. React fournit les composants&amp;nbsp;; Next.js ajoute le routage par fichiers, le rendu sur le serveur, le cache, des points d'API et un outil de build. Le 6 novembre 2026, la dernière version stable est la 16.4.5, publiée le 3 novembre selon le &lt;a href="https://registry.npmjs.org/next/latest" rel="noopener noreferrer"&gt;registre npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ce guide repose sur des sources officielles consultées le 6 novembre 2026. Nous avons aussi créé, compilé et lancé un petit projet, et nous détaillons ce qui a été exécuté.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 16.4.5 est la version stable&amp;nbsp;; elle demande Node.js 20.9 ou plus.&lt;/li&gt;
&lt;li&gt;Depuis la 16.4, les nouveaux projets activent les Cache Components&amp;nbsp;: le cache devient explicite, avec &lt;code&gt;"use cache"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Un &lt;code&gt;fetch&lt;/code&gt; n'est pas mis en cache par défaut. Dans notre projet, un &lt;code&gt;fetch&lt;/code&gt; sans cache ni &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; a fait échouer le build.&lt;/li&gt;
&lt;li&gt;Next.js tourne aussi hors de Vercel, dont l'offre gratuite est réservée à un usage non commercial.&lt;/li&gt;
&lt;li&gt;Une mise à jour de sécurité sort environ chaque mois depuis juillet 2026.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Next.js, c'est quoi exactement ?
&lt;/h2&gt;

&lt;p&gt;Next.js est un framework React pour construire des applications web complètes, interface et serveur dans le même projet. La documentation de React le décrit comme «&amp;nbsp;un framework React qui exploite pleinement l'architecture de React pour permettre des applications React full-stack&amp;nbsp;» (notre traduction, &lt;a href="https://react.dev/learn/creating-a-react-app" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;React est une bibliothèque d'interface&amp;nbsp;; avec React et Vite, vous choisissez vous-même routeur, chargement des données et rendu serveur. Next.js fournit ces briques avec des conventions. Pour React lui-même, voyez notre comparatif &lt;a href="https://neurautech.com/react-vs-vue/" rel="noopener noreferrer"&gt;React vs Vue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next.js ajoute à React&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;un routage par fichiers&lt;/strong&gt;&amp;nbsp;: le fichier &lt;code&gt;app/blog/page.tsx&lt;/code&gt; devient l'URL &lt;code&gt;/blog&lt;/code&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;le rendu sur le serveur&lt;/strong&gt;, au build ou à la demande, pour envoyer du HTML déjà rempli&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;du code serveur&lt;/strong&gt;&amp;nbsp;: gestionnaires de route et Server Actions&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;un cache&lt;/strong&gt; des données et des pages&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;des optimisations&lt;/strong&gt; pour les images, les polices et le découpage du JavaScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour les bases, voyez notre cours &lt;a href="https://neurautech.com/html-css-debutant/" rel="noopener noreferrer"&gt;HTML CSS débutant&lt;/a&gt;, puis nos guides pour &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;apprendre JavaScript&lt;/a&gt; et &lt;a href="https://neurautech.com/apprendre-typescript/" rel="noopener noreferrer"&gt;apprendre TypeScript&lt;/a&gt;, le langage par défaut des projets Next.js.&lt;/p&gt;




&lt;h2&gt;
  
  
  Version actuelle et prérequis
&lt;/h2&gt;

&lt;p&gt;La version stable est Next.js 16.4.5, un correctif de sécurité de la branche 16.4 sortie le 6 octobre 2026 (&lt;a href="https://nextjs.org/blog/next-16-4" rel="noopener noreferrer"&gt;blog Next.js&lt;/a&gt;, &lt;a href="https://github.com/vercel/next.js/releases/tag/v16.4.5" rel="noopener noreferrer"&gt;note de version&lt;/a&gt;).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Élément&lt;/th&gt;
&lt;th&gt;Valeur au 6 novembre 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Version stable&lt;/td&gt;
&lt;td&gt;16.4.5 (3 novembre 2026), dite «&amp;nbsp;Active LTS&amp;nbsp;»&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Branche maintenue en parallèle&lt;/td&gt;
&lt;td&gt;15.5.29, dite «&amp;nbsp;Maintenance LTS&amp;nbsp;»&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js minimum&lt;/td&gt;
&lt;td&gt;20.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript minimum&lt;/td&gt;
&lt;td&gt;5.1.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigateurs&lt;/td&gt;
&lt;td&gt;Chrome et Edge 111+, Firefox 111+, Safari 16.4+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://nextjs.org/docs/app/getting-started/installation" rel="noopener noreferrer"&gt;page d'installation&lt;/a&gt;, mise à jour le 2 octobre 2026, et &lt;a href="https://nextjs.org/blog/november-2026-security-release" rel="noopener noreferrer"&gt;mise à jour de sécurité du 3 novembre&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;La branche 16 date du 21 octobre 2025. Ses &lt;a href="https://nextjs.org/blog/next-16" rel="noopener noreferrer"&gt;notes de version&lt;/a&gt; expliquent pourquoi beaucoup de tutoriels sont périmés&amp;nbsp;: Node.js 18 n'est plus pris en charge, Turbopack devient le bundler par défaut, &lt;code&gt;middleware.ts&lt;/code&gt; est renommé &lt;code&gt;proxy.ts&lt;/code&gt; et &lt;code&gt;next build&lt;/code&gt; ne lance plus le linter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Composants serveur et composants client
&lt;/h2&gt;

&lt;p&gt;Dans l'App Router, un composant est un composant serveur tant que vous ne dites pas le contraire. Selon la &lt;a href="https://nextjs.org/docs/app/getting-started/server-and-client-components" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, les layouts et les pages sont par défaut des Server Components.&lt;/p&gt;

&lt;p&gt;Un composant serveur peut lire une base de données ou utiliser une clé secrète, et son code n'est pas envoyé au navigateur&amp;nbsp;; il ne peut pas utiliser &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;onClick&lt;/code&gt; ni &lt;code&gt;window&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Un composant client commence par &lt;code&gt;"use client"&lt;/code&gt;. Il est rendu en HTML, puis «&amp;nbsp;hydraté&amp;nbsp;» dans le navigateur pour devenir interactif. La directive marque une frontière&amp;nbsp;: tout ce que ce fichier importe et rend directement passe aussi côté client, sans directive propre. Un composant serveur transmis en &lt;code&gt;children&lt;/code&gt; reste, lui, rendu sur le serveur. La règle pratique&amp;nbsp;: tout en composant serveur, et &lt;code&gt;"use client"&lt;/code&gt; seulement sur les petites parties interactives.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les modes de rendu : SSR, SSG, ISR et streaming
&lt;/h2&gt;

&lt;p&gt;Next.js choisit le mode de rendu route par route, et &lt;code&gt;next build&lt;/code&gt; affiche celui qu'il a retenu.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Principe&lt;/th&gt;
&lt;th&gt;Comment l'obtenir en 16.4&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSG (statique)&lt;/td&gt;
&lt;td&gt;HTML produit au build&lt;/td&gt;
&lt;td&gt;Pas de donnée dynamique, ou données en &lt;code&gt;"use cache"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PPR (prérendu partiel)&lt;/td&gt;
&lt;td&gt;Coquille statique servie tout de suite, parties dynamiques diffusées à la requête&lt;/td&gt;
&lt;td&gt;Comportement par défaut avec les Cache Components&amp;nbsp;: &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; autour des données dynamiques&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSR (rendu serveur complet)&lt;/td&gt;
&lt;td&gt;Toute la page produite à chaque requête&lt;/td&gt;
&lt;td&gt;Avec les Cache Components, seulement sur option explicite (route bloquante)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ISR (régénération)&lt;/td&gt;
&lt;td&gt;Page statique régénérée après un délai ou à la demande&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;cacheLife&lt;/code&gt;, &lt;code&gt;revalidateTag&lt;/code&gt;, &lt;code&gt;revalidatePath&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming&lt;/td&gt;
&lt;td&gt;Les parties lentes arrivent après le reste&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; ou &lt;code&gt;loading.tsx&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSR (rendu client)&lt;/td&gt;
&lt;td&gt;Données chargées par le navigateur&lt;/td&gt;
&lt;td&gt;Composant client, SWR, React Query&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Avec les Cache Components, la documentation appelle ce modèle Partial Prerendering&amp;nbsp;: le build produit une coquille statique, et chaque partie dynamique placée dans un &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; arrive ensuite (&lt;a href="https://nextjs.org/docs/app/getting-started/caching" rel="noopener noreferrer"&gt;documentation sur le cache&lt;/a&gt;). Les robots qui ne lisent que le HTML sont traités à part&amp;nbsp;: Next.js attend les métadonnées pour les placer dans le &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, et l'option &lt;code&gt;htmlLimitedBots&lt;/code&gt; fixe la liste de ces robots (&lt;a href="https://nextjs.org/docs/app/guides/streaming" rel="noopener noreferrer"&gt;guide du streaming&lt;/a&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  App Router ou Pages Router ?
&lt;/h2&gt;

&lt;p&gt;Pour un nouveau projet Next.js, choisissez l'App Router. La &lt;a href="https://nextjs.org/docs/pages" rel="noopener noreferrer"&gt;documentation du Pages Router&lt;/a&gt; le dit elle-même&amp;nbsp;: il reste pris en charge, mais l'équipe recommande de migrer vers l'App Router pour profiter des dernières fonctions de React.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critère&lt;/th&gt;
&lt;th&gt;App Router (&lt;code&gt;app/&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Pages Router (&lt;code&gt;pages/&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Statut&lt;/td&gt;
&lt;td&gt;Recommandé, défaut de &lt;code&gt;create-next-app&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Pris en charge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Composants serveur&lt;/td&gt;
&lt;td&gt;Oui, par défaut&lt;/td&gt;
&lt;td&gt;Non&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Points d'API&lt;/td&gt;
&lt;td&gt;Gestionnaires de route (&lt;code&gt;route.ts&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;API Routes (&lt;code&gt;pages/api&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Données&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fetch&lt;/code&gt; dans les composants, &lt;code&gt;"use cache"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;getServerSideProps&lt;/code&gt;, &lt;code&gt;getStaticProps&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Une base de code existante sur le Pages Router peut y rester&amp;nbsp;; la documentation prévoit une &lt;a href="https://nextjs.org/docs/app/guides/migrating/app-router-migration" rel="noopener noreferrer"&gt;migration progressive&lt;/a&gt; de &lt;code&gt;pages&lt;/code&gt; vers &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Données, cache et code serveur
&lt;/h2&gt;

&lt;p&gt;Le comportement par défaut du cache a changé deux fois, d'où des tutoriels contradictoires. Dans Next.js 14, un &lt;code&gt;fetch&lt;/code&gt; était mis en cache par défaut. Next.js 15 a inversé ce choix&amp;nbsp;: &lt;code&gt;fetch&lt;/code&gt;, gestionnaires de route &lt;code&gt;GET&lt;/code&gt; et navigations côté client ne sont plus en cache par défaut (&lt;a href="https://nextjs.org/blog/next-15" rel="noopener noreferrer"&gt;blog Next.js 15&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Next.js 16 a ajouté les Cache Components, un cache «&amp;nbsp;entièrement opt-in&amp;nbsp;» (notre traduction, &lt;a href="https://nextjs.org/blog/next-16" rel="noopener noreferrer"&gt;blog Next.js 16&lt;/a&gt;). La &lt;a href="https://nextjs.org/docs/app/getting-started/caching" rel="noopener noreferrer"&gt;documentation sur le cache&lt;/a&gt;, mise à jour le 6 octobre 2026, fixe les règles&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un &lt;code&gt;fetch&lt;/code&gt; n'est pas mis en cache&amp;nbsp;; deux appels identiques dans un même rendu sont seulement mémoïsés&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"use cache"&lt;/code&gt; met en cache une fonction ou un composant, de préférence avec &lt;code&gt;cacheLife&lt;/code&gt;&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;une donnée non mise en cache doit être placée dans un &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gestionnaires de route.&lt;/strong&gt; Un fichier &lt;code&gt;route.ts&lt;/code&gt; répond aux requêtes HTTP avec les objets standard &lt;code&gt;Request&lt;/code&gt; et &lt;code&gt;Response&lt;/code&gt;&amp;nbsp;; c'est l'équivalent des API Routes (&lt;a href="https://nextjs.org/docs/app/getting-started/route-handlers" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;). Notre article &lt;a href="https://neurautech.com/api-c-est-quoi/" rel="noopener noreferrer"&gt;API, c'est quoi&amp;nbsp;?&lt;/a&gt; explique les requêtes et le JSON.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server Actions.&lt;/strong&gt; Une Server Action est une fonction serveur appelée depuis un formulaire ou un bouton, en &lt;code&gt;POST&lt;/code&gt;. Elle est joignable par une requête directe, prévient la &lt;a href="https://nextjs.org/docs/app/getting-started/mutating-data" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;&amp;nbsp;: vérifiez les droits dans chacune.&lt;/p&gt;




&lt;h2&gt;
  
  
  Premier projet Next.js pas à pas
&lt;/h2&gt;

&lt;p&gt;Voici le projet que nous avons créé le 6 novembre 2026 sous Windows 11, avec Node.js 22.15.0 et npm 10.9.2&amp;nbsp;: un composant serveur qui lit une API publique, un composant client avec un compteur, et un gestionnaire de route.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Créer le projet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@16.4.5 mon-app &lt;span class="nt"&gt;--ts&lt;/span&gt; &lt;span class="nt"&gt;--app&lt;/span&gt; &lt;span class="nt"&gt;--eslint&lt;/span&gt; &lt;span class="nt"&gt;--tailwind&lt;/span&gt; &lt;span class="nt"&gt;--use-npm&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;mon-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L'outil a installé next 16.4.5, react et react-dom 19.3.0, TypeScript 5.9.3 et Tailwind CSS 4.3.4. Le &lt;code&gt;next.config.ts&lt;/code&gt; généré contient déjà &lt;code&gt;cacheComponents: true&lt;/code&gt;. En fin d'installation, &lt;code&gt;npm audit&lt;/code&gt; signalait 8 vulnérabilités de gravité modérée dans les dépendances.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Un composant serveur qui lit une API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/DerniereVersion.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cacheLife&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PaquetNpm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Composant serveur : ce code ne part jamais dans le navigateur.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DerniereVersion&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;cacheLife&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hours&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://registry.npmjs.org/next/latest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Registre npm : HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paquet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaquetNpm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Dernière version de &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;paquet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; sur npm : &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;paquet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Un composant client avec un état
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/Compteur.tsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Composant client : il a un état et réagit aux clics.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Compteur&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setClics&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setClics&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded bg-black px-4 py-2 text-white"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Cliqué &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;clics&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; fois
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Un gestionnaire de route et la page
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/bonjour/route.ts&lt;/span&gt;
&lt;span class="c1"&gt;// Gestionnaire de route : GET /api/bonjour?nom=Ada&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inconnu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bonjour &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Compteur&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/Compteur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DerniereVersion&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/DerniereVersion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mx-auto flex max-w-xl flex-col gap-6 p-10"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl font-semibold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Mon premier projet Next.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DerniereVersion&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Compteur&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Essayez aussi &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"underline"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/api/bonjour?nom=Ada"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;/api/bonjour?nom=Ada&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;.
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Compiler et lancer
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;npm run build&lt;/code&gt; a réussi. Voici sa sortie brute, colonnes comprises, à une exception près&amp;nbsp;: nous avons retiré les deux lignes d'un avertissement propre à notre machine, qui signalait un &lt;code&gt;package-lock.json&lt;/code&gt; égaré dans le dossier personnel, hors du projet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;▲ Next.js 16.4.5 (Turbopack)

✓ Running next.config.ts took 424ms
- Cache Components enabled
- Partial Prefetching enabled

  Creating an optimized production build ...
✓ Compiled successfully in 11.5s
  Running TypeScript ...
  Finished TypeScript in 9.2s ...
  Collecting page data using 6 workers ...
  Generating static pages using 6 workers (0/5) ...
  Generating static pages using 6 workers (1/5) 
  Generating static pages using 6 workers (2/5) 
  Generating static pages using 6 workers (3/5) 
✓ Generating static pages using 6 workers (5/5) in 3.3s
  Finalizing page optimization ...

Route (app)       Revalidate  Expire
┌ ○ /                     1h      1d
├ ○ /_not-found
└ ƒ /api/bonjour


○  (Static)   prerendered as static content
ƒ  (Dynamic)  server-rendered on demand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La page d'accueil est statique et revalidée toutes les heures, à cause de &lt;code&gt;cacheLife("hours")&lt;/code&gt;. Le gestionnaire de route est dynamique, car il lit la requête. Après &lt;code&gt;npm start&lt;/code&gt;, &lt;code&gt;/api/bonjour?nom=Ada&lt;/code&gt; a renvoyé &lt;code&gt;{"message":"Bonjour Ada","date":"2026-11-06T15:09:49.906Z"}&lt;/code&gt;, et la page d'accueil portait l'en-tête &lt;code&gt;Cache-Control: s-maxage=3600, stale-while-revalidate=82800&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bt0cpqv3vi427zg2ugb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bt0cpqv3vi427zg2ugb.webp" alt="Capture du premier projet Next.js&amp;nbsp;: dernière version de next lue sur npm (16.4.5) et bouton compteur cliqué 3 fois" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans Chromium 120 piloté par Playwright 1.40, trois clics ont fait passer le compteur de 0 à 3&amp;nbsp;: l'hydratation fonctionne.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. L'erreur que vous allez rencontrer
&lt;/h3&gt;

&lt;p&gt;Lors d'un premier essai, avant d'ajouter la vérification &lt;code&gt;res.ok&lt;/code&gt;, nous avions retiré &lt;code&gt;"use cache"&lt;/code&gt; et &lt;code&gt;cacheLife&lt;/code&gt;. Le build avait échoué&amp;nbsp;: &lt;code&gt;Route "/": Next.js encountered uncached or runtime data during prerendering.&lt;/code&gt; Next.js propose trois corrections&amp;nbsp;: entourer la lecture d'un &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;, la mettre en cache avec &lt;code&gt;"use cache"&lt;/code&gt;, ou accepter une route bloquante avec &lt;code&gt;export const instant = false&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Turbopack et déploiement
&lt;/h2&gt;

&lt;p&gt;Turbopack est le bundler par défaut depuis Next.js 16, stable en développement comme en production (&lt;a href="https://nextjs.org/blog/next-16" rel="noopener noreferrer"&gt;blog Next.js 16&lt;/a&gt;). Webpack reste disponible avec l'option &lt;code&gt;--webpack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vercel n'est pas obligatoire. La &lt;a href="https://nextjs.org/docs/app/getting-started/deploying" rel="noopener noreferrer"&gt;documentation de déploiement&lt;/a&gt; liste quatre options&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Fonctions prises en charge&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Serveur Node.js (&lt;code&gt;next build&lt;/code&gt; puis &lt;code&gt;next start&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Toutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conteneur Docker&lt;/td&gt;
&lt;td&gt;Toutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Export statique (&lt;code&gt;output: "export"&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Limitées&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adaptateurs (Vercel et Bun vérifiés&amp;nbsp;; Cloudflare, Netlify, AWS Amplify par leurs propres intégrations)&lt;/td&gt;
&lt;td&gt;Variables&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pour Docker, &lt;code&gt;output: "standalone"&lt;/code&gt; crée un dossier &lt;code&gt;.next/standalone&lt;/code&gt; avec un &lt;code&gt;server.js&lt;/code&gt; minimal et les seules dépendances nécessaires, sans &lt;code&gt;public&lt;/code&gt; ni &lt;code&gt;.next/static&lt;/code&gt;, à copier à part (&lt;a href="https://nextjs.org/docs/app/api-reference/config/next-config-js/output" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;). Sur notre projet, ce dossier pesait 32&amp;nbsp;Mo et &lt;code&gt;node server.js&lt;/code&gt; a servi la page et l'API. Voyez notre guide &lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt; et notre tutoriel &lt;a href="https://neurautech.com/nginx-reverse-proxy-docker-compose/" rel="noopener noreferrer"&gt;Nginx reverse proxy avec Docker Compose&lt;/a&gt; pour le HTTPS.&lt;/p&gt;

&lt;p&gt;L'export statique se sert depuis n'importe quel serveur web, mais perd notamment les Server Actions, l'ISR, les cookies, le Proxy et l'optimisation d'images par défaut (&lt;a href="https://nextjs.org/docs/app/guides/static-exports" rel="noopener noreferrer"&gt;guide des exports statiques&lt;/a&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  Combien coûte l'hébergement ?
&lt;/h2&gt;

&lt;p&gt;Next.js est gratuit et open source. L'offre Hobby de Vercel est gratuite mais limitée à un usage personnel non commercial, selon sa &lt;a href="https://vercel.com/docs/plans/hobby" rel="noopener noreferrer"&gt;page&lt;/a&gt; mise à jour le 14 septembre 2026. Elle inclut notamment 100&amp;nbsp;Go de transfert de données et 1&amp;nbsp;million d'invocations de fonctions par mois&amp;nbsp;; l'offre Pro coûte 20&amp;nbsp;$ par développeur et par mois.&lt;/p&gt;

&lt;p&gt;Les &lt;a href="https://vercel.com/docs/limits/fair-use-guidelines" rel="noopener noreferrer"&gt;règles d'usage équitable&lt;/a&gt; qualifient de commercial tout déploiement qui sert le gain financier d'une personne impliquée, publicité et promotion de services comprises. Notre guide du &lt;a href="https://neurautech.com/portfolio-developpeur-comment-le-construire-2026/" rel="noopener noreferrer"&gt;portfolio de développeur&lt;/a&gt; en tire la conséquence&amp;nbsp;: un portfolio qui vend vos services relève de l'offre payante. Les autres options sont dans notre comparatif de l'&lt;a href="https://neurautech.com/hebergement-cloud-pour-developpeurs/" rel="noopener noreferrer"&gt;hébergement cloud pour développeurs&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sécurité : les failles à connaître
&lt;/h2&gt;

&lt;p&gt;Deux failles critiques ont marqué 2025, et les correctifs, dont plusieurs critiques, sont devenus mensuels en 2026. La conclusion&amp;nbsp;: tenez Next.js à jour, avec &lt;code&gt;npx next upgrade&lt;/code&gt; comme le recommande la &lt;a href="https://nextjs.org/docs/app/getting-started/installation" rel="noopener noreferrer"&gt;page d'installation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2025-29927.&lt;/strong&gt; Publiée le 21 mars 2025 et notée CVSS 9,1, cette faille permettait de contourner les contrôles d'autorisation placés dans le middleware avec l'en-tête &lt;code&gt;x-middleware-subrequest&lt;/code&gt; (&lt;a href="https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw" rel="noopener noreferrer"&gt;avis GitHub&lt;/a&gt;). Corrigée en 12.3.5, 13.5.9, 14.2.25 et 15.2.3. Elle touchait les applications auto-hébergées avec &lt;code&gt;next start&lt;/code&gt; ou &lt;code&gt;output: "standalone"&lt;/code&gt;&amp;nbsp;; selon le &lt;a href="https://vercel.com/blog/postmortem-on-next-js-middleware-bypass" rel="noopener noreferrer"&gt;post-mortem de Vercel&lt;/a&gt;, les sites hébergés chez Vercel, Netlify ou Cloudflare Workers et les exports statiques n'étaient pas concernés. La &lt;a href="https://nextjs.org/docs/app/getting-started/proxy" rel="noopener noreferrer"&gt;documentation du Proxy&lt;/a&gt;, nouveau nom du middleware, déconseille d'en faire une solution complète d'autorisation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2025-55182, dite React2Shell.&lt;/strong&gt; Le 3 décembre 2025, une faille des React Server Components notée CVSS 10,0 a été rendue publique&amp;nbsp;: elle permettait une exécution de code à distance sans authentification (&lt;a href="https://www.cve.org/CVERecord?id=CVE-2025-55182" rel="noopener noreferrer"&gt;fiche CVE&lt;/a&gt;). Next.js l'avait suivie sous CVE-2025-66478, identifiant depuis rejeté comme doublon de CVE-2025-55182 (&lt;a href="https://www.cve.org/CVERecord?id=CVE-2025-66478" rel="noopener noreferrer"&gt;fiche CVE&lt;/a&gt;). Les applications App Router en 15.x et 16.x étaient touchées&amp;nbsp;; les versions corrigées sont 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7 et 16.0.7, et l'équipe recommandait de changer les secrets des applications restées exposées (&lt;a href="https://nextjs.org/blog/CVE-2025-66478" rel="noopener noreferrer"&gt;avis Next.js&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Un rythme mensuel.&lt;/strong&gt; Le 13 juillet 2026, Next.js a annoncé des mises à jour de sécurité planifiées, environ une par mois (&lt;a href="https://nextjs.org/blog/next-security-release-program" rel="noopener noreferrer"&gt;blog Next.js&lt;/a&gt;). Ont suivi les mises à jour du &lt;a href="https://nextjs.org/blog/july-2026-security-release" rel="noopener noreferrer"&gt;20 juillet&lt;/a&gt;, du &lt;a href="https://nextjs.org/blog/august-2026-security-release" rel="noopener noreferrer"&gt;25 août&lt;/a&gt;, du &lt;a href="https://nextjs.org/blog/nextjs-security-update-september-22-2026" rel="noopener noreferrer"&gt;22 septembre&lt;/a&gt; (mise à jour urgente 16.3.6 contre une exécution de code critique dans &lt;code&gt;ImageResponse&lt;/code&gt;) et du &lt;a href="https://nextjs.org/blog/september-2026-security-release" rel="noopener noreferrer"&gt;30 septembre&lt;/a&gt;. Celle du 14 octobre (16.4.1) corrigeait deux failles critiques d'exécution de code, liées à &lt;code&gt;"use cache"&lt;/code&gt; et à l'optimisation d'images SVG (&lt;a href="https://nextjs.org/blog/nextjs-security-update-october-14-2026" rel="noopener noreferrer"&gt;blog Next.js&lt;/a&gt;). Celle du 3 novembre corrige une faille élevée et six moyennes (&lt;a href="https://nextjs.org/blog/november-2026-security-release" rel="noopener noreferrer"&gt;blog Next.js&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj8l9qjtfrz2f93oyeet7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj8l9qjtfrz2f93oyeet7.webp" alt="Chronologie des failles et mises à jour de sécurité de Next.js, de mars 2025 à novembre 2026" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En pratique&amp;nbsp;: vérifiez les droits dans chaque Server Action et chaque gestionnaire de route, et automatisez les mises à jour et les tests, par exemple avec &lt;a href="https://neurautech.com/github-actions-tutoriel/" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Popularité : ce que disent les chiffres
&lt;/h2&gt;

&lt;p&gt;L'enquête Stack Overflow 2026 a recueilli 30&amp;nbsp;903 réponses valides du 23 juin au 5 août 2026 (&lt;a href="https://survey.stackoverflow.co/2026/methodology" rel="noopener noreferrer"&gt;méthodologie&lt;/a&gt;). Parmi les 10&amp;nbsp;281 répondants à la question sur les frameworks web, 20,6&amp;nbsp;% ont beaucoup travaillé avec Next.js dans l'année, contre 41,5&amp;nbsp;% pour React, 17,2&amp;nbsp;% pour Vue.js, 16,0&amp;nbsp;% pour Angular, 7,8&amp;nbsp;% pour Svelte, 6,2&amp;nbsp;% pour Astro, 4,4&amp;nbsp;% pour Nuxt.js et 1,7&amp;nbsp;% pour Remix (&lt;a href="https://survey.stackoverflow.co/2026/technology/data" rel="noopener noreferrer"&gt;données 2026&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F851p3out0m1waxpc1ixv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F851p3out0m1waxpc1ixv.webp" alt="Usage des frameworks web selon l'enquête Stack Overflow 2026&amp;nbsp;: React 41,5&amp;nbsp;%, Next.js 20,6&amp;nbsp;%, Vue.js 17,2&amp;nbsp;%, Angular 16,0&amp;nbsp;%" width="799" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ces pourcentages décrivent les répondants, pas l'ensemble des développeurs. Autre angle&amp;nbsp;: du 27 octobre au 2 novembre 2026, le paquet &lt;code&gt;next&lt;/code&gt; a été téléchargé &lt;a href="https://api.npmjs.org/downloads/point/2026-10-27:2026-11-02/next" rel="noopener noreferrer"&gt;89&amp;nbsp;744&amp;nbsp;743 fois&lt;/a&gt; sur npm, &lt;code&gt;react-router&lt;/code&gt; &lt;a href="https://api.npmjs.org/downloads/point/2026-10-27:2026-11-02/react-router" rel="noopener noreferrer"&gt;73&amp;nbsp;416&amp;nbsp;892 fois&lt;/a&gt; et &lt;code&gt;nuxt&lt;/code&gt; &lt;a href="https://api.npmjs.org/downloads/point/2026-10-27:2026-11-02/nuxt" rel="noopener noreferrer"&gt;3&amp;nbsp;263&amp;nbsp;303 fois&lt;/a&gt;. La même semaine de 2025, &lt;code&gt;next&lt;/code&gt; en comptait &lt;a href="https://api.npmjs.org/downloads/point/2025-10-27:2025-11-02/next" rel="noopener noreferrer"&gt;15&amp;nbsp;115&amp;nbsp;622&lt;/a&gt;&amp;nbsp;: une multiplication par six que l'API ne permet pas d'expliquer. Ces chiffres incluent les installations automatiques en intégration continue, et ceux de &lt;code&gt;react-router&lt;/code&gt; comptent aussi les applications qui l'utilisent comme simple routeur côté client.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next.js, React avec Vite, React Router ou Nuxt ?
&lt;/h2&gt;

&lt;p&gt;Le bon choix dépend de ce que l'application doit faire côté serveur. La documentation de React recommande de partir d'un framework, comme Next.js ou React Router (&lt;a href="https://react.dev/learn/creating-a-react-app" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt;).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Votre besoin&lt;/th&gt;
&lt;th&gt;Choix raisonnable&lt;/th&gt;
&lt;th&gt;Pourquoi&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Site public à référencer, avec API et formulaires&lt;/td&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;td&gt;Rendu serveur, cache et code serveur dans un seul projet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tableau de bord derrière une connexion, sans SEO&lt;/td&gt;
&lt;td&gt;React avec Vite&lt;/td&gt;
&lt;td&gt;Moins de concepts, aucun serveur à exploiter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application React full-stack centrée sur le routage&lt;/td&gt;
&lt;td&gt;React Router 8.5.1&lt;/td&gt;
&lt;td&gt;Héritier de Remix 2&amp;nbsp;; demande Node.js 22.22 ou plus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Équipe qui préfère Vue&lt;/td&gt;
&lt;td&gt;Nuxt 4.6.4&lt;/td&gt;
&lt;td&gt;L'équivalent de Next.js pour Vue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site de contenu&amp;nbsp;: blog, documentation, marketing&lt;/td&gt;
&lt;td&gt;Astro 7.4.7&lt;/td&gt;
&lt;td&gt;Conçu pour les sites centrés sur le contenu (&lt;a href="https://docs.astro.build/en/concepts/why-astro/" rel="noopener noreferrer"&gt;documentation d'Astro&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Remix a fusionné dans React Router v7, annonçaient ses créateurs en mai 2024 (&lt;a href="https://remix.run/blog/merging-remix-and-react-router" rel="noopener noreferrer"&gt;blog Remix&lt;/a&gt;). Le nom désigne aujourd'hui Remix 3, qui n'est plus construit sur React&amp;nbsp;: son annonce de mai 2025 parle de «&amp;nbsp;pas même React&amp;nbsp;» comme dépendance et d'un départ sur un fork de Preact (notre traduction, &lt;a href="https://remix.run/blog/wake-up-remix" rel="noopener noreferrer"&gt;blog Remix&lt;/a&gt;), et le paquet &lt;code&gt;remix&lt;/code&gt; 3.2.0 ne dépend ni de React ni de Preact sur npm. Versions lues sur le registre npm le 6 novembre 2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Les 8 vulnérabilités modérées&lt;/strong&gt; signalées par &lt;code&gt;npm audit&lt;/code&gt;&amp;nbsp;: non analysées.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les performances.&lt;/strong&gt; Une compilation de 11,5&amp;nbsp;secondes sur une seule machine n'est pas une mesure comparative&amp;nbsp;; aucun test de charge n'a été fait.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le déploiement réel.&lt;/strong&gt; Nous avons lancé &lt;code&gt;next start&lt;/code&gt; et le serveur standalone en local, sans construire d'image Docker ni déployer sur Vercel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les scores CVSS des failles de 2026&lt;/strong&gt;, que les billets du blog ne donnent pas tous.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State of JS&lt;/strong&gt;&amp;nbsp;: non consulté pour cet article.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Next.js, c'est du front-end ou du back-end ?
&lt;/h3&gt;

&lt;p&gt;Les deux&amp;nbsp;: l'interface React, et du code serveur avec les composants serveur, les gestionnaires de route et les Server Actions. Pour de longs calculs, un back-end séparé reste souvent plus adapté.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faut-il apprendre React avant Next.js ?
&lt;/h3&gt;

&lt;p&gt;Oui. Next.js repose sur les composants, les props, l'état et les hooks de React, et ses messages d'erreur supposent qu'on les connaît.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quelle est la dernière version de Next.js ?
&lt;/h3&gt;

&lt;p&gt;Le 6 novembre 2026, c'est la 16.4.5, publiée le 3 novembre selon le &lt;a href="https://registry.npmjs.org/next/latest" rel="noopener noreferrer"&gt;registre npm&lt;/a&gt;. Vérifiez avec &lt;code&gt;npm view next version&lt;/code&gt;. La branche 15.5 reçoit encore des correctifs de sécurité.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peut-on utiliser Next.js sans Vercel ?
&lt;/h3&gt;

&lt;p&gt;Oui. Selon la &lt;a href="https://nextjs.org/docs/app/getting-started/deploying" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, un serveur Node.js ou un conteneur Docker prend en charge toutes les fonctions. L'export statique et certains adaptateurs en perdent une partie.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse de sources publiques consultées le 6 novembre 2026&amp;nbsp;: documentation et blog de Next.js, avis de sécurité GitHub, documentation de React et de Vercel, registre et statistiques de npm, enquête Stack Overflow 2026. La seule manipulation est le premier projet décrit plus haut&amp;nbsp;: création, build, lancement avec &lt;code&gt;next start&lt;/code&gt; et en mode standalone, appel de l'API et clics dans un navigateur automatisé. Les citations en anglais sont traduites par nos soins. Aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur à Vercel ni aux projets cités.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou une version périmée&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 6 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image d'en-tête&amp;nbsp;: Pankaj Patel (Unsplash License). Capture du projet&amp;nbsp;: NeurauTech.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>frameworkweb</category>
    </item>
    <item>
      <title>Exercices JavaScript corrigés : 20 exercices exécutés, des variables au fetch</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 15:55:23 +0000</pubDate>
      <link>https://dev.to/neurau_tech/exercices-javascript-corriges-20-exercices-executes-des-variables-au-fetch-p36</link>
      <guid>https://dev.to/neurau_tech/exercices-javascript-corriges-20-exercices-executes-des-variables-au-fetch-p36</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Ces 20 exercices JavaScript corrigés vont d'une phrase construite avec un template string à un petit programme en modules qui interroge une API, avec pour chacun un énoncé, un indice, la correction et la sortie réelle. Si vous découvrez le langage, lisez d'abord notre guide &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;Apprendre JavaScript en 2026&lt;/a&gt;, qui couvre l'installation et la théorie&amp;nbsp;: cette page sert à pratiquer.&lt;/p&gt;

&lt;p&gt;Toutes les corrections ont été exécutées le 6 novembre 2026 avec Node.js 22.15.0 et Node.js 26.13.0&amp;nbsp;: chaque sortie affichée est celle du terminal, identique sur les deux versions. Les trois exercices sur le DOM ont été testés automatiquement dans Chromium 120, Chrome 156 et Edge 157, où les 14 premières corrections tournent aussi. Node.js 22.15.0 n'est pas la dernière 22.x (la 22.23.4 est sortie le 20 octobre 2026), mais aucune correction ne dépend d'un correctif récent.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;19 exercices en 5 niveaux plus un projet final&amp;nbsp;: bases, fonctions, tableaux et chaînes, DOM et événements, puis fetch et modules.&lt;/li&gt;
&lt;li&gt;Chaque exercice suit le même format&amp;nbsp;: énoncé, indice, correction, sortie attendue et point à retenir.&lt;/li&gt;
&lt;li&gt;Les sorties viennent d'une exécution réelle sous Node.js 22.15.0 et 26.13.0&amp;nbsp;; Node 26 est la version LTS depuis le 28 octobre 2026.&lt;/li&gt;
&lt;li&gt;Une section reprend les erreurs les plus fréquentes avec le message exact affiché par Node.js ou le navigateur.&lt;/li&gt;
&lt;li&gt;MDN, freeCodeCamp et Exercism se disent gratuits sur leurs pages officielles&amp;nbsp;; Codewars vend un abonnement facultatif, Codewars Red.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Comment utiliser ces exercices JavaScript corrigés
&lt;/h2&gt;

&lt;p&gt;Essayez seul, puis lisez l'indice, et seulement ensuite la correction&amp;nbsp;: une correction lue trop tôt donne l'impression d'avoir compris sans laisser de trace.&lt;/p&gt;

&lt;p&gt;Les exercices 1 à 14 tournent dans Node.js. Enregistrez le code dans un fichier, par exemple &lt;code&gt;exercice01.js&lt;/code&gt;, puis lancez &lt;code&gt;node exercice01.js&lt;/code&gt;. Ils tournent aussi dans un navigateur&amp;nbsp;: chargés comme script d'une page dans Chromium, Chrome et Edge, ils ont donné les mêmes valeurs, sans erreur. Seule la présentation des tableaux et des objets diffère d'une console à l'autre, par exemple dans les outils de développement (F12). Les exercices 15 à 17 sont des pages HTML complètes&amp;nbsp;: ouvrez le fichier dans le navigateur. Si le HTML vous est encore étranger, notre cours &lt;a href="https://neurautech.com/html-css-debutant/" rel="noopener noreferrer"&gt;HTML CSS débutant&lt;/a&gt; pose les bases en une page.&lt;/p&gt;

&lt;p&gt;Les exercices 18 à 20 utilisent &lt;code&gt;fetch&lt;/code&gt;, global dans Node.js depuis la version 18 et stable depuis la version 21 selon la &lt;a href="https://nodejs.org/api/globals.html#fetch" rel="noopener noreferrer"&gt;documentation de Node.js&lt;/a&gt;. Ils utilisent aussi &lt;code&gt;await&lt;/code&gt; hors d'une fonction, ce qui demande un module&amp;nbsp;: gardez l'extension &lt;code&gt;.mjs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quelle version installer&amp;nbsp;? La page des &lt;a href="https://nodejs.org/en/about/previous-releases" rel="noopener noreferrer"&gt;versions de Node.js&lt;/a&gt; affiche la 26.13.0 comme «&amp;nbsp;Latest LTS&amp;nbsp;» le 6 novembre 2026 et précise que les applications en production ne devraient utiliser que des versions LTS actives ou en maintenance (notre traduction). Le calendrier officiel de &lt;a href="https://github.com/nodejs/Release" rel="noopener noreferrer"&gt;nodejs/Release&lt;/a&gt; donne les dates de chaque branche.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flt6ih44pv6nnm8dzh8oc.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flt6ih44pv6nnm8dzh8oc.webp" alt="Frise du calendrier officiel de Node.js&amp;nbsp;: la version 22 est en maintenance jusqu'au 30 avril 2027, la 24 en maintenance depuis le 20 octobre 2026, la 26 en LTS active depuis le 28 octobre 2026&amp;nbsp;; les exercices JavaScript corrigés de cet article ont été exécutés avec la 22 et la 26" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Le tableau de progression
&lt;/h2&gt;

&lt;p&gt;Les exercices vont du plus simple au plus complet. Les temps sont des estimations de l'auteur pour une première tentative, indice compris.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;N°&lt;/th&gt;
&lt;th&gt;Exercice&lt;/th&gt;
&lt;th&gt;Notion travaillée&lt;/th&gt;
&lt;th&gt;Niveau&lt;/th&gt;
&lt;th&gt;Temps indicatif&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Fiche de présentation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, template string, &lt;code&gt;typeof&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Prix TTC&lt;/td&gt;
&lt;td&gt;Conversion de types, &lt;code&gt;toFixed&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Mention d'une note&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else if&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Horaires du jour&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;Date&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;FizzBuzz&lt;/td&gt;
&lt;td&gt;Boucle &lt;code&gt;for&lt;/code&gt;, modulo&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Objectif d'épargne&lt;/td&gt;
&lt;td&gt;Boucle &lt;code&gt;while&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;10&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Convertir des températures&lt;/td&gt;
&lt;td&gt;Fonctions, fonctions fléchées&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Compteur privé&lt;/td&gt;
&lt;td&gt;Fermeture (closure)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Panier d'achat&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Fréquence des mots&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;split&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;Object.entries&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;25&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Profil utilisateur&lt;/td&gt;
&lt;td&gt;Déstructuration, spread&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Palindrome&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;normalize&lt;/code&gt;, expressions régulières&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Créer un slug&lt;/td&gt;
&lt;td&gt;Méthodes de chaînes&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Classement d'une classe&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;localeCompare&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Compteur cliquable&lt;/td&gt;
&lt;td&gt;DOM, &lt;code&gt;addEventListener&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;20&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Liste de tâches&lt;/td&gt;
&lt;td&gt;Création d'éléments, délégation&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Formulaire d'inscription&lt;/td&gt;
&lt;td&gt;Événements &lt;code&gt;input&lt;/code&gt; et &lt;code&gt;submit&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Charger un utilisateur&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;await&lt;/code&gt;, &lt;code&gt;response.ok&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;30&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Module de géométrie&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;export&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;15&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Bilan des tâches&lt;/td&gt;
&lt;td&gt;Projet&amp;nbsp;: modules, fetch, &lt;code&gt;reduce&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Projet&lt;/td&gt;
&lt;td&gt;60&amp;nbsp;min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Niveau 1 : variables, types et conditions
&lt;/h2&gt;

&lt;p&gt;Ce niveau ne demande que des variables, quelques opérations et des conditions. Le guide MDN des &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Template_literals" rel="noopener noreferrer"&gt;littéraux de gabarits&lt;/a&gt;, le nom officiel des template strings, et celui de l'opérateur &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/typeof" rel="noopener noreferrer"&gt;typeof&lt;/a&gt; suffisent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 1 : fiche de présentation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Stockez un prénom, un âge et une ville. Ajoutez un an à l'âge, affichez une phrase de présentation, puis le type de cinq valeurs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;const&lt;/code&gt; pour ce qui ne change pas, &lt;code&gt;let&lt;/code&gt; pour ce qui change. Un template string s'écrit entre accents graves et insère une valeur avec &lt;code&gt;${...}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prenom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Léa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ville&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lyon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// anniversaire : let autorise la réaffectation&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Je m'appelle &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prenom&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, j'ai &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ans et j'habite à &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ville&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;prenom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Je m'appelle Léa, j'ai 25 ans et j'habite à Lyon.
string number boolean undefined object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; &lt;code&gt;typeof null&lt;/code&gt; renvoie &lt;code&gt;"object"&lt;/code&gt;&amp;nbsp;: c'est une bizarrerie historique du langage, pas une erreur de votre code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 2 : calculer un prix TTC
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Un prix arrive sous forme de texte, &lt;code&gt;"19.90"&lt;/code&gt;, comme la valeur d'un champ de formulaire. Calculez le total TTC de 3 articles avec une TVA de 20&amp;nbsp;%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;+&lt;/code&gt; entre un texte et un nombre colle les deux. Convertissez d'abord avec &lt;code&gt;Number()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prixSaisi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;19.90&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ce que renvoie la valeur d'un champ de formulaire&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tauxTva&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prixSaisi&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// piège : + colle deux textes&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prixHt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prixSaisi&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalTtc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prixHt&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;tauxTva&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Total TTC : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;totalTtc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; euros`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;19.903
Total TTC : 71.64 euros
NaN true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; &lt;code&gt;toFixed(2)&lt;/code&gt; renvoie un texte arrondi pour l'affichage. Un texte non numérique donne &lt;code&gt;NaN&lt;/code&gt;, à tester avec &lt;code&gt;Number.isNaN()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 3 : mention d'une note
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Pour une note sur 20, affichez «&amp;nbsp;Très bien&amp;nbsp;» à partir de 16, «&amp;nbsp;Bien&amp;nbsp;» à partir de 14, «&amp;nbsp;Assez bien&amp;nbsp;» à partir de 12, «&amp;nbsp;Admis&amp;nbsp;» à partir de 10, sinon «&amp;nbsp;Non admis&amp;nbsp;». Refusez une note hors de 0 à 20.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Testez d'abord la validité, puis les seuils du plus haut au plus bas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;14.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note invalide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Très bien&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bien&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Assez bien&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Admis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Non admis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bien
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Seule la première branche vraie s'exécute&amp;nbsp;: si vous testez &lt;code&gt;note &amp;gt;= 10&lt;/code&gt; en premier, tout le monde est «&amp;nbsp;Admis&amp;nbsp;».&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 4 : horaires du jour
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Pour le 6 novembre 2026, affichez le jour en toutes lettres et les horaires d'un magasin&amp;nbsp;: fermé le dimanche, 10 h à 13 h le samedi, 9 h à 18 h sinon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;getDay()&lt;/code&gt; renvoie 0 pour dimanche et 6 pour samedi. Attention&amp;nbsp;: dans &lt;code&gt;new Date(année, mois, jour)&lt;/code&gt;, les mois commencent à 0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// les mois commencent à 0 : 10 = novembre&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// 0 = dimanche, 6 = samedi&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;horaires&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;horaires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fermé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;horaires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10 h à 13 h&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;horaires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;9 h à 18 h&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;libelle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleDateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr-FR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;weekday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;libelle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;horaires&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendredi 6 novembre : 9 h à 18 h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Sans &lt;code&gt;break&lt;/code&gt;, l'exécution continue dans le &lt;code&gt;case&lt;/code&gt; suivant. La page MDN de l'objet &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Date" rel="noopener noreferrer"&gt;Date&lt;/a&gt; détaille le piège des mois.&lt;/p&gt;




&lt;h2&gt;
  
  
  Niveau 2 : boucles et fonctions
&lt;/h2&gt;

&lt;p&gt;Ce niveau répète des instructions et les range dans des fonctions. Le guide MDN des &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="noopener noreferrer"&gt;fonctions fléchées&lt;/a&gt; et celui des &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Closures" rel="noopener noreferrer"&gt;fermetures&lt;/a&gt; accompagnent les exercices 7 et 8.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 5 : FizzBuzz
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Pour les nombres de 1 à 15, affichez «&amp;nbsp;Fizz&amp;nbsp;» pour les multiples de 3, «&amp;nbsp;Buzz&amp;nbsp;» pour les multiples de 5, «&amp;nbsp;FizzBuzz&amp;nbsp;» pour les multiples des deux, et le nombre sinon, le tout sur une ligne.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Testez d'abord le cas le plus restrictif. Remplissez un tableau avec &lt;code&gt;push&lt;/code&gt;, puis assemblez-le avec &lt;code&gt;join(" ")&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FizzBuzz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fizz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buzz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Avec &lt;code&gt;i % 3&lt;/code&gt; testé en premier, 15 affiche «&amp;nbsp;Fizz&amp;nbsp;»&amp;nbsp;: la branche FizzBuzz n'est jamais atteinte.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 6 : objectif d'épargne
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; En versant 75 euros par mois, combien de mois faut-il pour atteindre 1&amp;nbsp;000 euros&amp;nbsp;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Le nombre de tours n'est pas connu à l'avance&amp;nbsp;: c'est le cas d'usage de &lt;code&gt;while&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectif&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;versementMensuel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;solde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mois&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;solde&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;objectif&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;solde&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;versementMensuel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;mois&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mois&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; mois pour atteindre &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objectif&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; euros (solde : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;solde&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; euros)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;14 mois pour atteindre 1000 euros (solde : 1050 euros)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Une boucle &lt;code&gt;while&lt;/code&gt; doit modifier sa condition à chaque tour. Avec un versement de 0, celle-ci ne s'arrêterait jamais&amp;nbsp;: ajoutez un garde-fou.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 7 : convertir des températures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Écrivez une fonction classique qui convertit des degrés Celsius en Fahrenheit, une fonction fléchée pour l'inverse, et une fonction &lt;code&gt;arrondir&lt;/code&gt; avec une décimale par défaut.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; F = C x 9 / 5 + 32. Un paramètre par défaut s'écrit &lt;code&gt;decimales = 1&lt;/code&gt;. Une fonction se passe à &lt;code&gt;map&lt;/code&gt; sans parenthèses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;celsiusVersFahrenheit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;celsius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;celsius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fahrenheitVersCelsius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrondir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decimales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;decimales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;decimales&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;celsiusVersFahrenheit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;arrondir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fahrenheitVersCelsius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;98.6&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;arrondir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;celsiusVersFahrenheit&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;212
37
3.142
[ 32, 68, 98.6 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Une fonction fléchée sur une ligne renvoie sa valeur sans &lt;code&gt;return&lt;/code&gt;. Avec des accolades, le &lt;code&gt;return&lt;/code&gt; redevient obligatoire.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 8 : un compteur privé
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Écrivez &lt;code&gt;creerCompteur(depart)&lt;/code&gt; qui renvoie un objet avec &lt;code&gt;incrementer&lt;/code&gt;, &lt;code&gt;decrementer&lt;/code&gt; et &lt;code&gt;reinitialiser&lt;/code&gt;. La valeur ne doit pas être accessible directement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Une fonction définie dans une autre garde l'accès aux variables de celle-ci, même après son retour&amp;nbsp;: c'est une fermeture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;creerCompteur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;valeur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;depart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// invisible depuis l'extérieur&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;incrementer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;valeur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;decrementer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;valeur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;reinitialiser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valeur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;depart&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visites&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;creerCompteur&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;creerCompteur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;visites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;incrementer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;visites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;incrementer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrementer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;incrementer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrementer&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reinitialiser&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valeur&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3 8
0 undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Chaque appel à &lt;code&gt;creerCompteur&lt;/code&gt; crée sa propre variable &lt;code&gt;valeur&lt;/code&gt;. &lt;code&gt;stock.valeur&lt;/code&gt; vaut &lt;code&gt;undefined&lt;/code&gt;&amp;nbsp;: la donnée est bien protégée. L'exercice 15 reprend cette logique dans une page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Niveau 3 : tableaux, objets et chaînes
&lt;/h2&gt;

&lt;p&gt;Ce niveau traite des séries de données. La page MDN de &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" rel="noopener noreferrer"&gt;reduce&lt;/a&gt; et celle de l'&lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/Destructuring" rel="noopener noreferrer"&gt;affectation par décomposition&lt;/a&gt;, le nom français de la déstructuration, sont les deux références utiles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 9 : le panier d'achat
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; À partir d'un panier, gardez les articles en stock, affichez une ligne par article avec son sous-total, puis le total.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;filter&lt;/code&gt; garde, &lt;code&gt;map&lt;/code&gt; transforme, &lt;code&gt;reduce&lt;/code&gt; cumule. Donnez toujours une valeur de départ à &lt;code&gt;reduce&lt;/code&gt;, ici &lt;code&gt;0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;panier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clavier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;49.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;enStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Souris&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;19.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;enStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Écran&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;189&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;enStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Câble USB-C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;9.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;enStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;disponibles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;panier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enStock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lignes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;disponibles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prix&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; euros`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;disponibles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;somme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;somme&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prix&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lignes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Total : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; euros`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clavier x1 : 49.90 euros
Souris x2 : 39.00 euros
Câble USB-C x3 : 29.97 euros
Total : 118.87 euros
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Sans valeur de départ, &lt;code&gt;reduce&lt;/code&gt; sur un tableau vide lève &lt;code&gt;TypeError: Reduce of empty array with no initial value&lt;/code&gt;. Pour de vrais montants, calculez en centimes entiers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 10 : fréquence des mots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Comptez les mots d'une phrase sans tenir compte de la ponctuation ni des majuscules, puis affichez les trois plus fréquents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;split&lt;/code&gt; accepte une expression régulière. &lt;code&gt;compteur[mot] ?? 0&lt;/code&gt; vaut 0 quand le mot est absent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Le code court, le code clair. Un code clair se relit, un code court se teste.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mots&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;texte&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^\p&lt;/span&gt;&lt;span class="sr"&gt;{L}&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+/u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;mot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frequences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mots&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mot&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mot&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;top3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frequences&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mots&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mots&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;top3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;16 mots
[ [ 'code', 4 ], [ 'le', 2 ], [ 'court', 2 ] ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; &lt;code&gt;\p{L}&lt;/code&gt; désigne toute lettre Unicode, accents et ligatures compris&amp;nbsp;: avec &lt;code&gt;[^a-zà-ÿ]&lt;/code&gt;, «&amp;nbsp;cœur&amp;nbsp;» serait coupé en &lt;code&gt;c&lt;/code&gt; et &lt;code&gt;ur&lt;/code&gt;, un résultat vérifié dans Node.js. Cinq mots sont à égalité à 2. La page MDN de &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/sort" rel="noopener noreferrer"&gt;sort&lt;/a&gt; indique que la spécification impose un tri stable depuis ECMAScript 2019&amp;nbsp;: l'ordre d'apparition est conservé.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 11 : profil utilisateur
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Extrayez le nom, l'e-mail, la ville et un rôle par défaut d'un objet. Prenez le premier et le troisième élément d'un tableau, créez une copie promue administrateur, puis échangez deux variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; La déstructuration accepte des valeurs par défaut (&lt;code&gt;role = "lecteur"&lt;/code&gt;) et des objets imbriqués. &lt;code&gt;{ ...objet }&lt;/code&gt; copie les propriétés.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;utilisateur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Inès&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ines@exemple.fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;adresse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ville&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nantes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lecteur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;adresse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ville&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;utilisateur&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ville&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;premier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;troisieme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aucun&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HTML&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CSS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;premier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;troisieme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;utilisateur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;utilisateur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inès ines@exemple.fr lecteur Nantes
HTML aucun
undefined admin
2 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; L'objet d'origine n'est pas modifié. Mais la copie par spread est superficielle&amp;nbsp;: &lt;code&gt;promu.adresse&lt;/code&gt; et &lt;code&gt;utilisateur.adresse&lt;/code&gt; restent le même objet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 12 : palindrome avec accents
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Écrivez &lt;code&gt;estPalindrome(phrase)&lt;/code&gt; qui ignore la casse, les espaces, la ponctuation et les accents. Testez trois phrases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;normalize("NFD")&lt;/code&gt; sépare la lettre de son accent, que l'on retire ensuite avec une expression régulière. Une chaîne n'a pas de &lt;code&gt;reverse&lt;/code&gt;&amp;nbsp;: passez par un tableau.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;estPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;propre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;phrase&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NFD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;// "é" devient "e" + accent séparé&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\u&lt;/span&gt;&lt;span class="sr"&gt;0300-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;036f&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// on retire les accents&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// puis espaces et ponctuation&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;propre&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;propre&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;phrase&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ésope reste ici et se repose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Engage le jeu que je le gagne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;estPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ésope reste ici et se repose -&amp;gt; true
Engage le jeu que je le gagne -&amp;gt; true
JavaScript -&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Sans &lt;code&gt;normalize&lt;/code&gt;, le «&amp;nbsp;é&amp;nbsp;» d'«&amp;nbsp;Ésope&amp;nbsp;» est supprimé par &lt;code&gt;[^a-z0-9]&lt;/code&gt; avec la ponctuation&amp;nbsp;: il reste &lt;code&gt;soperesteicietserepose&lt;/code&gt;, qui n'est plus un palindrome, et le test renvoie &lt;code&gt;false&lt;/code&gt;. La page MDN de &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/String/normalize" rel="noopener noreferrer"&gt;normalize&lt;/a&gt; explique les formes NFC et NFD.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 13 : créer un slug
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Transformez un titre en slug d'URL&amp;nbsp;: minuscules, sans accents, mots séparés par des tirets, sans tiret au début ni à la fin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Même départ que l'exercice 12, puis remplacez chaque suite de caractères non alphanumériques par un tiret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slugifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;titre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;titre&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NFD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\u&lt;/span&gt;&lt;span class="sr"&gt;0300-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;036f&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^-+|-+$/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;slugifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Exercices JavaScript corrigés : 20 énoncés !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;slugifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  Ça marche, même avec des œufs ?  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;corrigés&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;corrigés&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NFD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exercices-javascript-corriges-20-enonces
ca-marche-meme-avec-des-ufs
8 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Deux surprises, toutes deux réelles&amp;nbsp;: «&amp;nbsp;œufs&amp;nbsp;» devient «&amp;nbsp;ufs&amp;nbsp;», car «&amp;nbsp;œ&amp;nbsp;» est une ligature et non une lettre accentuée, et &lt;code&gt;length&lt;/code&gt; compte 9 après NFD. Traitez «&amp;nbsp;œ&amp;nbsp;» et «&amp;nbsp;æ&amp;nbsp;» à part avec un &lt;code&gt;replace&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 14 : classement d'une classe
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Triez d'abord &lt;code&gt;[10, 9, 1, 100]&lt;/code&gt; sans puis avec fonction de comparaison. Calculez ensuite la moyenne de chaque élève et affichez le classement, les ex aequo par ordre alphabétique.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Sans fonction de comparaison, &lt;code&gt;sort&lt;/code&gt; compare des textes. &lt;code&gt;localeCompare&lt;/code&gt; trie correctement les prénoms accentués.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Omar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Élodie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Zoé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bastien&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculerMoyenne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;classe&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;moyenne&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calculerMoyenne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moyenne&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moyenne&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;moyenne&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;classement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;nom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;moyenne&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ 1, 10, 100, 9 ]
[ 1, 9, 10, 100 ]
Bastien  16.00
Élodie   16.00
Omar     12.00
Zoé      12.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; MDN le confirme&amp;nbsp;: par défaut, &lt;code&gt;sort&lt;/code&gt; convertit les éléments en chaînes, d'où &lt;code&gt;100&lt;/code&gt; avant &lt;code&gt;9&lt;/code&gt;. Et &lt;code&gt;sort&lt;/code&gt; modifie le tableau d'origine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Niveau 4 : le DOM et les événements
&lt;/h2&gt;

&lt;p&gt;Ces trois exercices sont des pages HTML complètes&amp;nbsp;: enregistrez-les en &lt;code&gt;.html&lt;/code&gt; et ouvrez-les dans le navigateur. Le script est placé en fin de &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, après les éléments qu'il manipule. La page MDN d'&lt;a href="https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener" rel="noopener noreferrer"&gt;addEventListener&lt;/a&gt; décrit les événements utilisés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comment nous les avons testés.&lt;/strong&gt; Un script Playwright 1.40 a cliqué, saisi et soumis chaque page dans Chromium 120, Chrome 156 et Edge 157, puis relu son contenu&amp;nbsp;: résultats identiques dans les trois, sans erreur JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 15 : un compteur cliquable
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Affichez une valeur et trois boutons&amp;nbsp;: +1, -1 et remise à zéro. Une valeur négative s'affiche en rouge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Récupérez les éléments avec &lt;code&gt;document.querySelector&lt;/code&gt;, puis réagissez au clic avec &lt;code&gt;addEventListener("click", ...)&lt;/code&gt;. Modifiez le texte avec &lt;code&gt;textContent&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Compteur&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Valeur : &lt;span class="nt"&gt;&amp;lt;output&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"valeur"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/output&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"moins"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;-1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"plus"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"zero"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Remettre à zéro&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;affichage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#valeur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;compteur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;affichage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;affichage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compteur&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crimson&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#plus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#moins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;compteur&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#zero&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;compteur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Résultat vérifié&amp;nbsp;:&lt;/strong&gt; après 3 clics sur +1, la page affiche 3&amp;nbsp;; après 5 clics sur -1, elle affiche -2 en rouge (&lt;code&gt;rgb(220, 20, 60)&lt;/code&gt;)&amp;nbsp;; le bouton de remise à zéro affiche 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Une seule fonction &lt;code&gt;afficher&lt;/code&gt; met la page à jour, ce qui garde l'état et l'affichage synchronisés.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 16 : une liste de tâches
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Un formulaire ajoute une tâche à une liste. Chaque tâche a un bouton «&amp;nbsp;Fait&amp;nbsp;», qui la barre, et un bouton «&amp;nbsp;Supprimer&amp;nbsp;». Un texte indique le nombre de tâches restantes. Une saisie vide ou faite d'espaces est ignorée.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Bloquez le rechargement avec &lt;code&gt;preventDefault()&lt;/code&gt;. Créez les éléments avec &lt;code&gt;createElement&lt;/code&gt; et posez un seul écouteur sur la liste&amp;nbsp;: c'est la délégation d'événements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Liste de tâches&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;.faite&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;line-through&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"formulaire"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"nouvelle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nouvelle tâche&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nouvelle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Ajouter&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"liste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"reste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0 tâche restante&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formulaire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#formulaire&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;champ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#nouvelle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;liste&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#liste&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reste&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#reste&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mettreAJourCompteur&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;liste&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li:not(.faite)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;reste&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; tâche&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; restante&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;formulaire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;              &lt;span class="c1"&gt;// pas de rechargement de la page&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;titre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;titre&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;texte&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;titre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;               &lt;span class="c1"&gt;// textContent, jamais innerHTML&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;boutonFait&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;boutonFait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fait&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;boutonFait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;basculer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;boutonSuppr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;boutonSuppr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Supprimer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;boutonSuppr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;supprimer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;texte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;boutonFait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;boutonSuppr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;liste&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;mettreAJourCompteur&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Un seul écouteur pour tous les boutons, même ceux créés plus tard&lt;/span&gt;
    &lt;span class="nx"&gt;liste&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bouton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;bouton&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bouton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bouton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;basculer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;faite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bouton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;supprimer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;mettreAJourCompteur&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Résultat vérifié&amp;nbsp;:&lt;/strong&gt; trois tâches ajoutées avec la touche Entrée affichent «&amp;nbsp;3 tâches restantes&amp;nbsp;», puis «&amp;nbsp;2 tâches restantes&amp;nbsp;» après un clic sur «&amp;nbsp;Fait&amp;nbsp;» (texte barré), puis «&amp;nbsp;1 tâche restante&amp;nbsp;» après une suppression. Une saisie vide ou de trois espaces n'ajoute rien, sans bulle d'erreur du navigateur, et l'URL ne change pas. La tâche &lt;code&gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&lt;/code&gt; s'affiche comme du texte&amp;nbsp;: aucune image n'est créée.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Le champ n'a pas l'attribut &lt;code&gt;required&lt;/code&gt;&amp;nbsp;: avec lui, le navigateur afficherait sa propre bulle sur un envoi vide, alors qu'ici le test &lt;code&gt;titre === ""&lt;/code&gt; suffit. &lt;code&gt;textContent&lt;/code&gt; affiche le texte tel quel&amp;nbsp;; &lt;code&gt;innerHTML&lt;/code&gt; l'interpréterait comme du HTML, une porte ouverte à l'injection de code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 17 : valider un formulaire
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Un formulaire d'inscription demande un e-mail, un mot de passe de 8&amp;nbsp;caractères minimum et une confirmation. Affichez un message sous chaque champ pendant la saisie, et vérifiez tout à l'envoi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; L'attribut &lt;code&gt;novalidate&lt;/code&gt; désactive les bulles du navigateur pour afficher vos propres messages. Un objet de règles, une fonction par champ, évite de répéter le code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Inscription&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;.erreur&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crimson&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;aria-invalid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crimson&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"inscription"&lt;/span&gt; &lt;span class="na"&gt;novalidate&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;E-mail&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"email-erreur"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"erreur"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email-erreur"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"mdp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Mot de passe (8 caractères minimum)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mdp"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"mdp-erreur"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"erreur"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mdp-erreur"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"confirmation"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Confirmation&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"confirmation"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"confirmation-erreur"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"erreur"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"confirmation-erreur"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Créer le compte&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"resultat"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+@&lt;/span&gt;&lt;span class="se"&gt;[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Adresse e-mail invalide.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;mdp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Encore &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; caractère(s).`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;confirmation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Confirmez le mot de passe.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#mdp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Les mots de passe ne correspondent pas.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;champ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`#&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// On nettoie l'e-mail, jamais un mot de passe : une espace y compte&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valeur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;valeur&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`#&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-erreur`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;champ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aria-invalid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formulaire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#inscription&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirmation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#confirmation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Vérification en direct pendant la saisie&lt;/span&gt;
    &lt;span class="nx"&gt;formulaire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Changer le mot de passe peut rendre la confirmation juste ou fausse&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mdp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;confirmation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;formulaire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;evenement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regles&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// tout vérifier, pas seulement le premier&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resultats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#resultat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;valide&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Compte prêt à être envoyé au serveur.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Corrigez les champs en rouge.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Résultat vérifié&amp;nbsp;:&lt;/strong&gt; un envoi à vide affiche «&amp;nbsp;Adresse e-mail invalide.&amp;nbsp;», «&amp;nbsp;Encore 8 caractère(s).&amp;nbsp;», «&amp;nbsp;Confirmez le mot de passe.&amp;nbsp;» et «&amp;nbsp;Corrigez les champs en rouge.&amp;nbsp;». La saisie de &lt;code&gt;lea@exemple&lt;/code&gt; et &lt;code&gt;secret&lt;/code&gt; affiche «&amp;nbsp;Encore 2 caractère(s).&amp;nbsp;». Deux mots de passe différents affichent «&amp;nbsp;Les mots de passe ne correspondent pas.&amp;nbsp;», et ce message revient si l'on modifie le mot de passe après la confirmation. Avec des valeurs correctes, y compris un mot de passe entouré d'espaces saisi deux fois à l'identique, les messages disparaissent et la page affiche «&amp;nbsp;Compte prêt à être envoyé au serveur.&amp;nbsp;». Chaque champ est relié à son message par &lt;code&gt;aria-describedby&lt;/code&gt;, que lisent les lecteurs d'écran.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; La validation dans le navigateur aide l'utilisateur mais ne protège rien&amp;nbsp;: le serveur doit refaire tous les contrôles. Ne nettoyez jamais un mot de passe avec &lt;code&gt;trim()&lt;/code&gt;&amp;nbsp;: une espace en fait partie. La règle de confirmation traite d'abord le champ vide, avec son propre message, sinon deux champs vides seraient jugés égaux.&lt;/p&gt;




&lt;h2&gt;
  
  
  Niveau 5 : fetch, async/await et modules
&lt;/h2&gt;

&lt;p&gt;Ce niveau sort du fichier unique&amp;nbsp;: il interroge une API et découpe le code. Si le vocabulaire des API vous manque, notre article &lt;a href="https://neurautech.com/api-c-est-quoi/" rel="noopener noreferrer"&gt;API, c'est quoi&amp;nbsp;?&lt;/a&gt; explique requêtes, statuts et JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 18 : charger un utilisateur avec fetch
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Avec l'API gratuite &lt;a href="https://jsonplaceholder.typicode.com/" rel="noopener noreferrer"&gt;JSONPlaceholder&lt;/a&gt;, qui se présente comme «&amp;nbsp;free fake REST API&amp;nbsp;» sans inscription, chargez les utilisateurs 1 et 999 et affichez nom, e-mail et ville. Gérez l'erreur HTTP et l'erreur réseau.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;fetch&lt;/code&gt; ne rejette pas sa promesse sur une réponse 404. Le guide MDN &lt;a href="https://developer.mozilla.org/fr/docs/Web/API/Fetch_API/Using_Fetch" rel="noopener noreferrer"&gt;Utiliser l'API Fetch&lt;/a&gt; le dit&amp;nbsp;: il faut vérifier le statut avant de lire le corps. Testez &lt;code&gt;response.ok&lt;/code&gt; et levez une erreur vous-même.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// exercice18.mjs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;chargerUtilisateur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// fetch ne rejette pas sur une erreur HTTP : à nous de vérifier&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; pour l'utilisateur &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;chargerUtilisateur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Erreur : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;afficher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.exemple.invalid/users/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// domaine qui n'existe pas&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Leanne Graham &amp;lt;Sincere@april.biz&amp;gt;, Gwenborough
Erreur : HTTP 404 pour l'utilisateur 999
TypeError : fetch failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Une 404 arrive avec &lt;code&gt;ok&lt;/code&gt; à &lt;code&gt;false&lt;/code&gt;&amp;nbsp;; seule une panne réseau rejette la promesse. Dans les trois navigateurs testés, la même requête donne 200 et &lt;code&gt;ok&lt;/code&gt; à &lt;code&gt;true&lt;/code&gt; pour l'utilisateur 1, 404 et &lt;code&gt;false&lt;/code&gt; pour le 999, mais le message réseau diffère&amp;nbsp;: &lt;code&gt;TypeError: Failed to fetch&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 19 : un module de géométrie
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; Créez &lt;code&gt;geometrie.mjs&lt;/code&gt; qui exporte une constante, une fonction nommée et une fonction par défaut. Importez-les dans &lt;code&gt;main.mjs&lt;/code&gt; de deux façons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; Un seul &lt;code&gt;export default&lt;/code&gt; par module, importé sans accolades&amp;nbsp;; les exports nommés s'importent entre accolades. &lt;code&gt;import * as&lt;/code&gt; regroupe tout dans un objet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// geometrie.mjs&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PI_ARRONDI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;aireRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;largeur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hauteur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;largeur&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;hauteur&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;aireCercle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rayon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;rayon&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.mjs&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;aireCercle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;aireRectangle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PI_ARRONDI&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./geometrie.mjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;geo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./geometrie.mjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;aireRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;aireCercle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PI_ARRONDI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;geo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue de &lt;code&gt;node main.mjs&lt;/code&gt;&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10
12.57
3.14 [ 'PI_ARRONDI', 'aireRectangle', 'default' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; Importer un nom qui n'existe pas arrête tout avant la première ligne&amp;nbsp;: &lt;code&gt;SyntaxError: The requested module './geometrie.mjs' does not provide an export named 'perimetre'&lt;/code&gt;. Dans le navigateur, le guide MDN des &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Modules" rel="noopener noreferrer"&gt;modules&lt;/a&gt; prévient qu'une page ouverte en &lt;code&gt;file://&lt;/code&gt; provoque des erreurs CORS&amp;nbsp;: servez-la avec un serveur local.&lt;/p&gt;




&lt;h2&gt;
  
  
  Projet final : le bilan des tâches
&lt;/h2&gt;

&lt;p&gt;Le dernier exercice réunit modules, fetch, déstructuration et &lt;code&gt;reduce&lt;/code&gt; dans un programme en trois fichiers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 20 : bilan des tâches en ligne de commande
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Énoncé.&lt;/strong&gt; JSONPlaceholder expose 200 tâches (&lt;code&gt;/todos&lt;/code&gt;) et 10 utilisateurs (&lt;code&gt;/users&lt;/code&gt;). Chargez les deux en parallèle, affichez le taux global de tâches terminées, puis le podium des trois utilisateurs les plus avancés. Une erreur doit afficher un message clair et un code de sortie non nul.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indice.&lt;/strong&gt; &lt;code&gt;Promise.all&lt;/code&gt; lance les deux requêtes en même temps. &lt;code&gt;??=&lt;/code&gt; initialise une entrée seulement si elle n'existe pas. Une &lt;code&gt;Map&lt;/code&gt; relie l'identifiant au nom.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api.mjs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;chargerJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chemin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;chemin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sur &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chemin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// stats.mjs&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bilanParUtilisateur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bilan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;faites&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;faites&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bilan&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faites&lt;/span&gt; &lt;span class="p"&gt;}])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;faites&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;taux&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;faites&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.mjs&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;chargerJson&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./api.mjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bilanParUtilisateur&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./stats.mjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;utilisateurs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;chargerJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;chargerJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;utilisateurs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;faites&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; tâches, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;faites&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; terminées (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;faites&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; %)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;podium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bilanParUtilisateur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taux&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taux&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;podium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faites&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taux&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;noms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;faites&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;taux&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; %)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Impossible de produire le bilan :&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;erreur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sortie attendue de &lt;code&gt;node main.mjs&lt;/code&gt;&amp;nbsp;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;200 tâches, 90 terminées (45 %)
1. Chelsey Dietrich : 12/20 (60 %)
2. Clementina DuBuque : 12/20 (60 %)
3. Leanne Graham : 11/20 (55 %)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;À retenir.&lt;/strong&gt; &lt;code&gt;stats.mjs&lt;/code&gt; ne fait aucun appel réseau&amp;nbsp;: il se teste avec un tableau écrit à la main. Pour aller plus loin, affichez le bilan dans une page HTML en réutilisant l'exercice 16, puis versionnez le projet en suivant notre guide &lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub pour débutant&lt;/a&gt;. Le typage de &lt;a href="https://neurautech.com/apprendre-typescript/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; aurait signalé une faute de frappe sur &lt;code&gt;completed&lt;/code&gt; avant l'exécution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les erreurs du débutant et leurs vrais messages
&lt;/h2&gt;

&lt;p&gt;Ces messages ont été produits le 6 novembre 2026 par Node.js 22.15.0 et 26.13.0, à l'identique, sauf la dernière ligne, obtenue dans Chromium, Chrome et Edge&amp;nbsp;: le navigateur signale l'exception comme «&amp;nbsp;Uncaught&amp;nbsp;», c'est-à-dire non interceptée, d'où ce préfixe dans la console. Lisez d'abord la dernière ligne d'une erreur&amp;nbsp;: elle donne le type et la cause.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code fautif&lt;/th&gt;
&lt;th&gt;Message exact&lt;/th&gt;
&lt;th&gt;Correction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;utilisateur.adresse.ville&lt;/code&gt; sans adresse&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TypeError: Cannot read properties of undefined (reading 'ville')&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;utilisateur.adresse?.ville&lt;/code&gt; renvoie &lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;const taux = 0.2; taux = 0.055;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TypeError: Assignment to constant variable.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;let&lt;/code&gt; si la valeur doit changer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;console.log(prix); let prix = 10;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ReferenceError: Cannot access 'prix' before initialization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Déclarer avant d'utiliser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;notes.map(...)&lt;/code&gt; sur un objet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TypeError: notes.map is not a function&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Object.values(notes).map(...)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;await&lt;/code&gt; dans une fonction sans &lt;code&gt;async&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SyntaxError: await is only valid in async functions and the top level bodies of modules&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ajouter &lt;code&gt;async&lt;/code&gt; devant &lt;code&gt;function&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;reponse.json()&lt;/code&gt; sans &lt;code&gt;await&lt;/code&gt; avant &lt;code&gt;fetch&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TypeError: reponse.json is not a function&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const reponse = await fetch(url)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Script dans &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; qui cherche un bouton&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Script en fin de &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; ou attribut &lt;code&gt;defer&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;L'oubli de &lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; est le plus sournois, car rien ne plante tout de suite. &lt;code&gt;console.log(reponse)&lt;/code&gt; affiche &lt;code&gt;Promise { &amp;lt;pending&amp;gt; }&lt;/code&gt; et &lt;code&gt;reponse.ok&lt;/code&gt; vaut &lt;code&gt;undefined&lt;/code&gt;&amp;nbsp;: l'erreur n'apparaît qu'à la ligne suivante.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;==&lt;/code&gt; contre &lt;code&gt;===&lt;/code&gt;.&lt;/strong&gt; Le double égal convertit les types avant de comparer, comme le rappelle la page MDN de l'&lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/Strict_equality" rel="noopener noreferrer"&gt;égalité stricte&lt;/a&gt;. Exécuté dans Node.js&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true true true true
false false false false true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilisez &lt;code&gt;===&lt;/code&gt; partout. &lt;code&gt;NaN&lt;/code&gt; n'est égal à rien, pas même à lui-même&amp;nbsp;: testez-le avec &lt;code&gt;Number.isNaN()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les nombres à virgule.&lt;/strong&gt; &lt;code&gt;0.1 + 0.2&lt;/code&gt; affiche &lt;code&gt;0.30000000000000004&lt;/code&gt; et &lt;code&gt;0.1 + 0.2 === 0.3&lt;/code&gt; vaut &lt;code&gt;false&lt;/code&gt;. Les opérateurs se comportent aussi différemment avec du texte&amp;nbsp;: &lt;code&gt;"5" * 2&lt;/code&gt; donne &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;"5" + 2&lt;/code&gt; donne &lt;code&gt;"52"&lt;/code&gt; et &lt;code&gt;"5" - 2&lt;/code&gt; donne &lt;code&gt;3&lt;/code&gt;. Notre guide &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;Apprendre JavaScript&lt;/a&gt; revient sur &lt;code&gt;var&lt;/code&gt; et sur &lt;code&gt;this&lt;/code&gt;, deux autres pièges classiques.&lt;/p&gt;




&lt;h2&gt;
  
  
  Où s'entraîner en ligne gratuitement
&lt;/h2&gt;

&lt;p&gt;Après ces 20 exercices, quatre plateformes prennent le relais. Nous avons vérifié leurs conditions le 6 novembre 2026, sans créer de compte.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plateforme&lt;/th&gt;
&lt;th&gt;Langue&lt;/th&gt;
&lt;th&gt;Gratuit&amp;nbsp;?&lt;/th&gt;
&lt;th&gt;Ce qu'on y trouve&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MDN Web Docs&lt;/td&gt;
&lt;td&gt;Français&lt;/td&gt;
&lt;td&gt;Oui, sans compte&lt;/td&gt;
&lt;td&gt;Cours «&amp;nbsp;Script dynamique avec JavaScript&amp;nbsp;» et pages «&amp;nbsp;Testez vos compétences&amp;nbsp;»&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;freeCodeCamp&lt;/td&gt;
&lt;td&gt;Anglais&lt;/td&gt;
&lt;td&gt;Oui, tout le contenu&lt;/td&gt;
&lt;td&gt;Cours, projets et certifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exercism, piste JavaScript&lt;/td&gt;
&lt;td&gt;Anglais&lt;/td&gt;
&lt;td&gt;Oui, mentorat compris&lt;/td&gt;
&lt;td&gt;159 exercices regroupés en 37 concepts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codewars&lt;/td&gt;
&lt;td&gt;Anglais&lt;/td&gt;
&lt;td&gt;Compte de base sans prix affiché&amp;nbsp;; abonnement Red payant et facultatif&lt;/td&gt;
&lt;td&gt;Kata (petits exercices) rédigés par la communauté&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MDN.&lt;/strong&gt; Le module &lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core/Scripting" rel="noopener noreferrer"&gt;Script dynamique avec JavaScript&lt;/a&gt;, traduit en français et publié sous licence Creative Commons, propose une page de test par notion, par exemple &lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core/Scripting/Test_your_skills/Arrays" rel="noopener noreferrer"&gt;les tableaux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;freeCodeCamp.&lt;/strong&gt; Sa &lt;a href="https://www.freecodecamp.org/news/about/" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt; l'affirme&amp;nbsp;: «&amp;nbsp;Every aspect of freeCodeCamp is 100% free&amp;nbsp;», cours, projets et certifications compris. L'organisation se présente comme une association américaine de type 501(c)(3).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exercism.&lt;/strong&gt; La page de la &lt;a href="https://exercism.org/tracks/javascript" rel="noopener noreferrer"&gt;piste JavaScript&lt;/a&gt; annonce 159 exercices et 37 concepts, «&amp;nbsp;100% free for everyone&amp;nbsp;», avec un mentorat assuré par des bénévoles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codewars.&lt;/strong&gt; Le site propose de petits exercices appelés «&amp;nbsp;kata&amp;nbsp;». Sa &lt;a href="https://docs.codewars.com/getting-started/registering/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; décrit une inscription par e-mail ou compte GitHub sans mentionner de paiement, mais aucune page officielle lue ne dit en toutes lettres que l'entraînement est gratuit. La page &lt;a href="https://www.codewars.com/subscription" rel="noopener noreferrer"&gt;Codewars Red&lt;/a&gt; vend un abonnement à 5 dollars par mois, 24 dollars par semestre ou 40 dollars par an, pour des statistiques détaillées, l'absence de publicité, un badge et l'accès aux fonctions en bêta.&lt;/p&gt;

&lt;p&gt;Pratiquer JavaScript reste un bon investissement. Dans l'enquête Stack Overflow 2026, JavaScript est le langage le plus utilisé&amp;nbsp;: 62,0&amp;nbsp;% des 14&amp;nbsp;099 personnes qui ont répondu à cette question disent l'avoir utilisé (&lt;a href="https://survey.stackoverflow.co/2026/technology" rel="noopener noreferrer"&gt;Stack Overflow Developer Survey 2026&lt;/a&gt;, consulté le 6 novembre 2026). La page parle d'une première place «&amp;nbsp;for the 12th year in a row&amp;nbsp;», mais l'édition 2023 évoquait déjà une onzième année&amp;nbsp;: nous ne reprenons pas ce décompte.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyru1onzgwqp1c8hvgeya.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyru1onzgwqp1c8hvgeya.webp" alt="Graphique en barres&amp;nbsp;: langages les plus utilisés selon l'enquête Stack Overflow 2026, JavaScript en tête avec 62,0&amp;nbsp;%, devant SQL, HTML/CSS et Python, sur 14&amp;nbsp;099 répondants à la question" width="799" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Une fois ces bases acquises, un framework devient accessible&amp;nbsp;: notre comparatif &lt;a href="https://neurautech.com/react-vs-vue/" rel="noopener noreferrer"&gt;React vs Vue&lt;/a&gt; aide à choisir. Et si vous venez d'un autre langage, nos &lt;a href="https://neurautech.com/exercices-python-debutant-corriges/" rel="noopener noreferrer"&gt;exercices Python débutant&lt;/a&gt; suivent le même format.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Les points suivants restent ouverts&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Firefox et Safari.&lt;/strong&gt; Les pages DOM ont été testées dans des navigateurs à moteur Chromium seulement&amp;nbsp;: Chromium 120 fourni avec Playwright 1.40, une version ancienne, Chrome 156.0.8078.73 et Edge 157.0.4341.42. Ces deux dernières sont des versions du canal stable, mais Chrome 158, diffusé depuis le 4 novembre 2026, n'était pas encore installé sur le poste de test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le décompte de Stack Overflow.&lt;/strong&gt; L'édition 2026 écrit que JavaScript est premier «&amp;nbsp;for the 12th year in a row&amp;nbsp;»&amp;nbsp;; celle de 2023 parlait déjà d'«&amp;nbsp;eleventh year in a row&amp;nbsp;». Le pourcentage de 62,0&amp;nbsp;% n'est pas en cause.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les autres versions de Node.js.&lt;/strong&gt; Seules les versions 22.15.0 et 26.13.0 ont été utilisées. Node 24 n'a pas été testé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les données de JSONPlaceholder.&lt;/strong&gt; Ce sont de fausses données fixes&amp;nbsp;; si le service les modifie, les sorties des exercices 18 et 20 changeront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le programme de freeCodeCamp et l'offre gratuite de Codewars.&lt;/strong&gt; Les pages de cours de freeCodeCamp se chargent en JavaScript et n'ont pas été lues en détail. La page d'abonnement de Codewars ne décrit pas le compte gratuit&amp;nbsp;; nous n'avons pas créé de compte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les temps indicatifs.&lt;/strong&gt; Ce sont des estimations de l'auteur, pas des mesures.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Existe-t-il une version PDF de ces exercices JavaScript corrigés ?
&lt;/h3&gt;

&lt;p&gt;Pas de PDF à télécharger. Pour une version papier, imprimez la page depuis le navigateur (Ctrl+P, «&amp;nbsp;Enregistrer au format PDF&amp;nbsp;»). Mais un exercice se fait en exécutant du code&amp;nbsp;: gardez un fichier par exercice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faut-il Node.js ou un navigateur pour faire ces exercices ?
&lt;/h3&gt;

&lt;p&gt;Les deux sont gratuits. Les exercices 1 à 14 marchent dans Node.js et aussi dans le navigateur, chargés dans une page ou collés dans la console (F12)&amp;nbsp;; nous les avons testés chargés dans une page. Les exercices 15 à 17 demandent un navigateur&amp;nbsp;; les exercices 18 à 20 ont été écrits pour Node.js 22 ou plus récent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combien de temps faut-il pour faire les 20 exercices ?
&lt;/h3&gt;

&lt;p&gt;Le total de nos estimations est d'environ sept heures, projet compris. Étalez ces exercices sur deux à trois semaines, un ou deux par jour, et refaites trois jours plus tard ceux qui vous ont posé problème.&lt;/p&gt;

&lt;h3&gt;
  
  
  Que faire après ces exercices ?
&lt;/h3&gt;

&lt;p&gt;Construisez un petit projet personnel et publiez-le sur GitHub. Ensuite, deux suites logiques&amp;nbsp;: &lt;a href="https://neurautech.com/apprendre-typescript/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; pour typer votre code, puis un framework comme React ou Vue.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Les exercices ont été écrits pour cet article. Les corrections 1 à 14 et 18 à 20 ont été exécutées le 6 novembre 2026 avec Node.js 22.15.0 et 26.13.0, et leur sortie copiée telle quelle. Les messages du tableau d'erreurs, les comparaisons &lt;code&gt;==&lt;/code&gt; et &lt;code&gt;===&lt;/code&gt;, &lt;code&gt;0.1 + 0.2&lt;/code&gt;, les conversions de &lt;code&gt;"5"&lt;/code&gt;, l'erreur de &lt;code&gt;reduce&lt;/code&gt; sur un tableau vide, l'export manquant de l'exercice 19 et l'oubli de &lt;code&gt;await&lt;/code&gt; (&lt;code&gt;Promise { &amp;lt;pending&amp;gt; }&lt;/code&gt;, puis &lt;code&gt;reponse.ok&lt;/code&gt; à &lt;code&gt;undefined&lt;/code&gt;) viennent eux aussi d'exécutions sous ces deux versions.&lt;/p&gt;

&lt;p&gt;Les exercices 15 à 17, l'erreur sur &lt;code&gt;null&lt;/code&gt;, les statuts de fetch et le message «&amp;nbsp;Failed to fetch&amp;nbsp;» dans le navigateur, ainsi que les corrections 1 à 14, ont été vérifiés par des scripts Playwright dans Chromium 120, Chrome 156 et Edge 157, versions du canal stable pour les deux derniers.&lt;/p&gt;

&lt;p&gt;Les références techniques viennent de MDN et de la documentation de Node.js&amp;nbsp;; les chiffres, de l'enquête Stack Overflow 2026. Les conditions des plateformes ont été lues sur leurs pages officielles. Aucun lien n'est affilié.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur dans une correction&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 6 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image&amp;nbsp;: Markus Spiske (Unsplash License). Graphiques&amp;nbsp;: NeurauTech, d'après l'enquête Stack Overflow 2026 et le calendrier de Node.js.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>exercices</category>
      <category>debutant</category>
      <category>dom</category>
    </item>
    <item>
      <title>Raccourcis VS Code : l'aide-mémoire Windows, macOS et clavier AZERTY</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 15:54:44 +0000</pubDate>
      <link>https://dev.to/neurau_tech/raccourcis-vs-code-laide-memoire-windows-macos-et-clavier-azerty-364l</link>
      <guid>https://dev.to/neurau_tech/raccourcis-vs-code-laide-memoire-windows-macos-et-clavier-azerty-364l</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Les raccourcis VS Code les plus utiles tiennent en une dizaine de combinaisons&amp;nbsp;: la palette de commandes, l'ouverture rapide de fichier, le commentaire, la duplication de ligne, le multicurseur, le terminal. Le piège, pour un lecteur francophone, est ailleurs&amp;nbsp;: plusieurs raccourcis officiels sont écrits pour un clavier américain et ne tombent pas sur la touche attendue en AZERTY.&lt;/p&gt;

&lt;p&gt;Cet aide-mémoire classe les raccourcis par tâche, avec la version Windows et Linux et la version macOS. Tous viennent de la documentation officielle de &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;code.visualstudio.com&lt;/a&gt;, relue le 6 novembre 2026, alors que la version stable est VS Code 1.145, publiée le 4 novembre 2026 selon les &lt;a href="https://code.visualstudio.com/updates/v1_145" rel="noopener noreferrer"&gt;notes de version&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trois raccourcis suffisent pour démarrer&amp;nbsp;: la palette de commandes (Ctrl+Maj+P), l'ouverture rapide (Ctrl+P) et le commentaire de ligne (Ctrl+/ en QWERTY).&lt;/li&gt;
&lt;li&gt;Sur macOS, Ctrl devient le plus souvent Cmd, mais pas toujours&amp;nbsp;: le terminal, Aller à la ligne et le contrôle de code source gardent Ctrl.&lt;/li&gt;
&lt;li&gt;VS Code se règle sur la touche, pas sur le caractère. En AZERTY sous Windows, Ctrl+/ tombe sur la touche «&amp;nbsp;:&amp;nbsp;» et Ctrl+` sur la touche « ù », d'après la table du clavier français que nous avons lue.&lt;/li&gt;
&lt;li&gt;L'éditeur de raccourcis (Ctrl+K Ctrl+S) affiche la combinaison réelle pour votre clavier, et &lt;code&gt;keybindings.json&lt;/code&gt; permet de la changer.&lt;/li&gt;
&lt;li&gt;Les fiches PDF officielles à imprimer datent de 2021 (Windows, macOS) et de 2024 (Linux) selon leurs propriétés, et ignorent Copilot&amp;nbsp;: la page des raccourcis par défaut est plus à jour.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Les 10 raccourcis VS Code à apprendre en premier
&lt;/h2&gt;

&lt;p&gt;Si vous n'en retenez que dix, prenez ceux-ci&amp;nbsp;: ils couvrent l'essentiel d'une journée de code, du fichier à ouvrir au terminal. Dans tout l'article, «&amp;nbsp;Maj&amp;nbsp;» désigne la touche Shift (⇧), «&amp;nbsp;Cmd&amp;nbsp;» la touche ⌘ et «&amp;nbsp;Option&amp;nbsp;» la touche ⌥ du Mac&amp;nbsp;; Haut, Bas, Gauche et Droite sont les touches fléchées. Un raccourci en deux temps comme Ctrl+K Ctrl+C se tape ainsi&amp;nbsp;: Ctrl+K, on relâche, puis Ctrl+C.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Palette de commandes&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+P ou F1&lt;/td&gt;
&lt;td&gt;Cmd+Maj+P ou F1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ouvrir un fichier (Quick Open)&lt;/td&gt;
&lt;td&gt;Ctrl+P&lt;/td&gt;
&lt;td&gt;Cmd+P&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commenter ou décommenter la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+/&lt;/td&gt;
&lt;td&gt;Cmd+/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dupliquer la ligne vers le bas&lt;/td&gt;
&lt;td&gt;Maj+Alt+Bas&lt;/td&gt;
&lt;td&gt;Maj+Option+Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Déplacer la ligne&lt;/td&gt;
&lt;td&gt;Alt+Haut ou Bas&lt;/td&gt;
&lt;td&gt;Option+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supprimer la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+K&lt;/td&gt;
&lt;td&gt;Cmd+Maj+K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélectionner l'occurrence suivante&lt;/td&gt;
&lt;td&gt;Ctrl+D&lt;/td&gt;
&lt;td&gt;Cmd+D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Renommer un symbole&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formater le document&lt;/td&gt;
&lt;td&gt;Maj+Alt+F&lt;/td&gt;
&lt;td&gt;Maj+Option+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Afficher ou masquer le terminal&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;raccourcis par défaut&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/docs/editing/getting-started/tips-and-tricks" rel="noopener noreferrer"&gt;astuces de VS Code&lt;/a&gt;, consultés le 6 novembre 2026. Sous Linux, deux lignes diffèrent&amp;nbsp;: le formatage passe par Ctrl+Maj+I et la duplication par Ctrl+Maj+Alt+Bas.&lt;/p&gt;

&lt;p&gt;Le premier réflexe à prendre est la palette de commandes. Elle donne accès à toutes les actions de l'éditeur par leur nom, et affiche à côté de chacune son raccourci&amp;nbsp;: c'est la meilleure façon d'apprendre les autres sans fiche.&lt;/p&gt;




&lt;h2&gt;
  
  
  Navigation : palette, fichiers, symboles
&lt;/h2&gt;

&lt;p&gt;La navigation repose sur une seule zone de saisie, Quick Open, dont le préfixe change le mode. Ctrl+P cherche un fichier, et les raccourcis suivants ouvrent la même zone avec un autre préfixe.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Aller à un fichier&lt;/td&gt;
&lt;td&gt;Ctrl+P&lt;/td&gt;
&lt;td&gt;Cmd+P&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à un symbole du fichier&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+O&lt;/td&gt;
&lt;td&gt;Cmd+Maj+O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à un symbole du projet&lt;/td&gt;
&lt;td&gt;Ctrl+T&lt;/td&gt;
&lt;td&gt;Cmd+T&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+G&lt;/td&gt;
&lt;td&gt;Ctrl+G&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à la définition&lt;/td&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aperçu de la définition (Peek)&lt;/td&gt;
&lt;td&gt;Alt+F12 (Linux&amp;nbsp;: Ctrl+Maj+F10)&lt;/td&gt;
&lt;td&gt;Option+F12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Afficher les références&lt;/td&gt;
&lt;td&gt;Maj+F12&lt;/td&gt;
&lt;td&gt;Maj+F12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenir en arrière&lt;/td&gt;
&lt;td&gt;Alt+Gauche (Linux&amp;nbsp;: Ctrl+Alt+-)&lt;/td&gt;
&lt;td&gt;Ctrl+-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller en avant&lt;/td&gt;
&lt;td&gt;Alt+Droite (Linux&amp;nbsp;: Ctrl+Maj+-)&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Erreur ou avertissement suivant&lt;/td&gt;
&lt;td&gt;F8&lt;/td&gt;
&lt;td&gt;F8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Panneau Problèmes&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+M&lt;/td&gt;
&lt;td&gt;Cmd+Maj+M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/editing/getting-started/tips-and-tricks" rel="noopener noreferrer"&gt;astuces de VS Code&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;raccourcis par défaut&lt;/a&gt;. Deux pièges pour les utilisateurs de Mac&amp;nbsp;: Aller à la ligne reste sur Ctrl+G, et la navigation arrière n'utilise pas Option+Gauche, contrairement à ce que laissent croire certains guides qui remplacent mécaniquement Alt par Option.&lt;/p&gt;

&lt;p&gt;Le couple F12 et Alt+Gauche est celui qui fait gagner le plus de temps dans un projet inconnu&amp;nbsp;: on saute dans la définition d'une fonction, on lit, on revient. Si vous découvrez JavaScript, essayez-le sur les exemples de notre guide pour &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;apprendre JavaScript&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Édition : commenter, dupliquer, déplacer, indenter
&lt;/h2&gt;

&lt;p&gt;Ce sont les raccourcis VS Code les plus recherchés, et ceux qui posent le plus de problèmes en AZERTY. La colonne Windows reprend les touches du clavier américain&amp;nbsp;: la section AZERTY plus bas donne leur équivalent.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Commenter ou décommenter la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+/&lt;/td&gt;
&lt;td&gt;Cmd+/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ajouter un commentaire de ligne&lt;/td&gt;
&lt;td&gt;Ctrl+K Ctrl+C&lt;/td&gt;
&lt;td&gt;Cmd+K Cmd+C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retirer un commentaire de ligne&lt;/td&gt;
&lt;td&gt;Ctrl+K Ctrl+U&lt;/td&gt;
&lt;td&gt;Cmd+K Cmd+U&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commentaire de bloc&lt;/td&gt;
&lt;td&gt;Maj+Alt+A (Linux&amp;nbsp;: Ctrl+Maj+A)&lt;/td&gt;
&lt;td&gt;Maj+Option+A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dupliquer la ligne (haut ou bas)&lt;/td&gt;
&lt;td&gt;Maj+Alt+Haut ou Bas (Linux&amp;nbsp;: Ctrl+Maj+Alt+Haut ou Bas)&lt;/td&gt;
&lt;td&gt;Maj+Option+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Déplacer la ligne&lt;/td&gt;
&lt;td&gt;Alt+Haut ou Bas&lt;/td&gt;
&lt;td&gt;Option+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supprimer la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+K&lt;/td&gt;
&lt;td&gt;Cmd+Maj+K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insérer une ligne dessous&lt;/td&gt;
&lt;td&gt;Ctrl+Entrée&lt;/td&gt;
&lt;td&gt;Cmd+Entrée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insérer une ligne dessus&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+Entrée&lt;/td&gt;
&lt;td&gt;Cmd+Maj+Entrée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indenter la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+]&lt;/td&gt;
&lt;td&gt;Cmd+]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Désindenter la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+[&lt;/td&gt;
&lt;td&gt;Cmd+[&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Renommer un symbole&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formater le document&lt;/td&gt;
&lt;td&gt;Maj+Alt+F (Linux&amp;nbsp;: Ctrl+Maj+I)&lt;/td&gt;
&lt;td&gt;Maj+Option+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formater la sélection&lt;/td&gt;
&lt;td&gt;Ctrl+K Ctrl+F&lt;/td&gt;
&lt;td&gt;Cmd+K Cmd+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correction rapide&lt;/td&gt;
&lt;td&gt;Ctrl+.&lt;/td&gt;
&lt;td&gt;Cmd+.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retour à la ligne automatique&lt;/td&gt;
&lt;td&gt;Alt+Z&lt;/td&gt;
&lt;td&gt;Option+Z&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;raccourcis par défaut&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/docs/editing/codebasics" rel="noopener noreferrer"&gt;bases de l'édition&lt;/a&gt;, consultés le 6 novembre 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le commentaire.&lt;/strong&gt; Ctrl+/ bascule le commentaire de ligne, quel que soit le langage&amp;nbsp;: &lt;code&gt;//&lt;/code&gt; en JavaScript, &lt;code&gt;#&lt;/code&gt; en Python, &lt;code&gt;&amp;lt;!-- --&amp;gt;&lt;/code&gt; en HTML. Si la touche ne répond pas sur votre clavier, Ctrl+K Ctrl+C et Ctrl+K Ctrl+U font le même travail en deux temps et n'utilisent que des lettres&amp;nbsp;: ils marchent sur les claviers latins, AZERTY compris.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'indentation.&lt;/strong&gt; Pour indenter un bloc, le plus simple reste de le sélectionner puis d'appuyer sur Tab, ou Maj+Tab pour le désindenter. Ctrl+] et Ctrl+[ font la même chose sans sélection, mais leurs touches changent en AZERTY. En Python, où l'indentation fait partie de la syntaxe, c'est le premier raccourci à maîtriser&amp;nbsp;: notre guide pour &lt;a href="https://neurautech.com/apprendre-python-guide-complet-pour-debutants/" rel="noopener noreferrer"&gt;apprendre Python&lt;/a&gt; explique pourquoi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le renommage.&lt;/strong&gt; F2 renomme une variable ou une fonction dans tout le projet, en suivant le langage. C'est plus sûr qu'un remplacement de texte, qui toucherait aussi les chaînes et les commentaires.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multicurseur et sélection
&lt;/h2&gt;

&lt;p&gt;Le multicurseur permet de modifier plusieurs endroits à la fois, et c'est souvent ce qui convertit les débutants aux raccourcis. Le plus utile est Ctrl+D&amp;nbsp;: chaque appui ajoute la prochaine occurrence du mot sélectionné à la sélection.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ajouter un curseur au clic&lt;/td&gt;
&lt;td&gt;Alt+Clic&lt;/td&gt;
&lt;td&gt;Option+Clic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curseur au-dessus ou en dessous&lt;/td&gt;
&lt;td&gt;Ctrl+Alt+Haut ou Bas (Linux&amp;nbsp;: Maj+Alt+Haut ou Bas)&lt;/td&gt;
&lt;td&gt;Cmd+Option+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélectionner l'occurrence suivante&lt;/td&gt;
&lt;td&gt;Ctrl+D&lt;/td&gt;
&lt;td&gt;Cmd+D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sauter l'occurrence suivante&lt;/td&gt;
&lt;td&gt;Ctrl+K Ctrl+D&lt;/td&gt;
&lt;td&gt;Cmd+K Cmd+D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélectionner toutes les occurrences&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+L&lt;/td&gt;
&lt;td&gt;Cmd+Maj+L&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curseur en fin de chaque ligne sélectionnée&lt;/td&gt;
&lt;td&gt;Maj+Alt+I&lt;/td&gt;
&lt;td&gt;Maj+Option+I&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélectionner la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+L&lt;/td&gt;
&lt;td&gt;Cmd+L&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Étendre ou réduire la sélection&lt;/td&gt;
&lt;td&gt;Maj+Alt+Droite ou Gauche&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+Cmd+Droite ou Gauche&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélection en colonne&lt;/td&gt;
&lt;td&gt;Maj+Alt+glisser&lt;/td&gt;
&lt;td&gt;Maj+Option+glisser&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/editing/codebasics" rel="noopener noreferrer"&gt;bases de l'édition&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/docs/editing/getting-started/tips-and-tricks" rel="noopener noreferrer"&gt;astuces de VS Code&lt;/a&gt;. La documentation prévient que le pilote de la carte graphique peut intercepter certains de ces raccourcis&amp;nbsp;: sur certains PC, Ctrl+Alt+Haut ou Bas fait pivoter l'écran au lieu d'ajouter un curseur.&lt;/p&gt;

&lt;p&gt;Un exemple concret&amp;nbsp;: pour ajouter un point-virgule au bout de dix lignes, sélectionnez-les, appuyez sur Maj+Alt+I (Maj+Option+I sur Mac) pour placer un curseur sur chaque ligne, puis sur Fin (Cmd+Droite sur Mac) et tapez «&amp;nbsp;;&amp;nbsp;» une seule fois&amp;nbsp;: il apparaît au bout des dix lignes. Les exercices de notre cours &lt;a href="https://neurautech.com/html-css-debutant/" rel="noopener noreferrer"&gt;HTML et CSS pour débutant&lt;/a&gt; se prêtent bien à l'entraînement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rechercher et remplacer
&lt;/h2&gt;

&lt;p&gt;La recherche existe à deux niveaux&amp;nbsp;: dans le fichier ouvert, et dans tout le projet. Les raccourcis suivent la même logique, avec Maj pour passer au projet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rechercher dans le fichier&lt;/td&gt;
&lt;td&gt;Ctrl+F&lt;/td&gt;
&lt;td&gt;Cmd+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remplacer dans le fichier&lt;/td&gt;
&lt;td&gt;Ctrl+H&lt;/td&gt;
&lt;td&gt;Cmd+Option+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Résultat suivant ou précédent&lt;/td&gt;
&lt;td&gt;Entrée ou Maj+Entrée&lt;/td&gt;
&lt;td&gt;Entrée ou Maj+Entrée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sélectionner tous les résultats&lt;/td&gt;
&lt;td&gt;Alt+Entrée&lt;/td&gt;
&lt;td&gt;Option+Entrée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rechercher dans la sélection&lt;/td&gt;
&lt;td&gt;Alt+L&lt;/td&gt;
&lt;td&gt;Cmd+Option+L&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rechercher dans le projet&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+F&lt;/td&gt;
&lt;td&gt;Cmd+Maj+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remplacer dans le projet&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+H&lt;/td&gt;
&lt;td&gt;Cmd+Maj+H&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Activer les expressions régulières&lt;/td&gt;
&lt;td&gt;Alt+R&lt;/td&gt;
&lt;td&gt;Cmd+Option+R&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;raccourcis par défaut&lt;/a&gt;, &lt;a href="https://code.visualstudio.com/docs/editing/codebasics" rel="noopener noreferrer"&gt;bases de l'édition&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/docs/editing/getting-started/tips-and-tricks" rel="noopener noreferrer"&gt;astuces de VS Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alt+Entrée est le raccourci méconnu de cette liste&amp;nbsp;: après une recherche, il pose un curseur sur chaque résultat, ce qui transforme la recherche en édition multiple. Combiné aux expressions régulières, il remplace bien des scripts de transformation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Terminal intégré
&lt;/h2&gt;

&lt;p&gt;Le terminal est le cas où macOS garde Ctrl&amp;nbsp;: Ctrl+` affiche ou masque le terminal sur les trois systèmes. C'est aussi le raccourci qui pose le plus de problèmes en AZERTY, car la touche accent grave n'y existe pas comme touche simple.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Afficher ou masquer le terminal&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nouveau terminal&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+`&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diviser le terminal&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+5&lt;/td&gt;
&lt;td&gt;Cmd+\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volet suivant ou précédent&lt;/td&gt;
&lt;td&gt;Alt+Droite ou Gauche&lt;/td&gt;
&lt;td&gt;Cmd+Option+Droite ou Gauche&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remonter ou descendre à la commande précédente dans la sortie&lt;/td&gt;
&lt;td&gt;Ctrl+Haut ou Bas&lt;/td&gt;
&lt;td&gt;Cmd+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ouvrir un terminal externe&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+C&lt;/td&gt;
&lt;td&gt;Cmd+Maj+C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copier, coller (Windows et macOS)&lt;/td&gt;
&lt;td&gt;Ctrl+C, Ctrl+V&lt;/td&gt;
&lt;td&gt;Cmd+C, Cmd+V&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copier, coller (Linux)&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+C, Ctrl+Maj+V&lt;/td&gt;
&lt;td&gt;sans objet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Source&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/terminal/basics" rel="noopener noreferrer"&gt;documentation du terminal&lt;/a&gt;, consultée le 6 novembre 2026. La division et le changement de volet ne fonctionnent que si le terminal a le focus. La documentation n'indique pas de raccourci par défaut pour fermer un terminal&amp;nbsp;: on passe par l'icône de corbeille ou par la palette.&lt;/p&gt;

&lt;p&gt;Si vous passez beaucoup de temps dans ce terminal, notre guide des &lt;a href="https://neurautech.com/commandes-linux-de-base/" rel="noopener noreferrer"&gt;commandes Linux de base&lt;/a&gt; est le complément naturel de cette section.&lt;/p&gt;




&lt;h2&gt;
  
  
  Panneaux, barre latérale et éditeurs
&lt;/h2&gt;

&lt;p&gt;Ces raccourcis servent à gagner de la place à l'écran et à passer d'une vue à l'autre sans souris.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Afficher ou masquer la barre latérale&lt;/td&gt;
&lt;td&gt;Ctrl+B&lt;/td&gt;
&lt;td&gt;Cmd+B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Afficher ou masquer le panneau du bas&lt;/td&gt;
&lt;td&gt;Ctrl+J&lt;/td&gt;
&lt;td&gt;Cmd+J&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explorateur de fichiers&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+E&lt;/td&gt;
&lt;td&gt;Cmd+Maj+E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vue Extensions&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+X&lt;/td&gt;
&lt;td&gt;Cmd+Maj+X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diviser l'éditeur&lt;/td&gt;
&lt;td&gt;Ctrl+\&lt;/td&gt;
&lt;td&gt;Cmd+\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller au groupe d'éditeurs 1, 2 ou 3&lt;/td&gt;
&lt;td&gt;Ctrl+1, 2 ou 3&lt;/td&gt;
&lt;td&gt;Cmd+1, 2 ou 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fermer l'éditeur&lt;/td&gt;
&lt;td&gt;Ctrl+W ou Ctrl+F4 (Linux&amp;nbsp;: Ctrl+W)&lt;/td&gt;
&lt;td&gt;Cmd+W&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rouvrir l'éditeur fermé&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+T&lt;/td&gt;
&lt;td&gt;Cmd+Maj+T&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mode Zen&lt;/td&gt;
&lt;td&gt;Ctrl+K Z&lt;/td&gt;
&lt;td&gt;Cmd+K Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paramètres&lt;/td&gt;
&lt;td&gt;Ctrl+,&lt;/td&gt;
&lt;td&gt;Cmd+,&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Éditeur des raccourcis&lt;/td&gt;
&lt;td&gt;Ctrl+K Ctrl+S&lt;/td&gt;
&lt;td&gt;Cmd+K Cmd+S&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;raccourcis par défaut&lt;/a&gt;, &lt;a href="https://code.visualstudio.com/docs/editing/getting-started/tips-and-tricks" rel="noopener noreferrer"&gt;astuces de VS Code&lt;/a&gt; et la fiche officielle pour Windows. La vue Extensions est celle où installer les outils de notre sélection des &lt;a href="https://neurautech.com/meilleures-extensions-vs-code-en-2026-pour-devs/" rel="noopener noreferrer"&gt;meilleures extensions VS Code&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Débogage
&lt;/h2&gt;

&lt;p&gt;Les raccourcis de débogage sont les mêmes sur les trois systèmes, à l'exception de ceux qui utilisent Ctrl ou Cmd. Sur un Mac, les touches de fonction peuvent demander d'appuyer en plus sur Fn, selon les réglages du clavier. Apple attribue aussi Fn+F11 à «&amp;nbsp;Afficher le bureau&amp;nbsp;» (&lt;a href="https://support.apple.com/en-us/102650" rel="noopener noreferrer"&gt;raccourcis clavier du Mac&lt;/a&gt;)&amp;nbsp;: si le pas à pas détaillé ne répond pas, c'est la piste à vérifier.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Démarrer ou continuer&lt;/td&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arrêter&lt;/td&gt;
&lt;td&gt;Maj+F5&lt;/td&gt;
&lt;td&gt;Maj+F5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redémarrer&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+F5&lt;/td&gt;
&lt;td&gt;Cmd+Maj+F5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pas à pas principal (step over)&lt;/td&gt;
&lt;td&gt;F10&lt;/td&gt;
&lt;td&gt;F10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pas à pas détaillé (step into)&lt;/td&gt;
&lt;td&gt;F11&lt;/td&gt;
&lt;td&gt;F11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pas à pas sortant (step out)&lt;/td&gt;
&lt;td&gt;Maj+F11&lt;/td&gt;
&lt;td&gt;Maj+F11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Point d'arrêt&lt;/td&gt;
&lt;td&gt;F9&lt;/td&gt;
&lt;td&gt;F9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Point d'arrêt dans la ligne&lt;/td&gt;
&lt;td&gt;Maj+F9&lt;/td&gt;
&lt;td&gt;Maj+F9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vue Exécuter et déboguer&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+D&lt;/td&gt;
&lt;td&gt;Cmd+Maj+D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Console de débogage&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+Y&lt;/td&gt;
&lt;td&gt;Cmd+Maj+Y&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Source&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/debugtest/debugging" rel="noopener noreferrer"&gt;documentation du débogage&lt;/a&gt;, consultée le 6 novembre 2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  Git et contrôle de code source
&lt;/h2&gt;

&lt;p&gt;VS Code définit peu de raccourcis pour Git&amp;nbsp;: l'essentiel passe par la vue Contrôle de code source et par la palette. Voici ceux que nous avons trouvés dans la documentation et dans les raccourcis par défaut.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vue Contrôle de code source&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+G&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+G&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Valider (commit) depuis la zone de message&lt;/td&gt;
&lt;td&gt;Ctrl+Entrée&lt;/td&gt;
&lt;td&gt;Cmd+Entrée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toute autre commande Git&lt;/td&gt;
&lt;td&gt;palette, puis «&amp;nbsp;Git:&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;palette, puis «&amp;nbsp;Git:&amp;nbsp;»&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Source&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/sourcecontrol/overview" rel="noopener noreferrer"&gt;documentation du contrôle de code source&lt;/a&gt;. Comme pour le terminal, le Mac garde Ctrl pour ouvrir la vue. Le raccourci de validation est la commande &lt;code&gt;scm.acceptInput&lt;/code&gt;, liée à Ctrl+Entrée dans les raccourcis par défaut de la version 1.107.1 que nous avons inspectée (voir la méthode en fin d'article).&lt;/p&gt;

&lt;p&gt;Dans la palette, tapez «&amp;nbsp;Git:&amp;nbsp;» pour lister les commandes&amp;nbsp;: Push, Pull, Stash, changer de branche. Si ces notions sont nouvelles, notre guide &lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub pour débutant&lt;/a&gt; les reprend depuis le début.&lt;/p&gt;




&lt;h2&gt;
  
  
  Copilot et chat
&lt;/h2&gt;

&lt;p&gt;La documentation officielle liste aujourd'hui sept raccourcis pour GitHub Copilot et le chat. Ils viennent de l'aide-mémoire des fonctions IA de la documentation, daté du 4 novembre 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows et Linux&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ouvrir la vue Chat&lt;/td&gt;
&lt;td&gt;Ctrl+Alt+I&lt;/td&gt;
&lt;td&gt;Ctrl+Cmd+I&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nouvelle conversation&lt;/td&gt;
&lt;td&gt;Ctrl+N&lt;/td&gt;
&lt;td&gt;Cmd+N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chat dans l'éditeur (inline)&lt;/td&gt;
&lt;td&gt;Ctrl+I&lt;/td&gt;
&lt;td&gt;Cmd+I&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chat dans le terminal&lt;/td&gt;
&lt;td&gt;Ctrl+I&lt;/td&gt;
&lt;td&gt;Cmd+I&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quick Chat&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+Alt+L&lt;/td&gt;
&lt;td&gt;Maj+Option+Cmd+L&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accepter une suggestion&lt;/td&gt;
&lt;td&gt;Tab&lt;/td&gt;
&lt;td&gt;Tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refuser une suggestion&lt;/td&gt;
&lt;td&gt;Échap&lt;/td&gt;
&lt;td&gt;Échap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Source&amp;nbsp;: &lt;a href="https://code.visualstudio.com/docs/agents/reference/ai-features-cheat-sheet" rel="noopener noreferrer"&gt;aide-mémoire officiel des fonctions IA de VS Code&lt;/a&gt;, consulté le 6 novembre 2026. Ctrl+N est aussi le raccourci Nouveau fichier&amp;nbsp;: il n'ouvre une nouvelle conversation que lorsque le focus est dans le chat, d'après les raccourcis par défaut de la version 1.107.1 que nous avons inspectée.&lt;/p&gt;

&lt;p&gt;La page ne donne pas de raccourci pour le mode vocal ni pour les suggestions de modification suivantes. Pour aller plus loin que les raccourcis, notre article sur l'&lt;a href="https://neurautech.com/comment-utiliser-lia-pour-coder-3x-plus-vite/" rel="noopener noreferrer"&gt;IA pour coder plus vite&lt;/a&gt; résume ce que les études mesurent vraiment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Raccourcis VS Code sur clavier AZERTY : ce qui change
&lt;/h2&gt;

&lt;p&gt;En AZERTY, une partie des raccourcis VS Code ne tombe pas sur la touche imprimée dans les guides, parce que l'éditeur se règle sur la touche et non sur le caractère. La documentation le dit&amp;nbsp;: les touches sont «&amp;nbsp;des représentations de touches virtuelles&amp;nbsp;» qui «&amp;nbsp;ne correspondent pas forcément au caractère produit&amp;nbsp;» (notre traduction), et l'interface affiche les raccourcis selon la disposition du clavier du système (&lt;a href="https://code.visualstudio.com/docs/configure/keybindings" rel="noopener noreferrer"&gt;documentation des raccourcis&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ov94c6pg6s2mwoy5uh6.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ov94c6pg6s2mwoy5uh6.webp" alt="Schéma des raccourcis VS Code sur clavier AZERTY sous Windows&amp;nbsp;: le commentaire passe sur Ctrl+deux-points, le terminal sur Ctrl+ù, la division de l'éditeur sur Ctrl+astérisque" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ce que nous avons vérifié.&lt;/strong&gt; Sur la machine de rédaction, un PC Windows 11 avec la disposition «&amp;nbsp;Français&amp;nbsp;» (AZERTY) installée, nous avons interrogé la table du clavier de Windows pour savoir quel caractère produit chaque touche virtuelle. Nous avons aussi lu les raccourcis par défaut dans les fichiers de VS Code 1.107.1, la version installée sur ce PC, plus ancienne que la 1.145 actuelle. Nous n'avons pas ouvert l'éditeur de raccourcis ni appuyé sur les touches&amp;nbsp;: le tableau ci-dessous est une déduction de ces deux lectures.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Raccourci officiel (QWERTY)&lt;/th&gt;
&lt;th&gt;Touche virtuelle Windows&lt;/th&gt;
&lt;th&gt;Équivalent attendu en AZERTY français&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+/ (commenter)&lt;/td&gt;
&lt;td&gt;VK_OEM_2&lt;/td&gt;
&lt;td&gt;Ctrl+:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+` (terminal)&lt;/td&gt;
&lt;td&gt;VK_OEM_3&lt;/td&gt;
&lt;td&gt;Ctrl+ù&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+Maj+` (nouveau terminal)&lt;/td&gt;
&lt;td&gt;VK_OEM_3&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+ù&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+\ (diviser l'éditeur)&lt;/td&gt;
&lt;td&gt;VK_OEM_5&lt;/td&gt;
&lt;td&gt;Ctrl+*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+] (indenter)&lt;/td&gt;
&lt;td&gt;VK_OEM_6&lt;/td&gt;
&lt;td&gt;Ctrl+^ (touche morte, non vérifié)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+[ (désindenter)&lt;/td&gt;
&lt;td&gt;VK_OEM_4&lt;/td&gt;
&lt;td&gt;Ctrl+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+. (correction rapide)&lt;/td&gt;
&lt;td&gt;VK_OEM_PERIOD&lt;/td&gt;
&lt;td&gt;Ctrl+; (à confirmer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+, (paramètres)&lt;/td&gt;
&lt;td&gt;VK_OEM_COMMA&lt;/td&gt;
&lt;td&gt;Ctrl+, sur la touche «&amp;nbsp;,&amp;nbsp;» (à confirmer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+- (zoom arrière)&lt;/td&gt;
&lt;td&gt;VK_OEM_MINUS&lt;/td&gt;
&lt;td&gt;aucune touche&amp;nbsp;; Ctrl+moins du pavé numérique (à confirmer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+K Ctrl+C, Ctrl+D, Ctrl+P&lt;/td&gt;
&lt;td&gt;lettres&lt;/td&gt;
&lt;td&gt;inchangés&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Un document de Microsoft confirme la logique sur un cas&amp;nbsp;: un billet de blog archivé, consacré à la version 0.10.5 de VS Code, indiquait qu'avec une disposition «&amp;nbsp;French (France)&amp;nbsp;», la commande Diviser l'éditeur s'affiche comme Ctrl+* (&lt;a href="https://learn.microsoft.com/en-us/archive/blogs/user_ed/visual-studio-code-new-features-improvements-for-non-us-standard-keyboard-layouts" rel="noopener noreferrer"&gt;blog archivé de Microsoft&lt;/a&gt;). C'est exactement ce que donne notre table pour Ctrl+.&lt;/p&gt;

&lt;p&gt;Le terminal a une histoire plus ancienne. Un ticket de décembre 2016, ouvert sur Linux, signalait que Ctrl+` ne fonctionnait pas en AZERTY ; l'équipe y répondait que VS Code ne livre pas de raccourcis par défaut propres à chaque disposition, et proposait une liaison par code de touche (&lt;a href="https://github.com/microsoft/vscode/issues/17651" rel="noopener noreferrer"&gt;ticket GitHub 17651&lt;/a&gt;). Le ticket a été fermé en 2017 : son contenu vaut comme historique, pas comme état actuel.&lt;/p&gt;

&lt;p&gt;Sur macOS et sous Linux, la correspondance peut être différente&amp;nbsp;: nous ne l'avons pas vérifiée. Dans tous les cas, l'éditeur de raccourcis de votre propre machine fait foi.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vérifier et corriger un raccourci en trois étapes
&lt;/h2&gt;

&lt;p&gt;La méthode est la même sur les trois systèmes&amp;nbsp;: lire, diagnostiquer, puis réassigner. Elle s'appuie sur trois outils documentés de VS Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5df18xxvg1r0legb4hf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5df18xxvg1r0legb4hf.webp" alt="Les trois étapes pour corriger un raccourci&amp;nbsp;: lire la touche réelle dans l'éditeur de raccourcis, diagnostiquer avec le journal de dépannage, réassigner dans keybindings.json" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Lire la touche réelle.&lt;/strong&gt; Ouvrez l'éditeur de raccourcis avec Ctrl+K Ctrl+S (Cmd+K Cmd+S sur Mac), ou par la palette avec «&amp;nbsp;Preferences: Open Keyboard Shortcuts&amp;nbsp;». Cherchez la commande, par exemple «&amp;nbsp;Toggle Line Comment&amp;nbsp;»&amp;nbsp;: la colonne de droite affiche la combinaison telle qu'elle s'applique à votre clavier, pas celle du clavier américain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Diagnostiquer.&lt;/strong&gt; Si une touche ne fait rien, lancez depuis la palette «&amp;nbsp;Developer: Toggle Keyboard Shortcuts Troubleshooting&amp;nbsp;». Selon la &lt;a href="https://code.visualstudio.com/docs/configure/keybindings" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, cette commande enregistre les raccourcis reçus et ouvre le panneau Sortie sur le journal. Appuyez ensuite sur la combinaison&amp;nbsp;: le journal indique le code de touche reçu et la commande déclenchée, ou l'absence de commande.&lt;/p&gt;

&lt;p&gt;Un ticket GitHub montre à quoi ressemble ce journal. Une ligne indique «&amp;nbsp;Converted keydown event - modifiers: [ctrl], code: Slash&amp;nbsp;», la suivante «&amp;nbsp;matched editor.action.commentLine&amp;nbsp;» (&lt;a href="https://github.com/microsoft/vscode/issues/136351" rel="noopener noreferrer"&gt;ticket GitHub 136351&lt;/a&gt;). Si aucune ligne «&amp;nbsp;matched&amp;nbsp;» n'apparaît, aucune commande n'est liée à cette touche&amp;nbsp;; si une autre commande apparaît, c'est un conflit, souvent avec une extension.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Réassigner.&lt;/strong&gt; Dans l'éditeur de raccourcis, l'icône «&amp;nbsp;Open Keyboard Shortcuts (JSON)&amp;nbsp;» ouvre le fichier &lt;code&gt;keybindings.json&lt;/code&gt; de l'utilisateur. Chaque règle y associe une touche (&lt;code&gt;key&lt;/code&gt;), une commande (&lt;code&gt;command&lt;/code&gt;) et, en option, une condition (&lt;code&gt;when&lt;/code&gt;). Préfixer une commande d'un tiret supprime une liaison existante.&lt;/p&gt;

&lt;p&gt;La documentation propose aussi d'écrire la touche par son code physique, entre crochets, pour qu'un raccourci ne dépende plus de la disposition. Voici un fichier valide qui place le commentaire et le terminal sur des touches physiques&amp;nbsp;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;json&lt;br&gt;
[&lt;br&gt;
  {&lt;br&gt;
    "key": "ctrl+[Slash]",&lt;br&gt;
    "command": "editor.action.commentLine",&lt;br&gt;
    "when": "editorTextFocus &amp;amp;&amp;amp; !editorReadonly"&lt;br&gt;
  },&lt;br&gt;
  {&lt;br&gt;
    "key": "ctrl+[Backquote]",&lt;br&gt;
    "command": "workbench.action.terminal.toggleTerminal"&lt;br&gt;
  }&lt;br&gt;
]&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sur un clavier AZERTY français, &lt;code&gt;[Slash]&lt;/code&gt; désigne la touche «&amp;nbsp;!&amp;nbsp;» (à droite de «&amp;nbsp;:&amp;nbsp;») et &lt;code&gt;[Backquote]&lt;/code&gt; la touche «&amp;nbsp;²&amp;nbsp;», sous Échap&amp;nbsp;: c'est la position de ces touches sur un clavier américain, d'après la table de Windows que nous avons lue. La liaison par code de touche est celle que proposait l'équipe de VS Code dans le ticket 17651. Nous n'avons pas testé ce fichier dans l'éditeur&amp;nbsp;: vérifiez le résultat dans l'éditeur de raccourcis après l'enregistrement.&lt;/p&gt;

&lt;p&gt;Pour saisir une combinaison sans erreur, la &lt;a href="https://code.visualstudio.com/docs/configure/keybindings" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; signale le widget Define Keybinding, ouvert par Ctrl+K Ctrl+K dans &lt;code&gt;keybindings.json&lt;/code&gt;&amp;nbsp;: il écoute les touches pressées et écrit la règle à votre place. Sous Linux, elle recommande de redémarrer VS Code après un changement de disposition du clavier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le tableau à imprimer
&lt;/h2&gt;

&lt;p&gt;Ce tableau reprend vingt raccourcis VS Code, avec la colonne AZERTY déduite plus haut pour les touches qui changent. Imprimez la page ou faites une capture de ce bloc.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Windows (QWERTY)&lt;/th&gt;
&lt;th&gt;Windows AZERTY (déduit, non testé)&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Palette de commandes&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+P&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+P&lt;/td&gt;
&lt;td&gt;Cmd+Maj+P&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ouvrir un fichier&lt;/td&gt;
&lt;td&gt;Ctrl+P&lt;/td&gt;
&lt;td&gt;Ctrl+P&lt;/td&gt;
&lt;td&gt;Cmd+P&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Symbole du fichier&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+O&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+O&lt;/td&gt;
&lt;td&gt;Cmd+Maj+O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+G&lt;/td&gt;
&lt;td&gt;Ctrl+G&lt;/td&gt;
&lt;td&gt;Ctrl+G&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aller à la définition&lt;/td&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commenter la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+/&lt;/td&gt;
&lt;td&gt;Ctrl+: ou Ctrl+K Ctrl+C&lt;/td&gt;
&lt;td&gt;Cmd+/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commentaire de bloc&lt;/td&gt;
&lt;td&gt;Maj+Alt+A&lt;/td&gt;
&lt;td&gt;Maj+Alt+A&lt;/td&gt;
&lt;td&gt;Maj+Option+A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dupliquer la ligne&lt;/td&gt;
&lt;td&gt;Maj+Alt+Bas&lt;/td&gt;
&lt;td&gt;Maj+Alt+Bas&lt;/td&gt;
&lt;td&gt;Maj+Option+Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Déplacer la ligne&lt;/td&gt;
&lt;td&gt;Alt+Haut ou Bas&lt;/td&gt;
&lt;td&gt;Alt+Haut ou Bas&lt;/td&gt;
&lt;td&gt;Option+Haut ou Bas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supprimer la ligne&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+K&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+K&lt;/td&gt;
&lt;td&gt;Cmd+Maj+K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indenter, désindenter&lt;/td&gt;
&lt;td&gt;Ctrl+] et Ctrl+[&lt;/td&gt;
&lt;td&gt;Tab et Maj+Tab sur sélection&lt;/td&gt;
&lt;td&gt;Cmd+] et Cmd+[&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Occurrence suivante&lt;/td&gt;
&lt;td&gt;Ctrl+D&lt;/td&gt;
&lt;td&gt;Ctrl+D&lt;/td&gt;
&lt;td&gt;Cmd+D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toutes les occurrences&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+L&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+L&lt;/td&gt;
&lt;td&gt;Cmd+Maj+L&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Renommer&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formater&lt;/td&gt;
&lt;td&gt;Maj+Alt+F&lt;/td&gt;
&lt;td&gt;Maj+Alt+F&lt;/td&gt;
&lt;td&gt;Maj+Option+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rechercher dans le projet&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+F&lt;/td&gt;
&lt;td&gt;Ctrl+Maj+F&lt;/td&gt;
&lt;td&gt;Cmd+Maj+F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terminal&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;td&gt;Ctrl+ù&lt;/td&gt;
&lt;td&gt;Ctrl+`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barre latérale&lt;/td&gt;
&lt;td&gt;Ctrl+B&lt;/td&gt;
&lt;td&gt;Ctrl+B&lt;/td&gt;
&lt;td&gt;Cmd+B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Démarrer le débogage&lt;/td&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chat Copilot&lt;/td&gt;
&lt;td&gt;Ctrl+Alt+I&lt;/td&gt;
&lt;td&gt;Ctrl+Alt+I&lt;/td&gt;
&lt;td&gt;Ctrl+Cmd+I&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Microsoft publie aussi trois fiches PDF officielles, pour &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;, &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer"&gt;macOS&lt;/a&gt; et &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;. D'après leurs propriétés, les fiches Windows et macOS ont été créées en août 2021 et la fiche Linux en septembre 2024&amp;nbsp;: aucune ne mentionne Copilot ni le chat, et toutes supposent un clavier américain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Cet aide-mémoire est une synthèse de la documentation officielle. Quelques points restent ouverts&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le comportement réel en AZERTY.&lt;/strong&gt; La colonne AZERTY est déduite de la table du clavier français de Windows et du mécanisme documenté par VS Code. Nous n'avons appuyé sur aucune touche dans l'éditeur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La version inspectée.&lt;/strong&gt; Les raccourcis lus dans les fichiers du programme viennent de VS Code 1.107.1, installé sur la machine de rédaction. Pour la version 1.145, nous nous appuyons sur les pages de documentation relues le 6 novembre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ctrl+^ pour indenter.&lt;/strong&gt; La touche «&amp;nbsp;^&amp;nbsp;» est une touche morte en AZERTY&amp;nbsp;; nous ne savons pas si Ctrl+^ déclenche bien l'indentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les zooms Ctrl+= et Ctrl+-.&lt;/strong&gt; La table de Windows n'associe aucune touche à la touche virtuelle du signe moins sur le clavier français&amp;nbsp;: Ctrl+- pourrait ne pas répondre. Les raccourcis par défaut de la version 1.107.1 lient aussi le zoom arrière à Ctrl+moins du pavé numérique et le zoom avant à Ctrl+plus du pavé numérique&amp;nbsp;; nous n'avons pas appuyé sur ces touches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS et Linux en AZERTY.&lt;/strong&gt; Leur correspondance n'a pas été vérifiée.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le mapping exact des fiches PDF pour Mac.&lt;/strong&gt; Le texte extrait du PDF macOS perd ses symboles&amp;nbsp;; les combinaisons Mac de cet article viennent des pages HTML de la documentation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quel est le raccourci pour commenter dans VS Code ?
&lt;/h3&gt;

&lt;p&gt;Ctrl+/ sous Windows et Linux, Cmd+/ sur Mac, selon la &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;liste des raccourcis par défaut&lt;/a&gt;. Sur un clavier AZERTY sous Windows, la même commande tombe sur Ctrl+:, d'après notre lecture de la table du clavier. Ctrl+K Ctrl+C ajoute un commentaire et Ctrl+K Ctrl+U le retire, sur les claviers latins, AZERTY compris.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comment ouvrir le terminal dans VS Code avec un clavier AZERTY ?
&lt;/h3&gt;

&lt;p&gt;Le raccourci officiel est Ctrl+&lt;code&gt;. En AZERTY français, il correspond à Ctrl+ù sous Windows, selon notre lecture de la table du clavier. Vous pouvez aussi le lier à la touche « ² » avec la règle &lt;/code&gt;ctrl+[Backquote]&lt;code&gt; dans &lt;/code&gt;keybindings.json`, ou passer par le menu Affichage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comment dupliquer une ligne dans VS Code ?
&lt;/h3&gt;

&lt;p&gt;Maj+Alt+Bas copie la ligne en dessous, et Maj+Alt+Haut au-dessus, sous Windows. Sur Mac, c'est Maj+Option+Bas ou Haut. Sous Linux, la &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;page des raccourcis par défaut&lt;/a&gt; indique Ctrl+Maj+Alt+Bas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Où trouver la liste complète des raccourcis VS Code ?
&lt;/h3&gt;

&lt;p&gt;Dans l'éditeur lui-même, avec Ctrl+K Ctrl+S, qui affiche les combinaisons adaptées à votre clavier. En ligne, la &lt;a href="https://code.visualstudio.com/docs/reference/default-keybindings" rel="noopener noreferrer"&gt;page des raccourcis par défaut&lt;/a&gt; est la plus à jour&amp;nbsp;; les fiches PDF officielles, plus anciennes, se prêtent mieux à l'impression. Si vous hésitez encore sur l'éditeur, notre &lt;a href="https://neurautech.com/meilleurs-ide-editeurs-code-2026-comparatif/" rel="noopener noreferrer"&gt;comparatif des IDE&lt;/a&gt; situe VS Code face aux autres.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse fondée sur la documentation officielle de VS Code (raccourcis par défaut, pages sur l'édition, le terminal, le débogage, le contrôle de code source et Copilot) et sur les fiches PDF officielles, relues le 6 novembre 2026. Pour la partie AZERTY, nous avons lu sur un PC Windows 11 la table de la disposition «&amp;nbsp;Français&amp;nbsp;» et les raccourcis par défaut contenus dans VS Code 1.107.1. Aucun raccourci n'a été testé à la main dans l'éditeur. Aucun lien n'est affilié.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un raccourci qui a changé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 6 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image d'en-tête&amp;nbsp;: qui nguyen via Unsplash (Unsplash License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>raccourcisclavier</category>
      <category>azerty</category>
      <category>productivite</category>
    </item>
    <item>
      <title>DevOps c'est quoi ? Définition, principes, métriques DORA et métier en 2026</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 15:54:42 +0000</pubDate>
      <link>https://dev.to/neurau_tech/devops-cest-quoi-definition-principes-metriques-dora-et-metier-en-2026-1ni2</link>
      <guid>https://dev.to/neurau_tech/devops-cest-quoi-definition-principes-metriques-dora-et-metier-en-2026-1ni2</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;DevOps c'est quoi&amp;nbsp;? C'est une façon de travailler qui réunit le développement (Dev) et l'exploitation (Ops) d'un logiciel autour d'un même objectif&amp;nbsp;: livrer souvent, sans casser la production. Ce n'est ni un outil, ni une équipe, mais une culture et des pratiques, soutenues par des outils.&lt;/p&gt;

&lt;p&gt;Ce guide s'adresse aux débutants, aux développeurs et aux managers. C'est une synthèse de sources publiques consultées le 6 novembre 2026, sans test de notre part.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le DevOps vise à abattre le «&amp;nbsp;mur&amp;nbsp;» entre ceux qui écrivent le code et ceux qui le font tourner. La première conférence devopsdays a lieu à Gand, en Belgique, en 2009.&lt;/li&gt;
&lt;li&gt;Deux grilles de lecture structurent la démarche&amp;nbsp;: CALMS (culture, automatisation, lean, mesure, partage) et les trois voies de Gene Kim (flux, rétroaction, apprentissage).&lt;/li&gt;
&lt;li&gt;DORA mesure aujourd'hui la livraison logicielle avec cinq métriques, et non plus quatre&amp;nbsp;: délai de mise en production, fréquence de déploiement, temps de rétablissement après un déploiement raté, taux d'échec des changements et taux de reprise des déploiements.&lt;/li&gt;
&lt;li&gt;Le SRE, le platform engineering et le DevSecOps ne remplacent pas le DevOps&amp;nbsp;: ce sont des façons de l'appliquer à la fiabilité, à l'outillage interne et à la sécurité.&lt;/li&gt;
&lt;li&gt;Côté salaire, le cabinet de recrutement Robert Half donne une médiane nationale de 73&amp;nbsp;000&amp;nbsp;€ fixes pour 2027, et le cabinet Silkhom 50 à 60&amp;nbsp;k€ bruts fixes pour un confirmé à Paris.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  DevOps c'est quoi : définition et origine
&lt;/h2&gt;

&lt;p&gt;DevOps est un mot-valise formé de &lt;em&gt;development&lt;/em&gt; et &lt;em&gt;operations&lt;/em&gt;. Il désigne la collaboration de ces deux métiers sur tout le cycle de vie d'une application, de l'idée à la production. Le livre de Google sur le SRE en résume les principes&amp;nbsp;: impliquer l'exploitation dans chaque phase de conception, préférer l'automatisation à l'effort humain et appliquer des pratiques d'ingénierie aux tâches d'exploitation (&lt;a href="https://sre.google/sre-book/introduction/" rel="noopener noreferrer"&gt;Site Reliability Engineering, Google&lt;/a&gt;, édition de 2016).&lt;/p&gt;

&lt;h3&gt;
  
  
  Le mur entre Dev et Ops
&lt;/h3&gt;

&lt;p&gt;Le problème de départ est organisationnel. Les développeurs sont jugés sur la vitesse à laquelle ils livrent, l'exploitation sur la stabilité. Atlassian décrit des objectifs séparés et souvent concurrents, des directions et des indicateurs séparés, parfois des bâtiments séparés (&lt;a href="https://www.atlassian.com/devops/what-is-devops/history-of-devops" rel="noopener noreferrer"&gt;Atlassian, histoire du DevOps&lt;/a&gt;, consulté le 6 novembre 2026).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scénario fictif, pour illustrer.&lt;/strong&gt; Une équipe livre une fois par mois, un vendredi soir&amp;nbsp;: trois cents changements partent ensemble, la production tombe, et personne ne sait lequel est en cause. La même équipe en mode DevOps aurait livré ces changements en petits déploiements automatisés, chacun testé par un pipeline&amp;nbsp;: celui qui casse est identifié en minutes et retiré seul. Ce scénario n'est pas un cas mesuré.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Patrick Debois et les devopsdays de 2009
&lt;/h3&gt;

&lt;p&gt;Patrick Debois, consultant belge, présente en 2008 à la conférence Agile de Toronto un exposé sur l'infrastructure et l'exploitation agiles. Sur &lt;a href="https://jedi.be/blog/2008/agile-2008-toronto-agile-infrastructure-and-operations-presentation/" rel="noopener noreferrer"&gt;son blog&lt;/a&gt; (9 octobre 2008), il raconte avoir rencontré des membres de Puppet qui ont proposé une session ouverte sur le sujet, et que personne d'autre que lui n'y est venu.&lt;/p&gt;

&lt;p&gt;En juin 2009, à la conférence Velocity, John Allspaw et Paul Hammond présentent «&amp;nbsp;10+ Deploys Per Day: Dev and Ops Cooperation at Flickr&amp;nbsp;», soit plus de dix déploiements par jour grâce à la coopération entre Dev et Ops chez Flickr (&lt;a href="https://www.kitchensoap.com/2009/06/23/slides-for-velocity-talk-2009/" rel="noopener noreferrer"&gt;blog de John Allspaw&lt;/a&gt;, 23 juin 2009). Debois a vu l'exposé à distance et dit qu'il a décidé, après, d'organiser une conférence (&lt;a href="https://www.infoq.com/news/2014/12/5-years-devops-days-qa/" rel="noopener noreferrer"&gt;interview sur InfoQ&lt;/a&gt;, décembre 2014).&lt;/p&gt;

&lt;p&gt;La première devopsdays se tient à Gand, en Belgique, en 2009, avec Patrick Debois comme fondateur (&lt;a href="https://devopsdays.org/about/" rel="noopener noreferrer"&gt;devopsdays.org&lt;/a&gt;, consulté le 6 novembre 2026).&lt;/p&gt;




&lt;h2&gt;
  
  
  Les principes : CALMS et les trois voies
&lt;/h2&gt;

&lt;p&gt;Deux cadres reviennent dans presque toutes les présentations sérieuses du DevOps. À notre sens, CALMS sert plutôt à évaluer une organisation, les trois voies à orienter les décisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  CALMS
&lt;/h3&gt;

&lt;p&gt;L'acronyme a deux étapes. John Willis écrit qu'il a forgé CAMS (culture, automatisation, mesure, partage) avec Damon Edwards après la première devopsdays américaine, à Mountain View en 2010, et que Jez Humble a ajouté plus tard le L de &lt;em&gt;Lean&lt;/em&gt; (&lt;a href="https://itrevolution.com/articles/devops-culture-part-1/" rel="noopener noreferrer"&gt;John Willis, IT Revolution&lt;/a&gt;, 1er mai 2012)&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lettre&lt;/th&gt;
&lt;th&gt;Principe&lt;/th&gt;
&lt;th&gt;En pratique&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Culture&lt;/td&gt;
&lt;td&gt;Responsabilité partagée de la production, pas de recherche de coupable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Automatisation&lt;/td&gt;
&lt;td&gt;Tests, builds, déploiements et infrastructure scriptés&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;Lean&lt;/td&gt;
&lt;td&gt;Petits lots, limitation du travail en cours, chasse au gaspillage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;Mesure&lt;/td&gt;
&lt;td&gt;Indicateurs de livraison et de fiabilité suivis dans le temps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;Partage (&lt;em&gt;Sharing&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;Connaissances, outils et retours d'incident accessibles à tous&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le &lt;a href="https://www.atlassian.com/devops/frameworks/calms-framework" rel="noopener noreferrer"&gt;guide CALMS d'Atlassian&lt;/a&gt; insiste&amp;nbsp;: toute l'automatisation du monde est inutile si développeurs et exploitants ne travaillent pas ensemble.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les trois voies
&lt;/h3&gt;

&lt;p&gt;Gene Kim a décrit en 2012 trois principes dont, selon lui, découlent toutes les pratiques DevOps, et qui structurent &lt;em&gt;The DevOps Handbook&lt;/em&gt; (&lt;a href="https://itrevolution.com/articles/the-three-ways-principles-underpinning-devops/" rel="noopener noreferrer"&gt;IT Revolution, Gene Kim&lt;/a&gt;, 22 août 2012)&amp;nbsp;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Le flux.&lt;/strong&gt; Optimiser le système entier plutôt qu'un service isolé, ne jamais transmettre un défaut connu à l'étape suivante.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La rétroaction.&lt;/strong&gt; Raccourcir et amplifier les boucles de retour, de la production vers le développement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L'expérimentation et l'apprentissage continus.&lt;/strong&gt; Prendre des risques mesurés, apprendre des échecs, et répéter pour maîtriser.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  La boucle DevOps en huit étapes
&lt;/h2&gt;

&lt;p&gt;Le cycle de vie DevOps se représente souvent comme une boucle en forme de huit couché, parcourue en continu. Les noms d'étapes varient selon les éditeurs, mais la version la plus courante en compte huit&amp;nbsp;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepv0913d5k6vep4lsaon.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepv0913d5k6vep4lsaon.webp" alt="Trois notes adhésives «&amp;nbsp;To Do&amp;nbsp;», «&amp;nbsp;Doing&amp;nbsp;» et «&amp;nbsp;Done&amp;nbsp;», les colonnes d'un tableau Kanban" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Étape&lt;/th&gt;
&lt;th&gt;Ce qu'on y fait&lt;/th&gt;
&lt;th&gt;Outils typiques&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Planifier&lt;/td&gt;
&lt;td&gt;Découper le travail en petites tâches&lt;/td&gt;
&lt;td&gt;Tableau Kanban, tickets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coder&lt;/td&gt;
&lt;td&gt;Écrire le code et le versionner&lt;/td&gt;
&lt;td&gt;Git, revue de code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Construire&lt;/td&gt;
&lt;td&gt;Compiler, empaqueter, créer l'image&lt;/td&gt;
&lt;td&gt;Docker, outils de build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tester&lt;/td&gt;
&lt;td&gt;Lancer les tests automatiques à chaque changement&lt;/td&gt;
&lt;td&gt;Frameworks de tests, CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publier&lt;/td&gt;
&lt;td&gt;Produire un artefact (le paquet ou l'image livrable) versionné&lt;/td&gt;
&lt;td&gt;Registre d'images, tags&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Déployer&lt;/td&gt;
&lt;td&gt;Mettre en production, souvent progressivement&lt;/td&gt;
&lt;td&gt;CD, Kubernetes, GitOps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exploiter&lt;/td&gt;
&lt;td&gt;Faire tourner, dimensionner, corriger&lt;/td&gt;
&lt;td&gt;Infrastructure as code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Surveiller&lt;/td&gt;
&lt;td&gt;Observer et réinjecter les retours dans la planification&lt;/td&gt;
&lt;td&gt;Logs, métriques, traces&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La dernière flèche fait du DevOps une boucle&amp;nbsp;: ce qu'on observe en production alimente la planification suivante. C'est la deuxième voie de Gene Kim appliquée au quotidien.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les pratiques et les outils
&lt;/h2&gt;

&lt;p&gt;Les outils changent, les pratiques restent. Voici les six blocs qu'on retrouve dans presque toutes les équipes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le contrôle de version.&lt;/strong&gt; Tout part de Git&amp;nbsp;: le code, mais aussi la configuration et l'infrastructure. Notre guide &lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub pour débutant&lt;/a&gt; va de la première commande à la pull request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'intégration et la livraison continues (CI/CD).&lt;/strong&gt; À chaque changement, un pipeline construit, teste et, si tout passe, déploie. Le principe est détaillé dans notre guide pour &lt;a href="https://neurautech.com/guide-complet-pour-automatiser-ses-deploiements/" rel="noopener noreferrer"&gt;automatiser ses déploiements&lt;/a&gt;, la pratique dans le &lt;a href="https://neurautech.com/github-actions-tutoriel/" rel="noopener noreferrer"&gt;tutoriel GitHub Actions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'infrastructure as code.&lt;/strong&gt; Serveurs, réseaux et bases se décrivent dans des fichiers versionnés. Terraform reste l'outil le plus connu. Le 10 août 2023, HashiCorp l'a fait passer de la licence MPL 2.0 à la Business Source License 1.1, une licence «&amp;nbsp;source disponible&amp;nbsp;» qui n'est pas open source au sens de l'OSI, créée par MariaDB, qui interdit les offres concurrentes de HashiCorp mais laisse les utilisateurs copier et modifier le code (&lt;a href="https://www.hashicorp.com/en/blog/hashicorp-adopts-business-source-license" rel="noopener noreferrer"&gt;annonce de HashiCorp&lt;/a&gt;). En réponse, plusieurs éditeurs ont créé OpenTofu, un fork (une copie indépendante du code), sous l'égide de la Linux Foundation et toujours sous MPL 2.0 (&lt;a href="https://opentofu.org/faq/" rel="noopener noreferrer"&gt;FAQ d'OpenTofu&lt;/a&gt;). Ansible, lui, sert surtout à configurer des machines existantes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les conteneurs et l'orchestration.&lt;/strong&gt; Un conteneur emporte l'application et ses dépendances. Commencez par &lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt;, puis &lt;a href="https://neurautech.com/kubernetes-pour-debutants-comprendre-lorchestration/" rel="noopener noreferrer"&gt;Kubernetes pour débutants&lt;/a&gt;. Notre comparatif &lt;a href="https://neurautech.com/kubernetes-vs-docker/" rel="noopener noreferrer"&gt;Kubernetes vs Docker&lt;/a&gt; aide à savoir quand un cluster se justifie.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'observabilité.&lt;/strong&gt; Le projet OpenTelemetry la définit comme la capacité à comprendre l'état interne d'un système par ses sorties&amp;nbsp;: traces, métriques et logs (&lt;a href="https://opentelemetry.io/docs/what-is-opentelemetry/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;, consulté le 6 novembre 2026). Il fournit des API open source, indépendantes du fournisseur, et envoie les données vers des outils comme Jaeger ou Prometheus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le GitOps.&lt;/strong&gt; Les principes OpenGitOps 1.0.0 en posent quatre&amp;nbsp;: un état souhaité déclaratif, versionné et immuable, tiré automatiquement par des agents logiciels et réconcilié en continu avec l'état réel (&lt;a href="https://opengitops.dev/" rel="noopener noreferrer"&gt;OpenGitOps&lt;/a&gt;). Exemple concret&amp;nbsp;: Argo CD tourne dans le cluster Kubernetes, compare en continu l'état réel à celui décrit dans un dépôt Git et applique lui-même les écarts (&lt;a href="https://argo-cd.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;documentation d'Argo CD&lt;/a&gt;). Le pipeline de CI ne pousse plus rien en production&amp;nbsp;: il modifie le dépôt, et l'agent tire le changement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mesurer les résultats : les métriques DORA
&lt;/h2&gt;

&lt;p&gt;Pour savoir si une démarche DevOps fonctionne, la référence est DORA (DevOps Research and Assessment). D'abord une société indépendante fondée notamment par Nicole Forsgren, Jez Humble et Gene Kim, auteurs du livre &lt;em&gt;Accelerate&lt;/em&gt;, DORA a été rachetée par Google en décembre 2018 et est aujourd'hui un programme de recherche de Google Cloud (&lt;a href="https://dora.dev/news/dora-joins-google-cloud/" rel="noopener noreferrer"&gt;annonce de DORA&lt;/a&gt;, 20 décembre 2018). Son guide, mis à jour le 5 janvier 2026, liste &lt;strong&gt;cinq&lt;/strong&gt; métriques de livraison logicielle (&lt;a href="https://dora.dev/guides/dora-metrics/" rel="noopener noreferrer"&gt;guide des métriques DORA&lt;/a&gt;, consulté le 6 novembre 2026)&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Famille&lt;/th&gt;
&lt;th&gt;Métrique DORA&lt;/th&gt;
&lt;th&gt;Ce qu'elle mesure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Débit&lt;/td&gt;
&lt;td&gt;Délai de mise en production des changements&lt;/td&gt;
&lt;td&gt;Temps entre le commit et le déploiement en production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Débit&lt;/td&gt;
&lt;td&gt;Fréquence de déploiement&lt;/td&gt;
&lt;td&gt;Nombre de déploiements sur une période&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Débit&lt;/td&gt;
&lt;td&gt;Temps de rétablissement après un déploiement raté&lt;/td&gt;
&lt;td&gt;Temps pour se remettre d'un déploiement qui exige une intervention immédiate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instabilité&lt;/td&gt;
&lt;td&gt;Taux d'échec des changements&lt;/td&gt;
&lt;td&gt;Part des déploiements suivis d'un retour arrière ou d'un correctif urgent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instabilité&lt;/td&gt;
&lt;td&gt;Taux de reprise des déploiements&lt;/td&gt;
&lt;td&gt;Part des déploiements non planifiés, causés par un incident en production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quatre clés devenues cinq
&lt;/h3&gt;

&lt;p&gt;Beaucoup d'articles parlent encore des «&amp;nbsp;quatre métriques DORA&amp;nbsp;». C'est daté. L'historique de DORA retrace l'évolution&amp;nbsp;: quatre variables en 2014, le remplacement du temps moyen de rétablissement (MTTR) par le temps de rétablissement après un déploiement raté en 2023, puis une cinquième métrique, le taux de reprise des déploiements, en 2024 (&lt;a href="https://dora.dev/insights/dora-metrics-history/" rel="noopener noreferrer"&gt;historique des métriques DORA&lt;/a&gt;, consulté le 6 novembre 2026).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2jlfl3s04c01wjim8ex.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2jlfl3s04c01wjim8ex.webp" alt="DevOps c'est quoi en chiffres&amp;nbsp;: chronologie des métriques de livraison DORA, de quatre variables en 2014 à cinq métriques depuis 2024, avec la fiabilité suivie à part" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La fiabilité est à part. Ajoutée en 2018 sous le nom de disponibilité, élargie à la fiabilité en 2021, elle relève selon DORA de la performance opérationnelle, pas de la livraison&amp;nbsp;: la même page reconnaît que le rapport 2021 l'a à tort appelée «&amp;nbsp;cinquième métrique&amp;nbsp;». Le changement de 2023 compte aussi&amp;nbsp;: la nouvelle métrique ne retient que les échecs causés par un changement logiciel, pas les pannes externes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ce que dit le rapport le plus récent
&lt;/h3&gt;

&lt;p&gt;Le dernier rapport listé sur &lt;a href="https://dora.dev/research/" rel="noopener noreferrer"&gt;dora.dev&lt;/a&gt; au 6 novembre 2026 est celui de 2025, consacré au développement assisté par l'IA. Google indique avoir interrogé près de 5&amp;nbsp;000 professionnels de la technologie dans le monde (&lt;a href="https://blog.google/innovation-and-ai/technology/developers-tools/dora-report-2025/" rel="noopener noreferrer"&gt;blog de Google&lt;/a&gt;, 23 septembre 2025). L'usage de l'IA y atteint 90&amp;nbsp;%, «&amp;nbsp;en hausse de 14&amp;nbsp;%&amp;nbsp;» sur un an selon les termes de Google, qui ne précise pas s'il s'agit de points.&lt;/p&gt;

&lt;p&gt;Sa conclusion, telle que la résume DORA&amp;nbsp;: l'IA agit comme un amplificateur, et les meilleurs résultats viennent du système sociotechnique, c'est-à-dire de l'organisation des équipes autant que des outils.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Attention à l'homonyme.&lt;/strong&gt; En France, «&amp;nbsp;DORA&amp;nbsp;» désigne aussi le règlement européen sur la résilience opérationnelle numérique du secteur financier, sans lien avec les métriques DevOps.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  DevOps, SRE, platform engineering et DevSecOps
&lt;/h2&gt;

&lt;p&gt;Ces quatre termes se recouvrent&amp;nbsp;: les trois derniers sont des façons d'appliquer le DevOps à un problème précis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le SRE (Site Reliability Engineering)&lt;/strong&gt; est né chez Google, où Benjamin Treynor Sloss a pris en 2003 la tête de l'équipe qui en est l'origine. Il le définit comme ce qui arrive quand on demande à un ingénieur logiciel de concevoir une équipe d'exploitation. Google plafonne à 50&amp;nbsp;% la part de travail d'exploitation de ses SRE pour garder du temps pour l'automatisation (&lt;a href="https://sre.google/sre-book/introduction/" rel="noopener noreferrer"&gt;livre SRE de Google&lt;/a&gt;). Le second livre résume la relation en une ligne&amp;nbsp;: «&amp;nbsp;class SRE implements interface DevOps&amp;nbsp;» (&lt;a href="https://sre.google/workbook/how-sre-relates/" rel="noopener noreferrer"&gt;The Site Reliability Workbook&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le platform engineering&lt;/strong&gt; construit une plateforme interne en libre-service, pour que chaque équipe produit n'ait pas à réinventer son pipeline. Le livre blanc du TAG App Delivery de la CNCF explique que l'équipe plateforme réduit le travail commun et intègre la gouvernance dans ses modèles (&lt;a href="https://tag-app-delivery.cncf.io/whitepapers/platforms/" rel="noopener noreferrer"&gt;CNCF, livre blanc sur les plateformes&lt;/a&gt;, consulté le 6 novembre 2026). Le bilan de DORA est nuancé&amp;nbsp;: selon le &lt;a href="https://dora.dev/research/2024/dora-report/" rel="noopener noreferrer"&gt;rapport 2024&lt;/a&gt;, une plateforme interne améliore la productivité individuelle, la performance des équipes et celle de l'organisation, mais peut aussi réduire le débit et la stabilité des changements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le DevSecOps&lt;/strong&gt; intègre la sécurité à chaque étape du pipeline. Le guide DevSecOps de l'OWASP vise à introduire des contrôles de sécurité sans ralentir la livraison, avec une culture «&amp;nbsp;shift-left&amp;nbsp;», la sécurité traitée dès le début du cycle (&lt;a href="https://owasp.org/projects/devsecops-guideline" rel="noopener noreferrer"&gt;OWASP DevSecOps Guideline&lt;/a&gt;, consulté le 6 novembre 2026). Silkhom y associe des missions concrètes&amp;nbsp;: scans de vulnérabilités automatisés dans la CI/CD, audit du cloud, réponse aux incidents.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approche&lt;/th&gt;
&lt;th&gt;Question centrale&lt;/th&gt;
&lt;th&gt;Indicateur typique&lt;/th&gt;
&lt;th&gt;Livrable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DevOps&lt;/td&gt;
&lt;td&gt;Comment livrer souvent et sans casse&amp;nbsp;?&lt;/td&gt;
&lt;td&gt;Métriques DORA&lt;/td&gt;
&lt;td&gt;Culture et pipeline partagés&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SRE&lt;/td&gt;
&lt;td&gt;Quel niveau de fiabilité viser&amp;nbsp;?&lt;/td&gt;
&lt;td&gt;Objectifs de niveau de service et budget d'erreur&lt;/td&gt;
&lt;td&gt;Service fiable, tâches manuelles réduites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform engineering&lt;/td&gt;
&lt;td&gt;Comment éviter que chaque équipe refasse tout&amp;nbsp;?&lt;/td&gt;
&lt;td&gt;Adoption de la plateforme&lt;/td&gt;
&lt;td&gt;Plateforme interne en libre-service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevSecOps&lt;/td&gt;
&lt;td&gt;Comment sécuriser sans ralentir&amp;nbsp;?&lt;/td&gt;
&lt;td&gt;Vulnérabilités détectées avant la production&lt;/td&gt;
&lt;td&gt;Contrôles de sécurité automatisés&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pour la sécurité au sens large, notre guide des &lt;a href="https://neurautech.com/metiers-de-la-cybersecurite/" rel="noopener noreferrer"&gt;métiers de la cybersécurité&lt;/a&gt; détaille neuf postes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le métier d'ingénieur DevOps
&lt;/h2&gt;

&lt;p&gt;Paradoxe&amp;nbsp;: le DevOps n'est pas un poste, mais le marché recrute des ingénieurs DevOps. Ce sont des profils qui construisent les pipelines, l'infrastructure et l'observabilité, et aident les développeurs à s'en servir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Missions et compétences
&lt;/h3&gt;

&lt;p&gt;Silkhom liste comme missions la réduction des interventions humaines pour accélérer les livraisons, l'automatisation complète de la mise en production et la qualité à chaque étape. Compétences citées&amp;nbsp;: Linux et Windows, Shell, Python, Bash, PowerShell, Jenkins, Ansible, Kubernetes, AWS et Azure (&lt;a href="https://www.silkhom.com/les-salaires-informatique-et-electronique/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;). Ajoutez-y Git, Docker et un outil d'infrastructure as code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Salaire : deux cabinets, deux méthodes
&lt;/h3&gt;

&lt;p&gt;Les chiffres viennent de cabinets de recrutement et ne mesurent pas la même chose. Robert Half donne une fourchette nationale pour l'ingénieur DevOps en 2027, en percentiles (le 25e percentile est le montant sous lequel se situe un quart des salaires)&amp;nbsp;: 61&amp;nbsp;000&amp;nbsp;€ au 25e, 73&amp;nbsp;000&amp;nbsp;€ à la médiane, 81&amp;nbsp;000&amp;nbsp;€ au 75e (&lt;a href="https://www.roberthalf.com/fr/fr/details-emploi/ingenieur-devops" rel="noopener noreferrer"&gt;Robert Half&lt;/a&gt;, consulté le 6 novembre 2026). Son &lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires" rel="noopener noreferrer"&gt;guide des salaires&lt;/a&gt; précise qu'il s'agit de salaires fixes, hors primes et avantages&amp;nbsp;; il ne dit pas s'ils sont bruts.&lt;/p&gt;

&lt;p&gt;Silkhom donne des fourchettes en brut annuel fixe, tirées selon le cabinet des données de plus de 25&amp;nbsp;000 candidats entre 2019 et 2026. À Paris&amp;nbsp;: 45 à 50&amp;nbsp;k€ en junior (0 à 2&amp;nbsp;ans), 50 à 60&amp;nbsp;k€ en confirmé (2 à 5&amp;nbsp;ans), 60 à 80&amp;nbsp;k€ en senior. Dans les grandes villes et en région&amp;nbsp;: 38 à 45, 45 à 55 et 55 à 65&amp;nbsp;k€ (&lt;a href="https://www.silkhom.com/les-salaires-informatique-et-electronique/" rel="noopener noreferrer"&gt;Silkhom, Salaires informatique 2026&lt;/a&gt;, consulté le 6 novembre 2026).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1dgje1293vcrzl0vrqyg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1dgje1293vcrzl0vrqyg.webp" alt="Graphique en barres de fourchettes&amp;nbsp;: salaires de l'ingénieur DevOps selon Silkhom à Paris et en région et selon Robert Half au niveau national" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La médiane nationale de Robert Half dépasse le haut de la fourchette confirmée de Silkhom à Paris&amp;nbsp;: les méthodes diffèrent trop pour trancher. Notre &lt;a href="https://neurautech.com/salaires-developpeurs-france-2026-grille-complete/" rel="noopener noreferrer"&gt;comparatif des salaires des développeurs&lt;/a&gt; confronte six sources, dont l'Apec.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comment y arriver
&lt;/h3&gt;

&lt;p&gt;Deux portes d'entrée mènent au poste d'ingénieur DevOps. Un développeur back-end qui maîtrise Git et les tests ajoute la CI/CD, Docker, puis le cloud. Un administrateur système qui maîtrise Linux et le réseau ajoute le code, l'infrastructure as code et les pipelines. Dans les deux cas, un projet personnel déployé de bout en bout pèse plus qu'une liste d'outils. Notre guide des &lt;a href="https://neurautech.com/meilleures-certifications-cloud-aws-azure-gcp-guide/" rel="noopener noreferrer"&gt;certifications cloud&lt;/a&gt; aide à structurer l'apprentissage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cinq idées reçues sur le DevOps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;«&amp;nbsp;Le DevOps, c'est une équipe.&amp;nbsp;»&lt;/strong&gt; Placer une «&amp;nbsp;équipe DevOps&amp;nbsp;» entre Dev et Ops recrée un silo&amp;nbsp;: c'est l'anti-modèle «&amp;nbsp;DevOps Team Silo&amp;nbsp;» décrit par Matthew Skelton et Manuel Pais (&lt;a href="https://web.devopstopologies.com/" rel="noopener noreferrer"&gt;DevOps Topologies&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;«&amp;nbsp;Le DevOps, c'est un outil.&amp;nbsp;»&lt;/strong&gt; Jenkins, GitHub Actions ou Kubernetes servent la démarche, ils ne la remplacent pas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;«&amp;nbsp;Le DevOps, c'est pour les géants du web.&amp;nbsp;»&lt;/strong&gt; Une petite équipe avec un pipeline, des tests et un déploiement automatisé applique déjà l'essentiel. Au fond, le DevOps, ce sont des boucles courtes, à n'importe quelle échelle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;«&amp;nbsp;Plus vite, c'est moins stable.&amp;nbsp;»&lt;/strong&gt; Les métriques DORA mesurent débit et instabilité ensemble pour ne pas sacrifier l'un à l'autre.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;«&amp;nbsp;DevOps et agile, c'est pareil.&amp;nbsp;»&lt;/strong&gt; L'agile a rapproché le métier et le développement&amp;nbsp;; le DevOps prolonge ce rapprochement jusqu'à l'exploitation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Par où commencer : une feuille de route
&lt;/h2&gt;

&lt;p&gt;Plutôt que de répéter nos tutoriels, voici l'ordre dans lequel les suivre&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Étape&lt;/th&gt;
&lt;th&gt;À apprendre&lt;/th&gt;
&lt;th&gt;Notre tutoriel&lt;/th&gt;
&lt;th&gt;Objectif&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Le terminal Linux&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/commandes-linux-de-base/" rel="noopener noreferrer"&gt;Commandes Linux de base&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Se connecter à un serveur et lire des logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Git et GitHub&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub pour débutant&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Travailler par branches et pull requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Conteneuriser une petite API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/github-actions-tutoriel/" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tester et publier à chaque push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Mise en production&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/nginx-reverse-proxy-docker-compose/" rel="noopener noreferrer"&gt;Nginx et Docker Compose&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Servir l'API en HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/hebergement-cloud-pour-developpeurs/" rel="noopener noreferrer"&gt;Hébergement cloud pour développeurs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Choisir où héberger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;&lt;a href="https://neurautech.com/kubernetes-pour-debutants-comprendre-lorchestration/" rel="noopener noreferrer"&gt;Kubernetes pour débutants&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Comprendre pods, services et déploiements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ajoutez ensuite Terraform ou OpenTofu, et OpenTelemetry sur votre projet. Puis mesurez votre fréquence de déploiement&amp;nbsp;: c'est la plus simple des métriques DORA à mesurer pour commencer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Glossaire DevOps
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Terme&lt;/th&gt;
&lt;th&gt;Définition courte&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CI (intégration continue)&lt;/td&gt;
&lt;td&gt;Fusionner et tester automatiquement chaque changement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CD (livraison ou déploiement continu)&lt;/td&gt;
&lt;td&gt;Rendre chaque version prête à partir en production, ou l'y envoyer automatiquement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline&lt;/td&gt;
&lt;td&gt;Suite d'étapes automatisées entre le commit et la production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artefact&lt;/td&gt;
&lt;td&gt;Paquet ou image produit par le build, celui qu'on déploie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure as code (IaC)&lt;/td&gt;
&lt;td&gt;Infrastructure décrite dans des fichiers versionnés&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fork&lt;/td&gt;
&lt;td&gt;Copie indépendante d'un projet open source, qui évolue de son côté&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestrateur&lt;/td&gt;
&lt;td&gt;Outil qui place, redémarre et dimensionne les conteneurs, comme Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observabilité&lt;/td&gt;
&lt;td&gt;Comprendre un système par ses logs, métriques et traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitOps&lt;/td&gt;
&lt;td&gt;Déploiement piloté par l'état décrit dans Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLO&lt;/td&gt;
&lt;td&gt;Objectif de niveau de service, par exemple un taux de disponibilité&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Budget d'erreur&lt;/td&gt;
&lt;td&gt;Marge d'indisponibilité tolérée par le SLO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toil&lt;/td&gt;
&lt;td&gt;Travail d'exploitation manuel et répétitif, à automatiser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Percentile&lt;/td&gt;
&lt;td&gt;Seuil sous lequel se situe une part donnée des valeurs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Post-mortem&lt;/td&gt;
&lt;td&gt;Analyse d'incident sans recherche de coupable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Qui a inventé le mot.&lt;/strong&gt; Des sources secondaires l'attribuent à Patrick Debois, parfois avec Andrew Clay Shafer. Le billet de Debois que nous citons ne nomme pas Shafer, et nous n'avons pas trouvé de source primaire qui tranche.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La date exacte de la première devopsdays.&lt;/strong&gt; Le site officiel donne l'année et la ville, pas le jour. Le lieu exact de Velocity 2009 n'est pas indiqué dans les sources lues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le détail des rapports DORA 2024 et 2025.&lt;/strong&gt; Nous avons lu les pages de DORA et la présentation de Google, pas les rapports complets. Aucun rapport DORA 2026 n'était publié au 6 novembre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La méthode des cabinets.&lt;/strong&gt; Robert Half ne dit pas si ses montants sont bruts ni combien de profils il observe. Leurs chiffres sont des repères.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Un ingénieur DevOps, c'est quoi exactement ?
&lt;/h3&gt;

&lt;p&gt;C'est un ingénieur qui automatise la construction, les tests, le déploiement et la surveillance des applications, et qui gère l'infrastructure sous forme de code. Selon &lt;a href="https://www.silkhom.com/les-salaires-informatique-et-electronique/" rel="noopener noreferrer"&gt;Silkhom&lt;/a&gt;, sa mission est de réduire les interventions humaines pour accélérer les livraisons. Ingénieur plateforme, ingénieur cloud ou SRE&amp;nbsp;: ces postes recouvrent des missions proches.&lt;/p&gt;

&lt;h3&gt;
  
  
  DevOps et SRE, c'est quoi la différence ?
&lt;/h3&gt;

&lt;p&gt;Le DevOps est une démarche générale, le SRE une façon précise de l'appliquer, née chez Google, centrée sur la fiabilité mesurée par des objectifs de niveau de service et des budgets d'erreur. Le &lt;a href="https://sre.google/workbook/how-sre-relates/" rel="noopener noreferrer"&gt;livre de Google&lt;/a&gt; le résume par «&amp;nbsp;class SRE implements interface DevOps&amp;nbsp;».&lt;/p&gt;

&lt;h3&gt;
  
  
  Le DevOps cloud, c'est quoi ?
&lt;/h3&gt;

&lt;p&gt;C'est l'application des pratiques DevOps à une infrastructure louée chez un fournisseur cloud&amp;nbsp;: ressources créées par code, déploiements automatisés, facturation à l'usage. Le cloud facilite le DevOps sans être obligatoire. Notre comparatif &lt;a href="https://neurautech.com/aws-vs-azure-vs-google-cloud-prix-services-usage/" rel="noopener noreferrer"&gt;AWS, Azure et Google Cloud&lt;/a&gt; aide à choisir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faut-il savoir coder pour faire du DevOps ?
&lt;/h3&gt;

&lt;p&gt;Oui, au moins des scripts&amp;nbsp;: pipelines CI/CD, infrastructure as code et automatisation sont du code. Silkhom cite Shell, Python, Bash et PowerShell parmi les compétences attendues. Pas besoin d'être développeur senior, mais il faut lire, écrire et versionner du code chaque jour.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse fondée exclusivement sur des sources publiques consultées le 6 novembre 2026&amp;nbsp;: pages de DORA et de Google, livres SRE de Google, textes de Patrick Debois, John Allspaw, John Willis et Gene Kim, documentation d'OWASP, de la CNCF, d'OpenTelemetry, d'OpenGitOps, d'Argo CD, d'OpenTofu et de HashiCorp, grilles de salaires de Robert Half et de Silkhom. Les chiffres des cabinets de recrutement sont signalés comme tels. Les citations en anglais sont traduites par nos soins. Aucun test n'a été mené, aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur aux éditeurs mentionnés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un chiffre périmé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 6 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Images&amp;nbsp;: airfocus et Eden Constantino (Unsplash License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>sre</category>
      <category>dora</category>
    </item>
    <item>
      <title>HTML CSS débutant : le cours pas à pas, un mini-projet et 8 exercices corrigés</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 10:23:40 +0000</pubDate>
      <link>https://dev.to/neurau_tech/html-css-debutant-le-cours-pas-a-pas-un-mini-projet-et-8-exercices-corriges-10a</link>
      <guid>https://dev.to/neurau_tech/html-css-debutant-le-cours-pas-a-pas-un-mini-projet-et-8-exercices-corriges-10a</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Ce cours HTML CSS débutant part de zéro et va jusqu'à une page publiée&amp;nbsp;: structure, mise en forme, Flexbox, Grid, responsive, accessibilité et validation, puis huit exercices corrigés et un plan de quatre semaines.&lt;/p&gt;

&lt;p&gt;HTML et CSS restent un passage obligé. Dans l'enquête 2026 de Stack Overflow, 58,2&amp;nbsp;% des 14&amp;nbsp;099 répondants disent avoir beaucoup développé avec HTML/CSS au cours de l'année écoulée, juste derrière JavaScript (62,0&amp;nbsp;%) et SQL (58,4&amp;nbsp;%), et devant Python (58,0&amp;nbsp;%) et TypeScript (43,8&amp;nbsp;%) (&lt;a href="https://survey.stackoverflow.co/2026/technology/data/languages" rel="noopener noreferrer"&gt;Stack Overflow Developer Survey 2026&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML décrit le contenu, CSS son apparence. Quelques jours de HTML sémantique d'abord, puis les deux ensemble.&lt;/li&gt;
&lt;li&gt;Deux outils gratuits suffisent&amp;nbsp;: Visual Studio Code et les DevTools du navigateur.&lt;/li&gt;
&lt;li&gt;Flexbox aligne sur un axe, Grid sur deux. Une media query adapte la page aux petits écrans.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:has()&lt;/code&gt;, l'imbrication CSS et les container queries sont «&amp;nbsp;Baseline Widely available&amp;nbsp;» selon MDN.&lt;/li&gt;
&lt;li&gt;Le mini-projet est passé sans erreur aux validateurs HTML et CSS du W3C le 5 novembre 2026.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbwc0w9hfoy16pobs9qy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbwc0w9hfoy16pobs9qy.webp" alt="Graphique en barres&amp;nbsp;: langages les plus pratiqués selon l'enquête Stack Overflow 2026, JavaScript 62,0&amp;nbsp;%, SQL 58,4&amp;nbsp;%, HTML/CSS 58,2&amp;nbsp;%, Python 58,0&amp;nbsp;%, TypeScript 43,8&amp;nbsp;%" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML et CSS : qui fait quoi
&lt;/h2&gt;

&lt;p&gt;HTML structure le contenu, CSS le met en forme. Le parcours de MDN, la documentation web de Mozilla, les enseigne dans cet ordre&amp;nbsp;: «&amp;nbsp;Structurer le contenu avec HTML&amp;nbsp;», puis «&amp;nbsp;Bases de la mise en forme CSS&amp;nbsp;» (&lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core" rel="noopener noreferrer"&gt;MDN, modules fondamentaux&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;HTML&lt;/th&gt;
&lt;th&gt;CSS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rôle&lt;/td&gt;
&lt;td&gt;Dire ce qu'est chaque contenu&amp;nbsp;: titre, paragraphe, lien, formulaire&lt;/td&gt;
&lt;td&gt;Dire à quoi il ressemble&amp;nbsp;: couleurs, tailles, espacements, disposition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unité de base&lt;/td&gt;
&lt;td&gt;La balise, par exemple &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; ou &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;La règle&amp;nbsp;: un sélecteur et des déclarations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fichier&lt;/td&gt;
&lt;td&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;style.css&lt;/code&gt;, relié par &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;JavaScript ajoute ensuite le comportement&amp;nbsp;; c'est la suite logique, détaillée dans notre guide pour &lt;a href="https://neurautech.com/apprendre-javascript/" rel="noopener noreferrer"&gt;apprendre JavaScript&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les outils : VS Code et les DevTools
&lt;/h2&gt;

&lt;p&gt;Un éditeur de code et un navigateur suffisent. Visual Studio Code est «&amp;nbsp;gratuit pour un usage privé ou commercial&amp;nbsp;», selon sa FAQ, qui précise qu'il est «&amp;nbsp;construit&amp;nbsp;» sur le code open source Code - OSS (licence MIT) mais distribué sous licence Microsoft (notre traduction) (&lt;a href="https://code.visualstudio.com/docs/supporting/faq" rel="noopener noreferrer"&gt;FAQ de VS Code&lt;/a&gt;, consultée le 5 novembre 2026). Trois réglages utiles&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le raccourci Emmet.&lt;/strong&gt; Tapez &lt;code&gt;!&lt;/code&gt; puis Tab dans un fichier &lt;code&gt;.html&lt;/code&gt; vide&amp;nbsp;: VS Code écrit le squelette de la page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Une extension d'aperçu.&lt;/strong&gt; Un serveur local recharge la page à chaque sauvegarde&amp;nbsp;; notre sélection d'&lt;a href="https://neurautech.com/meilleures-extensions-vs-code-en-2026-pour-devs/" rel="noopener noreferrer"&gt;extensions VS Code&lt;/a&gt; en compare plusieurs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le formatage automatique.&lt;/strong&gt; «&amp;nbsp;Format On Save&amp;nbsp;» garde une indentation propre.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les DevTools sont l'autre moitié de l'outillage. Dans Chrome, Ctrl + Maj + C sous Windows et Linux, ou Cmd + Option + C sur Mac, ouvre le panneau Elements en mode inspection&amp;nbsp;; un clic droit puis «&amp;nbsp;Inspecter&amp;nbsp;» fait la même chose (&lt;a href="https://developer.chrome.com/docs/devtools/open" rel="noopener noreferrer"&gt;Chrome for Developers&lt;/a&gt;, consulté le 5 novembre 2026). Vous y voyez le HTML réel, les règles appliquées, celles qui sont barrées et le schéma du modèle de boîte.&lt;/p&gt;




&lt;h2&gt;
  
  
  La structure d'une page HTML
&lt;/h2&gt;

&lt;p&gt;Toute page commence par le même squelette. Voici la version minimale que nous avons fait passer au validateur du W3C&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Ma première page&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Navigation principale"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#apropos"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;À propos&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"apropos"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Bonjour&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Ma première page en HTML et CSS.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Contact : moi@example.com&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt; active le mode standard, &lt;code&gt;lang="fr"&lt;/code&gt; annonce la langue aux lecteurs d'écran, &lt;code&gt;charset&lt;/code&gt; évite les accents cassés, et la balise viewport cale la page sur la largeur de l'écran. Sans elle, un mobile peut rendre la page dans une fenêtre virtuelle plus large, 980 pixels dans l'exemple de &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/name/viewport" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;, puis la réduire&amp;nbsp;: vos media queries pour petit écran ne se déclenchent pas.&lt;/p&gt;

&lt;p&gt;Les balises sémantiques décrivent le rôle de chaque zone&amp;nbsp;: &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; (en-tête), &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; (navigation), &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; (contenu principal, un seul par page), &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; (partie thématique avec titre), &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; (contenu autonome) et &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; (pied de page). Un &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; ne dit rien de son contenu&amp;nbsp;: gardez-le pour la mise en forme.&lt;/p&gt;




&lt;h2&gt;
  
  
  Texte, liens, images, listes, tableaux et formulaires
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Les titres et le texte.&lt;/strong&gt; &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; à &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; forment un plan, sans sauter de niveau. &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; crée un paragraphe, &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; marque une importance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les liens.&lt;/strong&gt; &lt;code&gt;&amp;lt;a href="#contact"&amp;gt;&lt;/code&gt; pointe vers une ancre de la page, une adresse complète vers une autre page. Le texte du lien doit avoir un sens seul&amp;nbsp;: jamais «&amp;nbsp;cliquez ici&amp;nbsp;».&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les images.&lt;/strong&gt; &lt;code&gt;alt&lt;/code&gt; décrit l'image pour qui ne la voit pas&amp;nbsp;; une image décorative reçoit &lt;code&gt;alt=""&lt;/code&gt;. &lt;code&gt;width&lt;/code&gt; et &lt;code&gt;height&lt;/code&gt; évitent que la page saute au chargement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les listes.&lt;/strong&gt; &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; à puces, &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; ordonnée, chaque élément dans un &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les tableaux.&lt;/strong&gt; Pour des données, jamais pour la mise en page. &lt;code&gt;&amp;lt;caption&amp;gt;&lt;/code&gt; donne le titre, &lt;code&gt;&amp;lt;th scope="col"&amp;gt;&lt;/code&gt; les en-têtes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les formulaires.&lt;/strong&gt; Chaque champ a un &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; relié par &lt;code&gt;for&lt;/code&gt; et &lt;code&gt;id&lt;/code&gt;. Le bon &lt;code&gt;type&lt;/code&gt; (&lt;code&gt;email&lt;/code&gt;, &lt;code&gt;tel&lt;/code&gt;) affiche le bon clavier sur mobile&amp;nbsp;; &lt;code&gt;required&lt;/code&gt; bloque un envoi vide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/inscription"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"courriel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;E-mail (obligatoire)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"courriel"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"courriel"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;S'inscrire&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Les bases de CSS : sélecteurs, cascade et spécificité
&lt;/h2&gt;

&lt;p&gt;Une règle CSS associe un sélecteur à des déclarations. Le sélecteur choisit les éléments, chaque déclaration fixe une propriété&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#1f2937&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les sélecteurs de base&amp;nbsp;: la balise (&lt;code&gt;p&lt;/code&gt;), la classe (&lt;code&gt;.carte&lt;/code&gt;), l'identifiant (&lt;code&gt;#contact&lt;/code&gt;), le descendant (&lt;code&gt;nav a&lt;/code&gt;) et les pseudo-classes comme &lt;code&gt;:hover&lt;/code&gt;. Préférez les classes&amp;nbsp;: elles se réutilisent.&lt;/p&gt;

&lt;p&gt;Quand deux règles visent le même élément, la cascade tranche. MDN la résume en trois critères, du moins fort au plus fort&amp;nbsp;: l'ordre dans le code (à égalité, la dernière règle gagne), la spécificité, puis &lt;code&gt;!important&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts" rel="noopener noreferrer"&gt;MDN, gestion des conflits&lt;/a&gt;, page modifiée le 6 octobre 2026, consultée le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;La spécificité se lit en trois colonnes&amp;nbsp;: identifiants, classes (avec attributs et pseudo-classes), éléments. Les colonnes se comparent de gauche à droite, et un seul identifiant bat n'importe quel nombre de classes, d'après la même page.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sélecteur&lt;/th&gt;
&lt;th&gt;Identifiants&lt;/th&gt;
&lt;th&gt;Classes&lt;/th&gt;
&lt;th&gt;Éléments&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0-0-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.menu a:hover&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0-2-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#menu a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1-0-1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le panneau Styles des DevTools barre les règles perdantes&amp;nbsp;: c'est le moyen le plus rapide de comprendre pourquoi une couleur ne s'applique pas. Évitez &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modèle de boîte, unités, couleurs et polices
&lt;/h2&gt;

&lt;p&gt;Chaque élément est une boîte&amp;nbsp;: contenu, &lt;code&gt;padding&lt;/code&gt; (marge intérieure), &lt;code&gt;border&lt;/code&gt;, puis &lt;code&gt;margin&lt;/code&gt; (marge extérieure). Par défaut, &lt;code&gt;width&lt;/code&gt; ne compte que le contenu&amp;nbsp;; avec &lt;code&gt;box-sizing: border-box&lt;/code&gt;, elle inclut padding et bordure, ce qui rend les calculs prévisibles.&lt;/p&gt;

&lt;p&gt;Les unités changent le comportement de la page&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unité&lt;/th&gt;
&lt;th&gt;Relative à&lt;/th&gt;
&lt;th&gt;Usage typique&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rien, valeur fixe&lt;/td&gt;
&lt;td&gt;Bordures fines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Taille de police de la racine (&lt;code&gt;html&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Tailles de texte, espacements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dimension du parent&lt;/td&gt;
&lt;td&gt;Largeurs fluides&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;vw&lt;/code&gt;, &lt;code&gt;vh&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;% de la largeur, de la hauteur de la fenêtre&lt;/td&gt;
&lt;td&gt;Titres fluides, toujours combinés à &lt;code&gt;rem&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Utilisez &lt;code&gt;rem&lt;/code&gt; pour le texte&amp;nbsp;: si le lecteur agrandit sa police, la page suit. N'écrivez jamais une taille de texte en &lt;code&gt;vw&lt;/code&gt; seul&amp;nbsp;: elle ne grossit pas avec le zoom, alors que le critère WCAG 1.4.4 demande un texte agrandissable jusqu'à 200&amp;nbsp;%. &lt;code&gt;clamp(1.75rem, 4vw, 2.5rem)&lt;/code&gt; combine un minimum en &lt;code&gt;rem&lt;/code&gt;, une valeur fluide et un maximum.&lt;/p&gt;

&lt;p&gt;Pour les couleurs, l'hexadécimal (&lt;code&gt;#1d4ed8&lt;/code&gt;) suffit&amp;nbsp;; rangez-les dans des variables (&lt;code&gt;--accent&lt;/code&gt; dans &lt;code&gt;:root&lt;/code&gt;, puis &lt;code&gt;var(--accent)&lt;/code&gt;). Pour les polices, &lt;code&gt;font-family: system-ui, sans-serif&lt;/code&gt; utilise la police du système, sans téléchargement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Flexbox et Grid : la mise en page
&lt;/h2&gt;

&lt;p&gt;Flexbox aligne des éléments sur un axe, Grid les place sur deux. Une barre de navigation est un cas typique de Flexbox&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;justify-content&lt;/code&gt; répartit sur l'axe principal, &lt;code&gt;align-items&lt;/code&gt; aligne sur l'axe secondaire, &lt;code&gt;gap&lt;/code&gt; fixe l'espacement. &lt;code&gt;flex-wrap: wrap&lt;/code&gt; autorise le retour à la ligne.&lt;/p&gt;

&lt;p&gt;Une grille de cartes est un cas typique de Grid&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cartes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L'unité &lt;code&gt;fr&lt;/code&gt; partage l'espace libre, mais une colonne &lt;code&gt;1fr&lt;/code&gt; ne descend pas sous la largeur de son contenu le plus long&amp;nbsp;: écrivez &lt;code&gt;repeat(3, minmax(0, 1fr))&lt;/code&gt; si un mot ou une image trop large déforme la grille. Retenez&amp;nbsp;: Flexbox pour une rangée de liens, Grid pour une galerie ou une page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le responsive design avec les media queries
&lt;/h2&gt;

&lt;p&gt;Une page responsive s'adapte à la largeur de l'écran. Partez du mobile&amp;nbsp;: une colonne par défaut, plus de colonnes quand la place le permet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cartes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.cartes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sous 48rem, soit 768 pixels avec la taille de police par défaut, les cartes s'empilent&amp;nbsp;; au-delà, elles passent sur trois colonnes. Nous avons vérifié ce comportement sur le mini-projet&amp;nbsp;: une colonne à 375 pixels de large, trois à 1&amp;nbsp;280 pixels, et aucun défilement horizontal dans les deux cas.&lt;/p&gt;

&lt;p&gt;Complétez avec &lt;code&gt;max-width: 100%; height: auto;&lt;/code&gt; sur les images&amp;nbsp;: la première déclaration empêche l'image de déborder, la seconde recalcule la hauteur pour garder ses proportions malgré les attributs &lt;code&gt;width&lt;/code&gt; et &lt;code&gt;height&lt;/code&gt;. Testez ensuite plusieurs largeurs avec le mode appareil des DevTools.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le CSS moderne et son statut Baseline
&lt;/h2&gt;

&lt;p&gt;Baseline est l'étiquette commune de web.dev et MDN pour savoir si une fonction CSS est utilisable partout. Une fonction est «&amp;nbsp;Newly available&amp;nbsp;» quand elle marche dans tous les navigateurs du socle&amp;nbsp;: Chrome, Edge, Firefox et Safari, sur ordinateur et sur mobile. Elle devient «&amp;nbsp;Widely available&amp;nbsp;» 30&amp;nbsp;mois plus tard (&lt;a href="https://web.dev/baseline" rel="noopener noreferrer"&gt;web.dev, Baseline&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;Trois fonctions modernes ont ce statut, d'après les bandeaux de MDN relevés le 5 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fonction&lt;/th&gt;
&lt;th&gt;À quoi elle sert&lt;/th&gt;
&lt;th&gt;Statut sur MDN&lt;/th&gt;
&lt;th&gt;Disponible partout depuis&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container" rel="noopener noreferrer"&gt;&lt;code&gt;@container&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Adapter un composant à son conteneur&lt;/td&gt;
&lt;td&gt;Widely available&lt;/td&gt;
&lt;td&gt;Février 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has" rel="noopener noreferrer"&gt;&lt;code&gt;:has()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Cibler un élément selon son contenu&lt;/td&gt;
&lt;td&gt;Widely available&lt;/td&gt;
&lt;td&gt;Décembre 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/Nesting_selector" rel="noopener noreferrer"&gt;Imbrication &lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Imbriquer des règles sans outil&lt;/td&gt;
&lt;td&gt;Widely available&lt;/td&gt;
&lt;td&gt;Décembre 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs0ra2khetogv51lq286u.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs0ra2khetogv51lq286u.webp" alt="Frise chronologique&amp;nbsp;: statut Baseline de @container,&amp;nbsp;:has() et de l'imbrication CSS" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MDN précise pour &lt;code&gt;@container&lt;/code&gt; et l'imbrication que certaines parties peuvent avoir un support variable. Le mini-projet utilise l'imbrication pour ranger les styles de la navigation dans l'en-tête&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et &lt;code&gt;:has()&lt;/code&gt; change la couleur du bouton tant qu'un champ du formulaire est invalide, sans une ligne de JavaScript&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:invalid&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#4b5563&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le bouton reste gris tant que le nom est vide ou que l'e-mail est invalide, et devient bleu quand les deux champs obligatoires sont valides&amp;nbsp;: nous l'avons vérifié avec un test Playwright décrit plus bas. Ce gris n'est qu'un indice&amp;nbsp;: le bouton reste cliquable, et c'est la validation native du navigateur qui bloque l'envoi (vérifié&amp;nbsp;: la page ne change pas et le champ passe en invalide). La couleur ne porte pas seule l'information (critère WCAG 1.4.1)&amp;nbsp;: les labels indiquent «&amp;nbsp;(obligatoire)&amp;nbsp;».&lt;/p&gt;




&lt;h2&gt;
  
  
  Accessibilité : les bases dès le premier jour
&lt;/h2&gt;

&lt;p&gt;Une page accessible se lit au clavier, au lecteur d'écran et avec une vue faible. La référence est WCAG 2.2, recommandation du W3C depuis le 5 octobre 2023, dont la version en vigueur date du 12 décembre 2024 (&lt;a href="https://www.w3.org/standards/history/WCAG22/" rel="noopener noreferrer"&gt;historique des publications du W3C&lt;/a&gt; et &lt;a href="https://www.w3.org/TR/WCAG22/" rel="noopener noreferrer"&gt;texte de WCAG 2.2&lt;/a&gt;, consultés le 5 novembre 2026). Quatre règles de base&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le contraste.&lt;/strong&gt; Le critère 1.4.3 demande un rapport d'au moins 4,5:1 pour le texte normal et 3:1 pour le grand texte, d'après la même norme.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les labels.&lt;/strong&gt; Chaque champ a un &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; visible et relié, qui signale aussi les champs obligatoires, par exemple «&amp;nbsp;Nom (obligatoire)&amp;nbsp;» (critère 3.3.2).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le focus visible.&lt;/strong&gt; Ne supprimez jamais &lt;code&gt;outline&lt;/code&gt; sans le remplacer&amp;nbsp;: le critère 2.4.7 exige un indicateur de focus visible au clavier, et le 2.4.11, nouveau en 2.2, interdit que l'élément qui a le focus soit entièrement caché par un contenu de la page, comme un bandeau fixe. Le critère 2.5.8 fixe aussi une cible d'au moins 24 x 24 pixels CSS, sauf exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les titres et les images.&lt;/strong&gt; Des titres sans saut de niveau, un &lt;code&gt;alt&lt;/code&gt; sur chaque image utile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le mini-projet applique la règle suivante, et notre test au clavier confirme un contour bleu de 3 pixels sur le premier lien atteint avec Tab&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;outline-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos calculs avec la formule du W3C pour le mini-projet&amp;nbsp;: texte &lt;code&gt;#1f2937&lt;/code&gt; sur blanc, 14,68:1&amp;nbsp;; liens &lt;code&gt;#1d4ed8&lt;/code&gt; sur &lt;code&gt;#f3f4f6&lt;/code&gt;, 6,09:1&amp;nbsp;; blanc sur le bouton bleu, 6,7:1, et sur le gris, 7,56:1. Notre première version grisait le bouton avec &lt;code&gt;opacity&lt;/code&gt;, ce qui pâlissait le texte&amp;nbsp;: une couleur de fond sombre règle le problème.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le mini-projet, validé par le W3C
&lt;/h2&gt;

&lt;p&gt;Le projet final est une page de présentation de développeur junior&amp;nbsp;: navigation, trois cartes, un tableau et un formulaire. Nous l'avons écrit puis vérifié le 5 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Validateur HTML du W3C&lt;/strong&gt; (Nu Html Checker 26.11.5)&amp;nbsp;: zéro erreur, zéro avertissement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validateur CSS du W3C&lt;/strong&gt; (profil CSS3 + SVG)&amp;nbsp;: zéro erreur, imbrication comprise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendu avec Playwright&lt;/strong&gt; dans Chrome 156, Edge 156 et Chromium 120, à 1&amp;nbsp;280 et 375 pixels&amp;nbsp;: trois colonnes puis une, sans défilement horizontal ni erreur de console.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test du formulaire&lt;/strong&gt;, dans les trois mêmes navigateurs&amp;nbsp;: bouton gris (&lt;code&gt;#4b5563&lt;/code&gt;) avec les champs vides puis avec l'e-mail «&amp;nbsp;lea&amp;nbsp;», bleu (&lt;code&gt;#1d4ed8&lt;/code&gt;) avec un e-mail valide&amp;nbsp;; clic sur «&amp;nbsp;Envoyer&amp;nbsp;» avec le nom vidé&amp;nbsp;: la page ne change pas et le champ est invalide. Une pression sur Tab donne au premier lien un contour plein de 3 pixels décalé de 2 pixels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprfum3n9hftoexxs31s3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprfum3n9hftoexxs31s3.webp" alt="Capture du mini-projet HTML CSS débutant à 1&amp;nbsp;280 pixels de large&amp;nbsp;: en-tête avec navigation, trois cartes de projets, tableau de compétences et formulaire de contact" width="800" height="892"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le fichier &lt;code&gt;index.html&lt;/code&gt;&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Léa Martin, développeuse web junior&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Page de présentation de Léa Martin, développeuse web junior."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"site-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Léa Martin&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Navigation principale"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#projets"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Projets&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#competences"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Compétences&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#contact"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"intro"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Développeuse web junior&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;J'apprends HTML et CSS depuis quatre semaines. Voici mes premiers projets.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"projets"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Projets&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cartes"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"carte"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"img/recette.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Aperçu de la page de recette"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Page de recette&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Titres, listes et image avec texte alternatif.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"carte"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"img/horaires.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Aperçu du tableau d'horaires"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Tableau d'horaires&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Un tableau avec en-têtes et légende.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"carte"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"img/formulaire.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Aperçu du formulaire d'inscription"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Formulaire d'inscription&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Chaque champ a son label.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"competences"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Compétences&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;table&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;caption&amp;gt;&lt;/span&gt;Ce que je sais faire après un mois&lt;span class="nt"&gt;&amp;lt;/caption&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;thead&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Domaine&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Niveau&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tbody&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;HTML sémantique&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;À l'aise&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;Flexbox et Grid&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;En progrès&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"contact"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/contact"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"nom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nom (obligatoire)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nom"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"nom"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;E-mail (obligatoire)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Message&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;rows=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Envoyer&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;copy;&lt;/span&gt; 2026 Léa Martin&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le fichier &lt;code&gt;style.css&lt;/code&gt;&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--texte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#1f2937&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--fond&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#1d4ed8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system-ui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--texte&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--fond&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="m"&gt;5%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#f3f4f6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;ul&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.intro&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.75rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.5rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cartes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.carte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nx"&gt;#d1d5db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.carte&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;table&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-collapse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;collapse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;td&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nx"&gt;#d1d5db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;textarea&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nx"&gt;#6b7280&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;outline-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:invalid&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#4b5563&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="l"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="m"&gt;5%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;#f3f4f6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.cartes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Un détail de cascade à remarquer&amp;nbsp;: la règle &lt;code&gt;form:has(:invalid) button&lt;/code&gt; est placée avant &lt;code&gt;button&lt;/code&gt;, mais elle gagne quand même. &lt;code&gt;:has()&lt;/code&gt; prend la spécificité de son argument le plus spécifique, ici &lt;code&gt;:invalid&lt;/code&gt;&amp;nbsp;: la règle vaut 0-1-2 et dépasse &lt;code&gt;button&lt;/code&gt; (0-0-1). Pour valider votre propre page, collez-la sur &lt;a href="https://validator.w3.org/nu/" rel="noopener noreferrer"&gt;validator.w3.org/nu&lt;/a&gt;&amp;nbsp;; la &lt;a href="https://validator.w3.org/nu/about.html" rel="noopener noreferrer"&gt;page de présentation du validateur&lt;/a&gt; rappelle que l'outil est un vérificateur, pas une certification.&lt;/p&gt;




&lt;h2&gt;
  
  
  Publier sa première page
&lt;/h2&gt;

&lt;p&gt;GitHub Pages publie gratuitement un site statique depuis un dépôt public. La documentation de GitHub décrit la marche à suivre&amp;nbsp;: créer un dépôt nommé &lt;code&gt;&amp;lt;votre-identifiant-github&amp;gt;.github.io&lt;/code&gt;, y placer &lt;code&gt;index.html&lt;/code&gt; à la racine, choisir la branche de publication dans Settings, puis Pages, et attendre la construction, qui peut prendre jusqu'à dix minutes (&lt;a href="https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site" rel="noopener noreferrer"&gt;GitHub Docs&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;Avec l'offre GitHub Free, le dépôt doit être public, selon la même page&amp;nbsp;: n'y mettez aucune donnée personnelle. Si Git vous est encore étranger, notre guide &lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub pour débutant&lt;/a&gt; va de la première commande au premier dépôt en ligne. Une page publiée devient ensuite la première brique d'un &lt;a href="https://neurautech.com/portfolio-developpeur-comment-le-construire-2026/" rel="noopener noreferrer"&gt;portfolio de développeur&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exercices HTML CSS débutant corrigés
&lt;/h2&gt;

&lt;p&gt;Faites chaque exercice avant de lire la correction. Le 5 novembre 2026, tous les blocs de code de l'article sont passés aux validateurs HTML et CSS du W3C sans erreur, les extraits HTML étant insérés dans une page complète.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 1 : le squelette
&lt;/h3&gt;

&lt;p&gt;Écrivez une page minimale en français, avec un titre d'onglet «&amp;nbsp;Exercice 1&amp;nbsp;», la balise viewport et un &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Exercice 1&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Ma première page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oubli classique&amp;nbsp;: &lt;code&gt;lang="fr"&lt;/code&gt;. Nous avons retiré cet attribut et repassé la page au validateur du W3C&amp;nbsp;: il répond par un avertissement qui conseille de déclarer la langue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 2 : une recette
&lt;/h3&gt;

&lt;p&gt;Créez une recette avec un titre, une image, une liste d'ingrédients non ordonnée et des étapes numérotées.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Crêpes&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"crepes.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Pile de crêpes dorées dans une assiette"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Ingrédients&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;250 g de farine&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;4 œufs&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;50 cl de lait&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Étapes&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Mélanger la farine et les œufs.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Ajouter le lait petit à petit.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercice 3 : un tableau d'horaires
&lt;/h3&gt;

&lt;p&gt;Affichez les horaires d'une bibliothèque sur trois jours, avec une légende et des en-têtes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;table&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;caption&amp;gt;&lt;/span&gt;Horaires de la bibliothèque&lt;span class="nt"&gt;&amp;lt;/caption&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;thead&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Jour&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Ouverture&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fermeture&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tbody&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Lundi&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;9 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;18 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Mardi&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;9 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;18 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Samedi&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;10 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;13 h&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercice 4 : un formulaire accessible
&lt;/h3&gt;

&lt;p&gt;Créez un formulaire avec un nom obligatoire, un e-mail obligatoire et une liste déroulante de sujets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"nom-ex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nom (obligatoire)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nom-ex"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"nom"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"mail-ex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;E-mail (obligatoire)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mail-ex"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"sujet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sujet&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sujet"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"sujet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;Question&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;Devis&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Envoyer&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chaque &lt;code&gt;for&lt;/code&gt; vise un &lt;code&gt;id&lt;/code&gt; unique&amp;nbsp;: le lecteur d'écran annonce ainsi le champ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 5 : le modèle de boîte
&lt;/h3&gt;

&lt;p&gt;Une boîte a &lt;code&gt;width: 300px&lt;/code&gt;, &lt;code&gt;padding: 20px&lt;/code&gt; et &lt;code&gt;border: 2px solid&lt;/code&gt;. Quelle largeur occupe-t-elle à l'écran&amp;nbsp;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt; En &lt;code&gt;content-box&lt;/code&gt; (par défaut)&amp;nbsp;: 300 + 2 × 20 + 2 × 2 = 344 pixels. En &lt;code&gt;border-box&lt;/code&gt;&amp;nbsp;: 300 pixels, dont 256 de contenu.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 6 : la spécificité
&lt;/h3&gt;

&lt;p&gt;Le lien &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; est dans &lt;code&gt;&amp;lt;nav id="menu" class="nav"&amp;gt;&lt;/code&gt;. De quelle couleur est-il&amp;nbsp;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#menu&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.nav&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt; Vert. &lt;code&gt;#menu a&lt;/code&gt; vaut 1-0-1, &lt;code&gt;.nav a&lt;/code&gt; 0-1-1 et &lt;code&gt;a&lt;/code&gt; 0-0-1. L'ordre du code ne joue qu'à spécificité égale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 7 : une navigation en Flexbox
&lt;/h3&gt;

&lt;p&gt;Placez un logo à gauche et trois liens à droite, centrés verticalement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"site-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Léa Martin&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Navigation principale"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#projets"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Projets&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#competences"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Compétences&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#contact"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;list-style: none&lt;/code&gt; retire les puces, &lt;code&gt;margin: 0&lt;/code&gt; et &lt;code&gt;padding: 0&lt;/code&gt; suppriment le retrait par défaut de la liste.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercice 8 : une galerie responsive
&lt;/h3&gt;

&lt;p&gt;Affichez six images sur une colonne sur mobile, deux à partir de 40rem et trois à partir de 64rem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.galerie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.galerie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.galerie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Un plan d'apprentissage en 4 semaines
&lt;/h2&gt;

&lt;p&gt;Quatre semaines à raison d'une heure par jour suffisent pour publier une première page propre. Ce plan est une proposition de notre part, pas une norme&amp;nbsp;: adaptez-le à votre rythme.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Semaine&lt;/th&gt;
&lt;th&gt;Objectif&lt;/th&gt;
&lt;th&gt;Livrable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Structure, balises sémantiques, texte, liens, images&lt;/td&gt;
&lt;td&gt;Exercices 1 et 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Tableaux, formulaires, sélecteurs, cascade&lt;/td&gt;
&lt;td&gt;Exercices 3, 4 et 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Modèle de boîte, Flexbox, Grid, media queries&lt;/td&gt;
&lt;td&gt;Exercices 5, 7 et 8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Accessibilité, validation, publication&lt;/td&gt;
&lt;td&gt;Le mini-projet en ligne&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Écrivez le code vous-même, sans copier-coller. Ensuite, ajoutez JavaScript puis un framework (notre comparatif &lt;a href="https://neurautech.com/react-vs-vue/" rel="noopener noreferrer"&gt;React vs Vue&lt;/a&gt; aide à choisir), ou visez un premier emploi avec notre guide de la &lt;a href="https://neurautech.com/reconversion-developpeur-web/" rel="noopener noreferrer"&gt;reconversion en développeur web&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les cours gratuits pour continuer
&lt;/h2&gt;

&lt;p&gt;Les quatre ressources ci-dessous sont gratuites au 5 novembre 2026&amp;nbsp;; aucune n'a été suivie de bout en bout pour cet article.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ressource&lt;/th&gt;
&lt;th&gt;Gratuit&amp;nbsp;?&lt;/th&gt;
&lt;th&gt;Langue&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Ce qui la distingue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core" rel="noopener noreferrer"&gt;MDN, modules fondamentaux&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Oui, sans compte&lt;/td&gt;
&lt;td&gt;Français et anglais&lt;/td&gt;
&lt;td&gt;Textes et exemples&lt;/td&gt;
&lt;td&gt;Module accessibilité dédié&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://openclassrooms.com/fr/courses/1603881-creez-votre-site-web-avec-html5-et-css3" rel="noopener noreferrer"&gt;OpenClassrooms, Créez votre site web avec HTML5 et CSS3&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Oui, «&amp;nbsp;cours en libre accès&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;Français&lt;/td&gt;
&lt;td&gt;Cours de 15&amp;nbsp;heures, quiz&lt;/td&gt;
&lt;td&gt;Corrigés sur GitHub, selon la page du cours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.freecodecamp.org/learn" rel="noopener noreferrer"&gt;freeCodeCamp&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Oui, le site s'annonce «&amp;nbsp;Learn to Code for Free&amp;nbsp;»&lt;/td&gt;
&lt;td&gt;Anglais&lt;/td&gt;
&lt;td&gt;Non vérifié&lt;/td&gt;
&lt;td&gt;Programme non lu (voir plus bas)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://web.dev/learn/css" rel="noopener noreferrer"&gt;web.dev, Learn CSS&lt;/a&gt; et &lt;a href="https://web.dev/learn/html" rel="noopener noreferrer"&gt;Learn HTML&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Oui, sans compte&lt;/td&gt;
&lt;td&gt;Anglais&lt;/td&gt;
&lt;td&gt;Modules de cours&lt;/td&gt;
&lt;td&gt;Couvre le CSS moderne, dont l'imbrication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;MDN se décrit comme une plateforme «&amp;nbsp;gratuite, de grande qualité et complète&amp;nbsp;» (notre traduction) (&lt;a href="https://developer.mozilla.org/en-US/about" rel="noopener noreferrer"&gt;MDN, à propos&lt;/a&gt;, consulté le 5 novembre 2026). La fiche d'OpenClassrooms indique 15&amp;nbsp;heures, un niveau facile et une mise à jour du 7 octobre 2026.&lt;/p&gt;

&lt;p&gt;Vous cherchez un cours HTML CSS en PDF&amp;nbsp;? Celui de Pierre Giraud se dit «&amp;nbsp;100&amp;nbsp;% gratuit&amp;nbsp;» et propose un PDF, mais affiche un millésime 2020, et nous n'avons trouvé dans son sommaire ni &lt;code&gt;:has()&lt;/code&gt; ni les container queries (&lt;a href="https://www.pierre-giraud.com/html-css-apprendre-coder-cours/" rel="noopener noreferrer"&gt;Pierre Giraud&lt;/a&gt;, consulté le 5 novembre 2026). Cet article s'imprime aussi&amp;nbsp;: Imprimer, puis Enregistrer au format PDF.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Ce cours HTML CSS débutant s'appuie sur des sources publiques et sur un mini-projet exécuté. Restent ces limites&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le rendu dans Firefox et Safari.&lt;/strong&gt; Mini-projet testé seulement dans des navigateurs à moteur Chromium&amp;nbsp;: Chrome 156 et Edge 156 installés sur le poste, et le Chromium 120 fourni avec Playwright 1.40, une version ancienne.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le programme de freeCodeCamp.&lt;/strong&gt; Ses pages se chargent en JavaScript&amp;nbsp;; seule la mention «&amp;nbsp;Learn to Code for Free&amp;nbsp;» a été lue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le prix éventuel du PDF de Pierre Giraud.&lt;/strong&gt; Un montant lu le 2 novembre n'a pas été retrouvé le 5 novembre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La durée réelle d'apprentissage.&lt;/strong&gt; Le plan de quatre semaines est une proposition, non une mesure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La publication sur GitHub Pages.&lt;/strong&gt; Non effectuée&amp;nbsp;; la procédure vient de la documentation de GitHub.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Combien de temps pour apprendre HTML et CSS ?
&lt;/h3&gt;

&lt;p&gt;Quelques semaines de pratique régulière pour les bases. Le cours d'OpenClassrooms annonce 15&amp;nbsp;heures&amp;nbsp;; notre plan propose quatre semaines à une heure par jour jusqu'à une page publiée.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faut-il apprendre HTML avant CSS ?
&lt;/h3&gt;

&lt;p&gt;Oui, de quelques jours de HTML sémantique, puis les deux ensemble. CSS met en forme un HTML existant, et le parcours de &lt;a href="https://developer.mozilla.org/fr/docs/Learn_web_development/Core" rel="noopener noreferrer"&gt;MDN&lt;/a&gt; suit cet ordre.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML et CSS sont-ils des langages de programmation ?
&lt;/h3&gt;

&lt;p&gt;Non. HTML est un langage de balisage et CSS un langage de feuilles de style, sans boucles ni logique de programme. Ils restent la base du web&amp;nbsp;: 58,2&amp;nbsp;% des répondants de l'&lt;a href="https://survey.stackoverflow.co/2026/technology/data/languages" rel="noopener noreferrer"&gt;enquête Stack Overflow 2026&lt;/a&gt; disent avoir beaucoup développé avec HTML/CSS dans l'année écoulée.&lt;/p&gt;

&lt;h3&gt;
  
  
  Où trouver un cours HTML CSS gratuit en français ?
&lt;/h3&gt;

&lt;p&gt;MDN, en français et sans compte, et le cours en libre accès d'OpenClassrooms. freeCodeCamp et web.dev Learn sont gratuits aussi, mais en anglais.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse de la documentation de MDN, web.dev, du W3C, de GitHub et de Chrome for Developers, consultée le 5 novembre 2026. Tests effectués, et seulement ceux-là&amp;nbsp;: les quatre vérifications listées dans la section du mini-projet, plus le passage de tous les blocs de code aux validateurs du W3C, dont une variante sans &lt;code&gt;lang&lt;/code&gt;. Les contrastes sont calculés avec la formule du W3C. Citations anglaises traduites par nos soins. Aucun lien affilié, aucune relation commerciale avec les plateformes citées.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou une information périmée&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 5 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image d'en-tête&amp;nbsp;: Jakub Żerdzicki (Unsplash License). Capture du mini-projet et graphiques&amp;nbsp;: NeurauTech.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>debutant</category>
      <category>developpementweb</category>
    </item>
    <item>
      <title>PostgreSQL vs MySQL en 2026 : versions, syntaxe, index et grille de choix</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 10:23:38 +0000</pubDate>
      <link>https://dev.to/neurau_tech/postgresql-vs-mysql-en-2026-versions-syntaxe-index-et-grille-de-choix-48ca</link>
      <guid>https://dev.to/neurau_tech/postgresql-vs-mysql-en-2026-versions-syntaxe-index-et-grille-de-choix-48ca</guid>
      <description>&lt;h2&gt;
  
  
  La réponse courte
&lt;/h2&gt;

&lt;p&gt;Le match PostgreSQL vs MySQL ne se gagne pas sur la vitesse brute&amp;nbsp;: les deux moteurs sont relationnels, transactionnels et libres. Ils se séparent sur la richesse fonctionnelle, la licence, les transactions par défaut et l'écosystème&amp;nbsp;: PostgreSQL offre plus de types, d'index et d'extensions&amp;nbsp;; MySQL et MariaDB restent les bases exigées par WordPress.&lt;/p&gt;

&lt;p&gt;Cet article synthétise des sources publiques lues le 5 novembre 2026, sans test ni benchmark de notre part.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Versions stables au 5 novembre 2026&amp;nbsp;: PostgreSQL 18.6 (la 19 est en release candidate depuis le 15 octobre) et MySQL 9.7 LTS, avec MySQL 26.10 en version Innovation depuis le 20 octobre.&lt;/li&gt;
&lt;li&gt;PostgreSQL est sous une licence permissive de type BSD ou MIT&amp;nbsp;; MySQL est sous GPLv2 ou sous licence commerciale d'Oracle.&lt;/li&gt;
&lt;li&gt;Par défaut, PostgreSQL travaille en Read Committed et InnoDB en Repeatable Read&amp;nbsp;: le même code peut donc voir des données différentes.&lt;/li&gt;
&lt;li&gt;Pour l'IA, pgvector apporte la recherche vectorielle indexée à PostgreSQL&amp;nbsp;; dans MySQL Community, le type VECTOR existe, mais pas la fonction DISTANCE().&lt;/li&gt;
&lt;li&gt;Aucun des deux n'est «&amp;nbsp;plus rapide&amp;nbsp;» en général&amp;nbsp;: mesurez sur votre propre charge.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Versions et politiques de support
&lt;/h2&gt;

&lt;p&gt;Côté PostgreSQL, la &lt;a href="https://www.postgresql.org/support/versioning/" rel="noopener noreferrer"&gt;politique de versions officielle&lt;/a&gt; indique qu'une version majeure, publiée environ une fois par an, est «&amp;nbsp;supportée 5&amp;nbsp;ans&amp;nbsp;» (notre traduction), avec une mineure de correctifs au moins tous les trois mois. Le 5 novembre 2026, elle liste cinq versions maintenues, de la 14 à la 18&amp;nbsp;; en voici trois&amp;nbsp;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Dernière mineure&lt;/th&gt;
&lt;th&gt;Sortie&lt;/th&gt;
&lt;th&gt;Fin de support&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL 18&lt;/td&gt;
&lt;td&gt;18.6&lt;/td&gt;
&lt;td&gt;25 septembre 2025&lt;/td&gt;
&lt;td&gt;14 novembre 2030&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL 17&lt;/td&gt;
&lt;td&gt;17.11&lt;/td&gt;
&lt;td&gt;26 septembre 2024&lt;/td&gt;
&lt;td&gt;8 novembre 2029&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL 14&lt;/td&gt;
&lt;td&gt;14.24&lt;/td&gt;
&lt;td&gt;30 septembre 2021&lt;/td&gt;
&lt;td&gt;12 novembre 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ces mineures sont sorties ensemble le 13 août 2026 (&lt;a href="https://www.postgresql.org/about/news/postgresql-186-1711-1615-1519-1424-and-19-beta-3-released-3365/" rel="noopener noreferrer"&gt;annonce&lt;/a&gt; de 18.6, 17.11, 16.15, 15.19 et 14.24). PostgreSQL 19, prévu en octobre 2026 par la &lt;a href="https://www.postgresql.org/developer/roadmap/" rel="noopener noreferrer"&gt;feuille de route&lt;/a&gt;, en est à la release candidate 1 du 15 octobre.&lt;/p&gt;

&lt;p&gt;Côté MySQL, le &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/mysql-releases.html" rel="noopener noreferrer"&gt;manuel de référence 9.7&lt;/a&gt; décrit deux pistes&amp;nbsp;: les séries LTS (8.4 et 9.7) ont «&amp;nbsp;5&amp;nbsp;ans de support premier et 3&amp;nbsp;ans de support étendu&amp;nbsp;» (notre traduction), une version Innovation n'est supportée que jusqu'à la suivante.&lt;/p&gt;

&lt;p&gt;Après 9.7, MySQL passe à une numérotation calendaire AA.M&amp;nbsp;: 26.7 désigne juillet 2026, et les &lt;a href="https://dev.mysql.com/doc/relnotes/mysql/26.10/en/" rel="noopener noreferrer"&gt;notes de version&lt;/a&gt; datent MySQL 26.10.0 du 20 octobre 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Et MariaDB&amp;nbsp;?&lt;/strong&gt; C'est un fork de MySQL lancé par ses développeurs d'origine, qui reste sous GPLv2 (&lt;a href="https://mariadb.org/about/" rel="noopener noreferrer"&gt;MariaDB Foundation&lt;/a&gt;). Sa &lt;a href="https://mariadb.org/about/#maintenance-policy" rel="noopener noreferrer"&gt;politique de maintenance&lt;/a&gt; prévoit une LTS par an, maintenue trois ans en binaires communautaires&amp;nbsp;; la LTS actuelle, 12.3, est sortie le 28 mai 2026. Compatible pour le SQL courant, il diverge de MySQL sur de nombreux points&amp;nbsp;: testez avant de substituer l'un à l'autre.&lt;/p&gt;




&lt;h2&gt;
  
  
  Licences : liberté totale contre double licence
&lt;/h2&gt;

&lt;p&gt;PostgreSQL est publié sous la &lt;a href="https://www.postgresql.org/about/licence/" rel="noopener noreferrer"&gt;PostgreSQL License&lt;/a&gt;, «&amp;nbsp;une licence open source libérale, similaire aux licences BSD ou MIT&amp;nbsp;» (notre traduction). Vous pouvez l'intégrer à un produit fermé en conservant la mention de copyright.&lt;/p&gt;

&lt;p&gt;MySQL appartient à Oracle et suit un modèle de double licence. Selon la &lt;a href="https://www.mysql.com/about/legal/licensing/oem/" rel="noopener noreferrer"&gt;page de licences d'Oracle&lt;/a&gt;, le serveur et les bibliothèques clientes sont disponibles sous GPLv2 et sous licence commerciale&amp;nbsp;; toujours selon Oracle, un éditeur qui distribue MySQL avec un logiciel dont il ne publie pas le code doit signer un contrat commercial.&lt;/p&gt;

&lt;p&gt;Les obligations dépendent de la façon dont votre logiciel est lié à MySQL et distribué&amp;nbsp;: une application web qui s'y connecte depuis votre serveur ne distribue pas MySQL. Pour un produit livré chez des clients, faites valider le montage par un juriste.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conformité au standard SQL
&lt;/h2&gt;

&lt;p&gt;PostgreSQL vise le standard le plus récent&amp;nbsp;: sa &lt;a href="https://www.postgresql.org/docs/18/features.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; indique qu'il prend en charge au moins 170 des 177 fonctionnalités obligatoires de SQL:2023 Core&amp;nbsp;; aucun système ne revendique une conformité complète.&lt;/p&gt;

&lt;p&gt;MySQL vise la conformité «&amp;nbsp;sans sacrifier la vitesse ni la fiabilité&amp;nbsp;» (notre traduction) et assume de nombreuses extensions, selon son &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/compatibility.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Un développeur formé au SQL standard, par exemple avec notre &lt;a href="https://neurautech.com/sql-debutant-cours-exercices/" rel="noopener noreferrer"&gt;cours SQL pour débutant&lt;/a&gt;, retrouve donc plus vite ses repères dans PostgreSQL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Types de données : JSON, tableaux, UUID, enums
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JSON contre JSONB.&lt;/strong&gt; C'est ici que PostgreSQL prend le plus d'avance. Il distingue &lt;code&gt;json&lt;/code&gt;, copie exacte du texte, et &lt;code&gt;jsonb&lt;/code&gt;, binaire, «&amp;nbsp;nettement plus rapide à traiter&amp;nbsp;» et indexable&amp;nbsp;: sa &lt;a href="https://www.postgresql.org/docs/18/datatype-json.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; recommande &lt;code&gt;jsonb&lt;/code&gt; dans la plupart des cas.&lt;/p&gt;

&lt;p&gt;MySQL a un seul type &lt;code&gt;JSON&lt;/code&gt;, lui aussi binaire, mais d'après son &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/json.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;, une colonne JSON ne s'indexe pas directement&amp;nbsp;: on passe par une colonne générée ou un index multi-valeurs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;PostgreSQL 18&lt;/th&gt;
&lt;th&gt;MySQL 9.7&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;json&lt;/code&gt; et &lt;code&gt;jsonb&lt;/code&gt;, index GIN sur &lt;code&gt;jsonb&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;JSON&lt;/code&gt; binaire, index via colonne générée ou multi-valeurs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tableaux&lt;/td&gt;
&lt;td&gt;Natifs (&lt;code&gt;integer[]&lt;/code&gt;, &lt;code&gt;text[]&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Pas de type tableau, on passe par &lt;code&gt;JSON&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UUID&lt;/td&gt;
&lt;td&gt;Type &lt;code&gt;uuid&lt;/code&gt;, fonction &lt;code&gt;uuidv7()&lt;/code&gt; depuis la 18&lt;/td&gt;
&lt;td&gt;Pas de type dédié&amp;nbsp;: &lt;code&gt;UUID()&lt;/code&gt; et &lt;code&gt;UUID_TO_BIN()&lt;/code&gt; vers &lt;code&gt;BINARY(16)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enum&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CREATE TYPE ... AS ENUM&lt;/code&gt;, réutilisable&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ENUM(...)&lt;/code&gt; déclaré colonne par colonne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Booléen&lt;/td&gt;
&lt;td&gt;Type &lt;code&gt;boolean&lt;/code&gt; réel&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;BOOLEAN&lt;/code&gt; est un synonyme de &lt;code&gt;TINYINT(1)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://www.postgresql.org/about/news/postgresql-18-released-3142/" rel="noopener noreferrer"&gt;annonce de PostgreSQL 18&lt;/a&gt; pour &lt;code&gt;uuidv7()&lt;/code&gt;, qui génère des UUID ordonnés dans le temps, et &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/numeric-type-syntax.html" rel="noopener noreferrer"&gt;manuel MySQL&lt;/a&gt; pour les booléens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Index : la boîte à outils de PostgreSQL contre InnoDB
&lt;/h2&gt;

&lt;p&gt;PostgreSQL propose six types d'index intégrés (&lt;a href="https://www.postgresql.org/docs/18/indexes-types.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;), là où InnoDB s'appuie surtout sur le B-tree&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;B-tree&lt;/strong&gt;, le type par défaut, pour l'égalité et les intervalles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash&lt;/strong&gt;, limité aux comparaisons d'égalité.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GIN&lt;/strong&gt;, des index inversés pour les valeurs composées&amp;nbsp;: tableaux, &lt;code&gt;jsonb&lt;/code&gt;, recherche plein texte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GiST&lt;/strong&gt; et &lt;strong&gt;SP-GiST&lt;/strong&gt;, pour les données géométriques ou les intervalles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BRIN&lt;/strong&gt;, qui résume des plages de blocs&amp;nbsp;: compact sur de grandes tables triées, comme des journaux horodatés.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chez MySQL, la plupart des index sont des B-trees, sauf les R-trees spatiaux, le hachage des tables &lt;code&gt;MEMORY&lt;/code&gt; et les listes inversées du &lt;code&gt;FULLTEXT&lt;/code&gt; (&lt;a href="https://dev.mysql.com/doc/refman/9.7/en/mysql-indexes.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;). PostgreSQL ajoute les index partiels (avec une clause &lt;code&gt;WHERE&lt;/code&gt;) et les index sur expressions (&lt;a href="https://www.postgresql.org/docs/18/sql-createindex.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;)&amp;nbsp;; MySQL indexe des expressions depuis la version 8.0.13 grâce aux «&amp;nbsp;functional key parts&amp;nbsp;» (&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/create-index.html" rel="noopener noreferrer"&gt;manuel 8.0&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Autre différence&amp;nbsp;: chaque table InnoDB stocke ses lignes dans un index clusterisé, en général la clé primaire (&lt;a href="https://dev.mysql.com/doc/refman/9.7/en/innodb-index-types.html" rel="noopener noreferrer"&gt;manuel d'InnoDB&lt;/a&gt;), alors que PostgreSQL les range dans un tas séparé des index.&lt;/p&gt;




&lt;h2&gt;
  
  
  Transactions, MVCC et niveaux d'isolation
&lt;/h2&gt;

&lt;p&gt;Les deux moteurs sont ACID et multiversion (MVCC), mais pas avec le même niveau d'isolation par défaut.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Point&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;MySQL (InnoDB)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Niveau par défaut&lt;/td&gt;
&lt;td&gt;Read Committed&lt;/td&gt;
&lt;td&gt;Repeatable Read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read Uncommitted&lt;/td&gt;
&lt;td&gt;Se comporte comme Read Committed&lt;/td&gt;
&lt;td&gt;Réellement disponible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lectures fantômes en Repeatable Read&lt;/td&gt;
&lt;td&gt;Impossibles&lt;/td&gt;
&lt;td&gt;Évitées pour les lectures simples (instantané) et verrouillantes (verrous next-key), mais un &lt;code&gt;UPDATE&lt;/code&gt; peut toucher des lignes invisibles à l'instantané&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDL dans une transaction&lt;/td&gt;
&lt;td&gt;Annulable par &lt;code&gt;ROLLBACK&lt;/code&gt;, sauf exceptions (&lt;code&gt;CREATE DATABASE&lt;/code&gt;, &lt;code&gt;CREATE INDEX CONCURRENTLY&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Provoque un commit implicite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources&amp;nbsp;: &lt;a href="https://www.postgresql.org/docs/18/transaction-iso.html" rel="noopener noreferrer"&gt;documentation de PostgreSQL sur l'isolation&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/innodb-transaction-isolation-levels.html" rel="noopener noreferrer"&gt;manuel d'InnoDB&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/implicit-commit.html" rel="noopener noreferrer"&gt;liste des commits implicites de MySQL&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/innodb-next-key-locking.html" rel="noopener noreferrer"&gt;verrous next-key&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/innodb-consistent-read.html" rel="noopener noreferrer"&gt;lectures cohérentes d'InnoDB&lt;/a&gt; et page &lt;a href="https://www.postgresql.org/docs/18/sql-createdatabase.html" rel="noopener noreferrer"&gt;CREATE DATABASE&lt;/a&gt;, lus le 5 novembre 2026.&lt;/p&gt;

&lt;p&gt;En Repeatable Read, les &lt;code&gt;SELECT&lt;/code&gt; simples d'InnoDB lisent l'instantané de la première lecture, mais les instructions verrouillantes voient l'état le plus récent&amp;nbsp;: son manuel déconseille de les mélanger.&lt;/p&gt;

&lt;p&gt;En Read Committed, chaque requête PostgreSQL voit les données validées à son démarrage&amp;nbsp;: deux lectures successives d'une même transaction peuvent différer. Fixez le niveau explicitement quand la logique métier en dépend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le MVCC n'est pas implémenté de la même façon.&lt;/strong&gt; InnoDB modifie la ligne en place dans l'index clusterisé et garde les anciennes versions dans les journaux d'annulation (undo logs), qu'un processus de purge supprime ensuite (&lt;a href="https://dev.mysql.com/doc/refman/9.7/en/innodb-multi-versioning.html" rel="noopener noreferrer"&gt;manuel d'InnoDB&lt;/a&gt;). PostgreSQL écrit une nouvelle version de la ligne dans la table&amp;nbsp;; l'ancienne reste jusqu'au passage de &lt;code&gt;VACUUM&lt;/code&gt;, en pratique du démon autovacuum (&lt;a href="https://www.postgresql.org/docs/18/routine-vacuuming.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;En exploitation&amp;nbsp;: sur PostgreSQL, surveillez l'autovacuum des tables très modifiées&amp;nbsp;; sur InnoDB, évitez les transactions longues, qui bloquent la purge.&lt;/p&gt;




&lt;h2&gt;
  
  
  Réplication et haute disponibilité
&lt;/h2&gt;

&lt;p&gt;PostgreSQL propose la réplication physique en streaming du journal d'écriture (WAL), asynchrone par défaut et synchrone si l'on renseigne &lt;code&gt;synchronous_standby_names&lt;/code&gt; (&lt;a href="https://www.postgresql.org/docs/18/warm-standby.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;), ainsi que la réplication logique, table par table. Le multimaître synchrone n'est pas natif (&lt;a href="https://www.postgresql.org/docs/18/different-replication-solutions.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;), et la bascule automatique s'appuie couramment sur un outil comme &lt;a href="https://github.com/patroni/patroni" rel="noopener noreferrer"&gt;Patroni&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;MySQL réplique son journal binaire, en asynchrone par défaut, avec un mode semi-synchrone et des identifiants de transaction globaux (GTID), selon son &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/replication.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;. Group Replication et InnoDB Cluster ajoutent la haute disponibilité intégrée.&lt;/p&gt;




&lt;h2&gt;
  
  
  Extensions et IA : pgvector face au type VECTOR
&lt;/h2&gt;

&lt;p&gt;PostgreSQL s'enrichit par extensions. Deux exemples dominent&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PostGIS&lt;/strong&gt;, pour stocker, indexer et interroger des données géospatiales (&lt;a href="https://postgis.net/" rel="noopener noreferrer"&gt;postgis.net&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pgvector&lt;/strong&gt;, pour la recherche de similarité vectorielle. Sa &lt;a href="https://github.com/pgvector/pgvector" rel="noopener noreferrer"&gt;page GitHub&lt;/a&gt; indique, le 5 novembre 2026, la version 0.8.7, des index HNSW et IVFFlat, notamment les distances L2, produit scalaire et cosinus, et jusqu'à 2&amp;nbsp;000 dimensions indexables (4&amp;nbsp;000 en &lt;code&gt;halfvec&lt;/code&gt;), pour Postgres 13 et suivants.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une recherche sémantique reste du SQL&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;bigserial&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contenu&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;hnsw&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="n"&gt;vector_cosine_ops&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contenu&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'[0.1,0.2,0.3]'&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;C'est la brique de base d'un système &lt;a href="https://neurautech.com/rag-retrieval-augmented-generation/" rel="noopener noreferrer"&gt;RAG&lt;/a&gt;, avec des embeddings produits par exemple par un &lt;a href="https://neurautech.com/llm-local-ollama/" rel="noopener noreferrer"&gt;LLM local avec Ollama&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Et MySQL&amp;nbsp;?&lt;/strong&gt; MySQL 9.7 a un type &lt;code&gt;VECTOR&lt;/code&gt; de 16&amp;nbsp;383 valeurs au plus, qui ne peut servir d'aucune clé (&lt;a href="https://dev.mysql.com/doc/refman/9.7/en/vector.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;). Surtout, la &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/vector-functions.html" rel="noopener noreferrer"&gt;page des fonctions vectorielles&lt;/a&gt; indique que &lt;code&gt;DISTANCE()&lt;/code&gt; est «&amp;nbsp;disponible uniquement pour les utilisateurs de MySQL HeatWave sur OCI et de MySQL AI&amp;nbsp;; elle n'est pas incluse dans les distributions MySQL Commercial ou Community&amp;nbsp;» (notre traduction).&lt;/p&gt;

&lt;p&gt;MySQL Community stocke donc des vecteurs sans calculer de distance en SQL natif. MariaDB propose un type &lt;code&gt;VECTOR&lt;/code&gt; depuis la version 11.7.1, avec index vectoriel et fonctions de distance (&lt;a href="https://mariadb.com/docs/server/reference/sql-structure/vectors" rel="noopener noreferrer"&gt;documentation MariaDB&lt;/a&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  PostgreSQL vs MySQL : les différences de syntaxe
&lt;/h2&gt;

&lt;p&gt;Pour le SQL courant (&lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;JOIN&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;), rien ne change. Les écarts se concentrent sur quelques points, d'après les documentations officielles&amp;nbsp;: &lt;a href="https://www.postgresql.org/docs/18/sql-insert.html" rel="noopener noreferrer"&gt;INSERT&lt;/a&gt;, &lt;a href="https://www.postgresql.org/docs/18/functions-string.html" rel="noopener noreferrer"&gt;fonctions de chaînes&lt;/a&gt; et &lt;a href="https://www.postgresql.org/docs/18/sql-syntax-lexical.html" rel="noopener noreferrer"&gt;identifiants&lt;/a&gt; de PostgreSQL, &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/create-table.html" rel="noopener noreferrer"&gt;CREATE TABLE&lt;/a&gt; et &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/string-functions.html" rel="noopener noreferrer"&gt;fonctions de chaînes&lt;/a&gt; de MySQL, &lt;a href="https://mariadb.com/docs/release-notes/community-server/old-releases/10.5/what-is-mariadb-105" rel="noopener noreferrer"&gt;nouveautés de MariaDB 10.5&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Besoin&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;MySQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clé auto-incrémentée&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY&lt;/code&gt; (ou &lt;code&gt;serial&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;id INT AUTO_INCREMENT PRIMARY KEY&lt;/code&gt; (la colonne doit être indexée)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pagination&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT 10 OFFSET 20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;LIMIT 10 OFFSET 20&lt;/code&gt; ou &lt;code&gt;LIMIT 20, 10&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insérer ou mettre à jour&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ON CONFLICT (sku) DO UPDATE SET qte = EXCLUDED.qte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AS nouv ON DUPLICATE KEY UPDATE qte = nouv.qte&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concaténation&lt;/td&gt;
&lt;td&gt;`'a' \&lt;/td&gt;
&lt;td&gt;\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Délimiter un identifiant&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;"ma colonne"&lt;/code&gt;&amp;nbsp;; sans guillemets, les noms passent en minuscules&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;`ma colonne`&lt;/code&gt; (guillemets doubles en mode &lt;code&gt;ANSI_QUOTES&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Booléen&lt;/td&gt;
&lt;td&gt;Type &lt;code&gt;boolean&lt;/code&gt;&amp;nbsp;: écrivez &lt;code&gt;WHERE actif&lt;/code&gt;, pas &lt;code&gt;WHERE actif = 1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TRUE&lt;/code&gt; vaut 1, &lt;code&gt;FALSE&lt;/code&gt; vaut 0 (&lt;code&gt;TINYINT(1)&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Valeur de retour d'un INSERT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RETURNING id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;LAST_INSERT_ID()&lt;/code&gt;&amp;nbsp;; MariaDB accepte &lt;code&gt;INSERT ... RETURNING&lt;/code&gt; depuis 10.5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;L'upsert est l'écart le plus coûteux en migration. En PostgreSQL&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A12'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;CONFLICT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DO&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;EXCLUDED&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En MySQL, avec l'alias de ligne recommandé par le &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/insert-on-duplicate.html" rel="noopener noreferrer"&gt;manuel&lt;/a&gt;, &lt;code&gt;VALUES()&lt;/code&gt; étant déprécié&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A12'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;nouv&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;DUPLICATE&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;nouv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pièges&amp;nbsp;: &lt;code&gt;ON CONFLICT (sku)&lt;/code&gt; exige un index ou une contrainte unique sur &lt;code&gt;sku&lt;/code&gt;, alors que &lt;code&gt;ON DUPLICATE KEY&lt;/code&gt; se déclenche sur n'importe quelle clé primaire ou unique de la table&amp;nbsp;; le manuel de MySQL conseille d'ailleurs d'éviter cette clause sur les tables à plusieurs index uniques. MySQL compte aussi 1 ligne affectée pour une insertion, 2 pour une mise à jour et 0 si rien ne change, ce qu'un ORM ou une &lt;a href="https://neurautech.com/creer-une-api-rest-avec-node-js-et-express-en-2026/" rel="noopener noreferrer"&gt;API REST en Node.js&lt;/a&gt; doit savoir.&lt;/p&gt;

&lt;p&gt;Autre écart en migration&amp;nbsp;: avec &lt;code&gt;GENERATED ALWAYS&lt;/code&gt;, PostgreSQL refuse un &lt;code&gt;id&lt;/code&gt; explicite sans &lt;code&gt;OVERRIDING SYSTEM VALUE&lt;/code&gt;. Pour importer des identifiants existants depuis MySQL, déclarez la colonne &lt;code&gt;GENERATED BY DEFAULT&lt;/code&gt;, puis recalez la séquence après l'import, sinon le prochain &lt;code&gt;INSERT&lt;/code&gt; sans &lt;code&gt;id&lt;/code&gt; échouera sur une clé en double&amp;nbsp;: &lt;code&gt;SELECT setval(pg_get_serial_sequence('stock', 'id'), (SELECT max(id) FROM stock));&lt;/code&gt; (&lt;a href="https://www.postgresql.org/docs/18/functions-sequence.html" rel="noopener noreferrer"&gt;fonctions de séquence&lt;/a&gt;). Ces exemples reprennent la syntaxe des manuels&amp;nbsp;; nous ne les avons pas exécutés.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performances : ce qu'on peut dire honnêtement
&lt;/h2&gt;

&lt;p&gt;Aucune source sérieuse ne permet de dire que l'un est plus rapide en général&amp;nbsp;: tout dépend du schéma, des index et des requêtes.&lt;/p&gt;

&lt;p&gt;L'annonce de PostgreSQL 18 parle de gains «&amp;nbsp;jusqu'à 3 fois&amp;nbsp;» grâce aux entrées-sorties asynchrones, mais «&amp;nbsp;dans certains scénarios&amp;nbsp;»&amp;nbsp;: c'est une mesure du projet lui-même. Bytebase, éditeur d'outils pour bases de données, estime de son côté que les performances sont comparables, à 30&amp;nbsp;% près, selon son expérience&amp;nbsp;: une opinion, pas une mesure (&lt;a href="https://www.bytebase.com/blog/postgres-vs-mysql/" rel="noopener noreferrer"&gt;Bytebase&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;Nous n'avons lancé aucun micro-benchmark. La bonne méthode&amp;nbsp;: lancez les deux moteurs en conteneurs avec leurs images officielles (notre tutoriel &lt;a href="https://neurautech.com/docker-pour-debutants/" rel="noopener noreferrer"&gt;Docker pour débutants&lt;/a&gt; suffit), chargez un échantillon de vos données et rejouez vos dix requêtes les plus fréquentes.&lt;/p&gt;

&lt;p&gt;Réglez au moins le cache mémoire (&lt;code&gt;shared_buffers&lt;/code&gt; côté PostgreSQL, &lt;code&gt;innodb_buffer_pool_size&lt;/code&gt; côté MySQL) avant de comparer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Popularité : deux mesures, deux méthodes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ce que déclarent les développeurs.&lt;/strong&gt; L'&lt;a href="https://survey.stackoverflow.co/2026/technology" rel="noopener noreferrer"&gt;enquête Stack Overflow 2026&lt;/a&gt;, consultée le 5 novembre 2026, demande dans quelles bases on a fait «&amp;nbsp;un travail de développement important au cours de l'année écoulée&amp;nbsp;» (notre traduction). Sur les 12&amp;nbsp;061 répondants à cette question, tous profils confondus, PostgreSQL arrive en tête avec 57,9&amp;nbsp;%, devant SQLite (42,1&amp;nbsp;%), MySQL (35,1&amp;nbsp;%) et MariaDB (20,3&amp;nbsp;%). Enquête déclarative, non représentative.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9fu07z0nwtho48j1gr1v.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9fu07z0nwtho48j1gr1v.webp" alt="Graphique en barres&amp;nbsp;: bases de données utilisées par les 12&amp;nbsp;061 répondants de l'enquête Stack Overflow 2026, PostgreSQL 57,9&amp;nbsp;%, SQLite 42,1&amp;nbsp;%, MySQL 35,1&amp;nbsp;%, MariaDB 20,3&amp;nbsp;%" width="799" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ce que mesure DB-Engines.&lt;/strong&gt; Le &lt;a href="https://db-engines.com/en/ranking" rel="noopener noreferrer"&gt;classement DB-Engines&lt;/a&gt; de novembre 2026 place MySQL 2e avec 823,23&amp;nbsp;points et PostgreSQL 4e avec 689,69&amp;nbsp;points. Sur un an, MySQL perd 42,59&amp;nbsp;points et PostgreSQL en gagne 38,32 (scores 2025 recalculés à partir de ces écarts). La &lt;a href="https://db-engines.com/en/ranking_definition" rel="noopener noreferrer"&gt;méthode&lt;/a&gt; combine mentions web, Google Trends, Stack Overflow, offres d'emploi, LinkedIn et X&amp;nbsp;; elle ne mesure pas les installations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq10njnoc5ybtgs7vrqkk.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq10njnoc5ybtgs7vrqkk.webp" alt="Graphique en haltères&amp;nbsp;: comparaison PostgreSQL vs MySQL dans le classement DB-Engines, MySQL de 865,82 à 823,23&amp;nbsp;points, PostgreSQL de 651,37 à 689,69, MariaDB de 87,36 à 75,07, de novembre 2025 à novembre 2026" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En résumé&amp;nbsp;: MySQL garde un score composite DB-Engines plus élevé, mais l'écart se réduit, et PostgreSQL domine chez les répondants de Stack Overflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hébergement et offres gérées
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt;&amp;nbsp;: &lt;a href="https://aws.amazon.com/rds/" rel="noopener noreferrer"&gt;Amazon RDS&lt;/a&gt; propose PostgreSQL, MySQL et MariaDB, et Aurora des éditions compatibles PostgreSQL et MySQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Cloud&lt;/strong&gt;&amp;nbsp;: &lt;a href="https://docs.cloud.google.com/sql/docs" rel="noopener noreferrer"&gt;Cloud SQL&lt;/a&gt; prend en charge MySQL, PostgreSQL et SQL Server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure&lt;/strong&gt;&amp;nbsp;: l'offre &lt;a href="https://learn.microsoft.com/en-us/azure/mysql/flexible-server/overview" rel="noopener noreferrer"&gt;Azure Database for MySQL flexible server&lt;/a&gt; s'appuie sur MySQL Community 5.7, 8.0 et 8.4 (page lue le 5 novembre 2026)&amp;nbsp;: pas encore 9.7.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress&lt;/strong&gt;&amp;nbsp;: ses &lt;a href="https://wordpress.org/about/requirements/" rel="noopener noreferrer"&gt;prérequis officiels&lt;/a&gt; demandent MySQL 8.0 ou plus, ou MariaDB 10.11 ou plus. PostgreSQL n'y figure pas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une offre gérée peut donc avoir une série LTS de retard. Pour comparer ces clouds, voyez notre comparatif &lt;a href="https://neurautech.com/aws-vs-azure-vs-google-cloud-prix-services-usage/" rel="noopener noreferrer"&gt;AWS vs Azure vs Google Cloud&lt;/a&gt; et notre guide de l'&lt;a href="https://neurautech.com/hebergement-cloud-pour-developpeurs/" rel="noopener noreferrer"&gt;hébergement cloud pour développeurs&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Grille de choix selon votre projet
&lt;/h2&gt;

&lt;p&gt;Cette grille, déduite des différences documentées plus haut, ne remplace pas un test sur vos données.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Votre projet&lt;/th&gt;
&lt;th&gt;Notre choix&lt;/th&gt;
&lt;th&gt;Pourquoi&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;J'apprends le SQL, premier projet&lt;/td&gt;
&lt;td&gt;L'un ou l'autre, PostgreSQL de préférence&lt;/td&gt;
&lt;td&gt;Même SQL de base&amp;nbsp;; PostgreSQL suit de plus près le standard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nouvelle application web ou API&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;Types riches, &lt;code&gt;jsonb&lt;/code&gt;, DDL transactionnel, licence permissive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress ou autre CMS PHP conçu pour MySQL&lt;/td&gt;
&lt;td&gt;MySQL ou MariaDB&lt;/td&gt;
&lt;td&gt;WordPress exige MySQL ou MariaDB dans ses prérequis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site PHP sur hébergement mutualisé&lt;/td&gt;
&lt;td&gt;La base fournie par l'offre&lt;/td&gt;
&lt;td&gt;Vérifiez la base incluse avant de choisir&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recherche sémantique, RAG, embeddings&lt;/td&gt;
&lt;td&gt;PostgreSQL avec pgvector&lt;/td&gt;
&lt;td&gt;Distance et index vectoriels dans l'édition libre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Données géographiques&lt;/td&gt;
&lt;td&gt;PostgreSQL avec PostGIS&lt;/td&gt;
&lt;td&gt;Types et index spatiaux par extension&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Équipe experte en MySQL, charge simple&lt;/td&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;td&gt;La compétence de l'équipe prime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logiciel distribué chez vos clients avec base embarquée&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;Pas de licence commerciale à négocier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Besoin d'un fork libre compatible MySQL&lt;/td&gt;
&lt;td&gt;MariaDB&lt;/td&gt;
&lt;td&gt;GPLv2, recherche vectorielle native&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;En cas de doute, le comparatif PostgreSQL vs MySQL penche vers PostgreSQL pour un projet neuf, et vers MySQL quand l'existant l'impose.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Les performances et les exemples SQL.&lt;/strong&gt; Docker n'était pas disponible&amp;nbsp;: aucun benchmark n'a été lancé et aucun exemple n'a été exécuté.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les dates de fin de support de MySQL 8.4 et 9.7.&lt;/strong&gt; Le manuel donne la règle (5&amp;nbsp;ans plus 3&amp;nbsp;ans), pas les dates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L'annonce d'octobre 2026 de MySQL&lt;/strong&gt; sur le blog d'Oracle, inaccessible depuis nos outils.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La sortie finale de PostgreSQL 19,&lt;/strong&gt; non publiée le 5 novembre 2026.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PostgreSQL ou MySQL : lequel choisir pour débuter ?
&lt;/h3&gt;

&lt;p&gt;Les deux conviennent. PostgreSQL suit de plus près le standard SQL&amp;nbsp;; MySQL ou MariaDB s'imposent si vous visez WordPress. Notre &lt;a href="https://neurautech.com/sql-debutant-cours-exercices/" rel="noopener noreferrer"&gt;cours SQL pour débutant&lt;/a&gt; fonctionne avec les deux.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL est-il plus rapide que MySQL ?
&lt;/h3&gt;

&lt;p&gt;Pas en général. Même l'annonce de &lt;a href="https://www.postgresql.org/about/news/postgresql-18-released-3142/" rel="noopener noreferrer"&gt;PostgreSQL 18&lt;/a&gt; parle de gains «&amp;nbsp;dans certains scénarios&amp;nbsp;».&lt;/p&gt;

&lt;h3&gt;
  
  
  MySQL Community permet-il la recherche vectorielle ?
&lt;/h3&gt;

&lt;p&gt;En partie&amp;nbsp;: le type &lt;code&gt;VECTOR&lt;/code&gt; existe, mais selon le &lt;a href="https://dev.mysql.com/doc/refman/9.7/en/vector-functions.html" rel="noopener noreferrer"&gt;manuel MySQL 9.7&lt;/a&gt;, &lt;code&gt;DISTANCE()&lt;/code&gt; est réservée à HeatWave sur OCI et à MySQL AI. Les options libres documentées sont pgvector et MariaDB 11.7 ou plus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peut-on migrer de MySQL vers PostgreSQL facilement ?
&lt;/h3&gt;

&lt;p&gt;Le SQL courant passe. Reprenez l'auto-incrément, l'upsert, les guillemets, les booléens et l'isolation par défaut, puis testez tout.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse fondée exclusivement sur des sources publiques lues le 5 novembre 2026&amp;nbsp;: documentation officielle de PostgreSQL, de MySQL et de MariaDB, pages des fournisseurs cloud, enquête Stack Overflow 2026 et classement DB-Engines. Les chiffres d'éditeurs sont signalés comme tels. Les citations issues de sources en anglais sont traduites par nos soins. Aucun test ni benchmark n'a été mené, aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur aux éditeurs mentionnés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou une version périmée&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 5 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image d'en-tête&amp;nbsp;: Taylor Vick (Unsplash License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>mysql</category>
      <category>sql</category>
      <category>basededonnees</category>
    </item>
    <item>
      <title>Métiers de la cybersécurité : 9 postes, salaires, formations et accès en 2026</title>
      <dc:creator>Neurau Tech</dc:creator>
      <pubDate>Fri, 06 Nov 2026 10:22:59 +0000</pubDate>
      <link>https://dev.to/neurau_tech/metiers-de-la-cybersecurite-9-postes-salaires-formations-et-acces-en-2026-5eo3</link>
      <guid>https://dev.to/neurau_tech/metiers-de-la-cybersecurite-9-postes-salaires-formations-et-acces-en-2026-5eo3</guid>
      <description>&lt;h2&gt;
  
  
  L'essentiel en une minute
&lt;/h2&gt;

&lt;p&gt;Les métiers de la cybersécurité recrutent en France, mais surtout des profils déjà formés en informatique&amp;nbsp;: l'étude 2025 de l'Observatoire des métiers de l'ANSSI compte 23&amp;nbsp;183 offres d'emploi sur un an, et 40&amp;nbsp;% d'entre elles demandent un Bac+5. Voici neuf postes, ce qu'ils paient selon des sources datées et comment y entrer.&lt;/p&gt;

&lt;p&gt;Synthèse de sources publiques consultées le 5 novembre 2026&amp;nbsp;: aucun recruteur interrogé, aucune formation suivie.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Points clés&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Les offres d'emploi en cybersécurité ont augmenté de 49&amp;nbsp;% entre 2019 et 2024, selon l'Observatoire&amp;nbsp;; 77&amp;nbsp;% sont des CDI.&lt;/li&gt;
&lt;li&gt;Architecte (21&amp;nbsp;%), consultant (15&amp;nbsp;%) et ingénieur (15&amp;nbsp;%) sont les métiers les plus demandés.&lt;/li&gt;
&lt;li&gt;Selon le Guide des salaires 2027 de Robert Half (national, brut fixe annuel), un ingénieur cybersécurité gagne de 53&amp;nbsp;000&amp;nbsp;€ (25e percentile) à 82&amp;nbsp;000&amp;nbsp;€ (75e percentile), médiane 67&amp;nbsp;000&amp;nbsp;€&amp;nbsp;; un RSSI de 75&amp;nbsp;000&amp;nbsp;€ à 100&amp;nbsp;000&amp;nbsp;€, médiane 85&amp;nbsp;000&amp;nbsp;€.&lt;/li&gt;
&lt;li&gt;44&amp;nbsp;% des professionnels interrogés n'ont ni diplôme ni certification en cybersécurité.&lt;/li&gt;
&lt;li&gt;TryHackMe (offre gratuite limitée), PortSwigger Web Security Academy et Hackropole permettent de s'entraîner gratuitement&amp;nbsp;; le MOOC SecNumacadémie est fermé pour refonte.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Un marché qui recrute, mais pas n'importe qui
&lt;/h2&gt;

&lt;p&gt;La demande est réelle, mais elle vise des profils qualifiés. L'étude «&amp;nbsp;Les professionnels de la cybersécurité&amp;nbsp;» de juin 2025, réalisée par l'Afpa et l'ANSSI avec la DGEFP, a analysé 23&amp;nbsp;183 offres d'emploi publiées en France de juin 2023 à juin 2024. Elle relève une hausse de 49&amp;nbsp;% des offres entre 2019 et 2024 (&lt;a href="https://sti.eduscol.education.fr/sites/eduscol.education.fr.sti/files/articles/18365/etude-des-professionnels-de-la-cybersecurite-vf2.pdf" rel="noopener noreferrer"&gt;étude de l'Observatoire des métiers, PDF hébergé par Éduscol&lt;/a&gt;, juin 2025, consultée le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;Les offres sont exigeantes&amp;nbsp;: 40&amp;nbsp;% demandent un Bac+5, 6&amp;nbsp;% un Bac+4, 6&amp;nbsp;% un Bac+3 et 9&amp;nbsp;% un Bac+2, 4&amp;nbsp;% un autre niveau, tandis que 34&amp;nbsp;% ne précisent rien. Côté contrats, 77&amp;nbsp;% des offres sont des CDI, 11&amp;nbsp;% des missions en freelance, 5&amp;nbsp;% des contrats en alternance et 4&amp;nbsp;% des CDD&amp;nbsp;; l'étude ne détaille pas le reste.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsloplaxkao57z02csgvo.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsloplaxkao57z02csgvo.webp" alt="Graphique en haltères&amp;nbsp;: part des cinq métiers de la cybersécurité les plus demandés dans les offres d'emploi en 2019 et en 2024, selon l'Observatoire des métiers de l'ANSSI" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L'architecte représente 21&amp;nbsp;% des offres, contre 10&amp;nbsp;% en 2019&amp;nbsp;; l'ingénieur est passé de 30&amp;nbsp;% à 15&amp;nbsp;%.&lt;/p&gt;

&lt;p&gt;L'association ISC2, qui délivre la certification CISSP, a estimé en 2024 le manque de professionnels, y compris pour la France. Les tableaux par pays de son étude 2024 comptent 230&amp;nbsp;338 professionnels de la cybersécurité en France et un déficit de 69&amp;nbsp;139 personnes, en hausse de 17&amp;nbsp;% sur un an (&lt;a href="https://www.isc2.org/Insights/2024/09/Employers-Must-Act-Cybersecurity-Workforce-Growth-Stalls-as-Skills-Gaps-Widen" rel="noopener noreferrer"&gt;ISC2, premiers résultats de l'étude 2024&lt;/a&gt;, 11 septembre 2024, consulté le 5 novembre 2026). La même page cite des données LinkedIn selon lesquelles les nouvelles offres en cybersécurité ont reculé de 4,5&amp;nbsp;% sur un an en France. Ce déficit est une estimation d'enquête, pas un nombre d'offres.&lt;/p&gt;

&lt;p&gt;L'édition 2025, fondée sur 16&amp;nbsp;029 répondants, déplace le sujet vers les compétences&amp;nbsp;: 95&amp;nbsp;% signalent au moins un besoin de compétence, l'IA (41&amp;nbsp;%) et la sécurité du cloud (36&amp;nbsp;%) en tête (&lt;a href="https://www.isc2.org/Insights/2025/12/ISC2-publishes-2025-cybersecurity-workforce-study" rel="noopener noreferrer"&gt;communiqué d'ISC2&lt;/a&gt;, 4 décembre 2025). Le communiqué ne chiffre pas le déficit français.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les 9 métiers de la cybersécurité à connaître
&lt;/h2&gt;

&lt;p&gt;Les métiers de la cybersécurité se rangent en trois familles&amp;nbsp;: défendre au quotidien, attaquer pour tester, et gouverner le risque. Les intitulés s'appuient sur l'étude 2025 de l'Observatoire et sur les usages des offres d'emploi&amp;nbsp;; nous n'avons pas pu consulter le Panorama des métiers de l'ANSSI (voir plus bas). Les descriptions sont notre synthèse. Voir aussi les &lt;a href="https://neurautech.com/cyberattaques-les-plus-frequentes-comment-proteger/" rel="noopener noreferrer"&gt;cyberattaques les plus fréquentes&lt;/a&gt; que ces équipes combattent.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Analyste SOC
&lt;/h3&gt;

&lt;p&gt;L'analyste SOC surveille les alertes de sécurité, le plus souvent depuis un SIEM qui centralise les journaux. Il écarte les faux positifs et qualifie les incidents, parfois en horaires décalés. C'est, à notre lecture des offres, une des portes d'entrée les plus courantes pour un jeune diplômé ou un administrateur système. Les courriels piégés font partie du quotidien&amp;nbsp;: voir notre guide pour &lt;a href="https://neurautech.com/phishing-comment-reconnaitre-et-eviter-les-arnaques/" rel="noopener noreferrer"&gt;reconnaître un phishing&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Pentester (auditeur de sécurité technique)
&lt;/h3&gt;

&lt;p&gt;Le pentester mène des tests d'intrusion autorisés sur une application, un réseau ou un Active Directory, puis rédige un rapport avec des recommandations de correction. Il faut maîtriser le web, les réseaux, Linux, Windows et les scripts&amp;nbsp;; le métier s'exerce surtout en cabinet d'audit ou de conseil.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Analyste réponse aux incidents (CSIRT ou CERT)
&lt;/h3&gt;

&lt;p&gt;Face à une attaque confirmée, l'analyste de réponse aux incidents la contient, trouve le point d'entrée et pilote le retour à la normale. Il travaille dans un CSIRT ou un CERT, interne ou chez un prestataire, souvent après une expérience en SOC.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Analyste forensique
&lt;/h3&gt;

&lt;p&gt;L'analyste forensique collecte et examine les traces numériques&amp;nbsp;: disques, mémoire vive, journaux. Il reconstitue l'attaque sans altérer les preuves, parfois pour la justice.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Analyste de la menace (threat intelligence)
&lt;/h3&gt;

&lt;p&gt;L'analyste de la menace suit les groupes d'attaquants, leurs outils et leurs cibles pour orienter la défense. Il ne concerne que 2&amp;nbsp;% des répondants de l'Observatoire&amp;nbsp;: c'est une spécialité.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Ingénieur sécurité et DevSecOps
&lt;/h3&gt;

&lt;p&gt;L'ingénieur sécurité déploie et exploite les solutions de protection&amp;nbsp;: pare-feu, gestion des identités, sondes, durcissement des serveurs. Sa variante DevSecOps intègre la sécurité aux chaînes CI/CD.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Architecte sécurité
&lt;/h3&gt;

&lt;p&gt;L'architecte sécurité définit les modèles de sécurité et vérifie que les projets les respectent. C'est le métier le plus demandé dans les offres, mais il suppose plusieurs années d'expérience.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Consultant GRC (gouvernance, risques et conformité)
&lt;/h3&gt;

&lt;p&gt;Le consultant GRC traduit normes et lois en mesures&amp;nbsp;: analyse de risques, politique de sécurité, ISO 27001, directive NIS 2. D'après notre lecture des offres, il s'ouvre aussi à des profils venant de l'audit ou du juridique.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. RSSI (responsable de la sécurité des systèmes d'information)
&lt;/h3&gt;

&lt;p&gt;Le RSSI définit la politique de sécurité, pilote projets et budgets et rend compte à la direction. C'est le métier le plus représenté dans l'enquête de l'Observatoire&amp;nbsp;: 30&amp;nbsp;% des 1&amp;nbsp;720 répondants l'exercent. Ce n'est pas un poste de débutant.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les salaires, source par source
&lt;/h2&gt;

&lt;p&gt;Les salaires varient selon la source, la région et ce qui est compté&amp;nbsp;: nous retenons deux grilles de cabinets de recrutement. Pour comparer avec les autres métiers de la tech, notre &lt;a href="https://neurautech.com/salaires-developpeurs-france-2026-grille-complete/" rel="noopener noreferrer"&gt;grille des salaires des développeurs&lt;/a&gt; compare six études.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Robert Half, Guide des salaires 2027.&lt;/strong&gt; Mis en ligne le 1er octobre 2026, ce guide donne des projections pour 2027, fondées selon le cabinet sur la rémunération réelle des professionnels qu'il a placés en France. Ce sont des salaires annuels bruts fixes, hors primes et avantages, au niveau national. Le 25e percentile correspond à un débutant dans la fonction, le 50e à une expérience intermédiaire et le 75e à une expérience reconnue (&lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;Robert Half, salaires IT et Tech 2027 en France&lt;/a&gt;, consulté le 5 novembre 2026).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fonction (Robert Half, national)&lt;/th&gt;
&lt;th&gt;25e percentile&lt;/th&gt;
&lt;th&gt;Médiane&lt;/th&gt;
&lt;th&gt;75e percentile&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur cybersécurité&lt;/td&gt;
&lt;td&gt;53&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;67&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;82&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSSI&lt;/td&gt;
&lt;td&gt;75&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;85&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;100&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Directeur sécurité des systèmes d'information&lt;/td&gt;
&lt;td&gt;97&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;126&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;165&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Développeur, pour comparaison&lt;/td&gt;
&lt;td&gt;43&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;56&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;65&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrateur systèmes et réseaux, pour comparaison&lt;/td&gt;
&lt;td&gt;40&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;45&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;td&gt;55&amp;nbsp;000&amp;nbsp;€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiadkri1qbb276k9k3nb3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiadkri1qbb276k9k3nb3.webp" alt="Graphique en intervalles&amp;nbsp;: salaires annuels bruts fixes du 25e au 75e percentile pour l'ingénieur cybersécurité, le RSSI et le directeur sécurité, comparés au développeur, selon Robert Half" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Licorne Society, grille cybersécurité.&lt;/strong&gt; Ce cabinet publie des fourchettes brutes annuelles pour Paris et l'Île-de-France, avec une décote moyenne de 10 à 15&amp;nbsp;% en région&amp;nbsp;; la page ne précise pas si les primes sont incluses ni sur combien de recrutements elle repose (&lt;a href="https://www.licornesociety.com/blog/salaire-cybersecurite" rel="noopener noreferrer"&gt;Licorne Society&lt;/a&gt;, mise à jour du 11 mars 2026, consultée le 5 novembre 2026).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métier (Licorne Society, Île-de-France)&lt;/th&gt;
&lt;th&gt;Junior (0 à 2&amp;nbsp;ans)&lt;/th&gt;
&lt;th&gt;Confirmé (2 à 5&amp;nbsp;ans)&lt;/th&gt;
&lt;th&gt;Senior (5&amp;nbsp;ans et plus)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Analyste SOC&lt;/td&gt;
&lt;td&gt;40 à 48&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;50 à 65&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;65 à 80&amp;nbsp;k€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pentester&lt;/td&gt;
&lt;td&gt;42 à 50&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;52 à 70&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;70 à 95&amp;nbsp;k€ et plus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingénieur cybersécurité&lt;/td&gt;
&lt;td&gt;45 à 52&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;55 à 70&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;70 à 85&amp;nbsp;k€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consultant GRC&lt;/td&gt;
&lt;td&gt;45 à 55&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;58 à 75&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;75 à 100&amp;nbsp;k€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevSecOps&lt;/td&gt;
&lt;td&gt;48 à 58&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;60 à 80&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;80 à 110&amp;nbsp;k€&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecte cyber&lt;/td&gt;
&lt;td&gt;Non indiqué&lt;/td&gt;
&lt;td&gt;65 à 85&amp;nbsp;k€&lt;/td&gt;
&lt;td&gt;90 à 120&amp;nbsp;k€ et plus&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pour un RSSI, la même grille indique 55&amp;nbsp;000 à 70&amp;nbsp;000 euros en PME ou en prise de poste, et 90&amp;nbsp;000 à 130&amp;nbsp;000 euros pour un profil senior en grand groupe. Faute de grille sourcée, nous ne donnons aucun chiffre pour les analystes CSIRT, forensiques et de la menace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notre lecture.&lt;/strong&gt; Robert Half donne des montants plus élevés&amp;nbsp;: son 25e percentile pour l'ingénieur (53&amp;nbsp;000&amp;nbsp;€) dépasse la fourchette junior francilienne de Licorne Society, et son RSSI au 25e percentile (75&amp;nbsp;000&amp;nbsp;€) dépasse la fourchette PME. Hors Île-de-France, partez du bas des fourchettes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Se former : diplômes, alternance, reconversion
&lt;/h2&gt;

&lt;p&gt;Aucune route n'est obligatoire, selon l'étude de l'Observatoire. Parmi les 1&amp;nbsp;720 professionnels interrogés, 33&amp;nbsp;% ont un diplôme en cybersécurité, 37&amp;nbsp;% une certification, et 44&amp;nbsp;% n'ont ni l'un ni l'autre&amp;nbsp;; 63&amp;nbsp;% ont en revanche un diplôme en informatique ou en numérique hors cybersécurité. 62&amp;nbsp;% déclarent un Bac+5 et 12&amp;nbsp;% un Bac+6 ou plus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les diplômes.&lt;/strong&gt; Au niveau Bac+2, deux BTS mènent vers la sécurité&amp;nbsp;: le BTS SIO option A «&amp;nbsp;Solutions d'infrastructure, systèmes et réseaux&amp;nbsp;» (SISR, &lt;a href="https://www.francecompetences.fr/recherche/rncp/40792/" rel="noopener noreferrer"&gt;fiche RNCP40792&lt;/a&gt;) et le BTS CIEL option A «&amp;nbsp;Informatique et réseaux&amp;nbsp;» (&lt;a href="https://www.francecompetences.fr/recherche/rncp/37391/" rel="noopener noreferrer"&gt;fiche RNCP37391&lt;/a&gt;). Au niveau Bac+3, le BUT Réseaux et télécommunications a une version «&amp;nbsp;Cybersécurité&amp;nbsp;» (&lt;a href="https://www.francecompetences.fr/recherche/rncp/41611/" rel="noopener noreferrer"&gt;fiche RNCP41611&lt;/a&gt;). Viennent ensuite les masters spécialisés et les écoles d'ingénieurs. Ces trois fiches, actives et ouvertes à l'apprentissage, ont été lues le 5 novembre 2026. L'ANSSI attribue le label SecNumedu aux formations initiales spécialisées qui respectent son référentiel&amp;nbsp;; la liste à jour figure sur son site, cyber.gouv.fr, que nous n'avons pas pu charger le 5 novembre 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les titres RNCP.&lt;/strong&gt; Certains diplômes sont enregistrés au répertoire national des certifications professionnelles. Exemple vérifié&amp;nbsp;: le titre d'ingénieur du Cnam, spécialité informatique et cybersécurité, de niveau 7, est accessible en formation initiale, en apprentissage, en formation continue et par validation des acquis, pour des sessions ouvertes à partir du 1er septembre 2026 (&lt;a href="https://www.francecompetences.fr/recherche/rncp/42432/" rel="noopener noreferrer"&gt;fiche RNCP42432 de France compétences&lt;/a&gt;, consultée le 5 novembre 2026). Vérifiez le numéro RNCP d'une école privée avant de signer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'alternance.&lt;/strong&gt; Elle représente 5&amp;nbsp;% des offres analysées par l'Observatoire, et 7&amp;nbsp;% des offres d'ingénieur en cybersécurité. Contrat, salaire et aides sont détaillés dans notre guide de l'&lt;a href="https://neurautech.com/alternance-developpeur-web/" rel="noopener noreferrer"&gt;alternance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La reconversion.&lt;/strong&gt; Elle est possible, mais rarement directe. Dans l'enquête de l'Observatoire, 40&amp;nbsp;% des répondants ont principalement exercé dans l'informatique hors cybersécurité et 12&amp;nbsp;% dans un autre domaine. La voie réaliste passe par un premier poste technique. Les financements sont détaillés dans notre article sur la &lt;a href="https://neurautech.com/reconversion-developpeur-web/" rel="noopener noreferrer"&gt;reconversion&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Les certifications qui comptent
&lt;/h2&gt;

&lt;p&gt;Une certification ne remplace pas l'expérience. L'Observatoire relève que les titulaires d'une certification ou d'un diplôme en cybersécurité ont été approchés par des recruteurs dans 80&amp;nbsp;% des cas au cours de l'année, contre 53&amp;nbsp;% pour les autres&amp;nbsp;: c'est une corrélation, pas la preuve d'un effet. Voici cinq certifications courantes, choisies par nos soins, avec ce que leurs pages officielles indiquaient le 5 novembre 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Certification&lt;/th&gt;
&lt;th&gt;Pour quel métier&lt;/th&gt;
&lt;th&gt;Ce que dit la page officielle&lt;/th&gt;
&lt;th&gt;Prix affiché&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.comptia.org/en-us/certifications/security/v7/" rel="noopener noreferrer"&gt;CompTIA Security+&lt;/a&gt; (SY0-701)&lt;/td&gt;
&lt;td&gt;Premier poste, SOC&lt;/td&gt;
&lt;td&gt;90 questions au plus, 90&amp;nbsp;minutes, score de 750 sur 900&amp;nbsp;; recommande Network+ et 2&amp;nbsp;ans d'expérience. Version V8 annoncée vers le 17 novembre 2026&lt;/td&gt;
&lt;td&gt;Non affiché sur la page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.eccouncil.org/train-certify/certified-ethical-hacker-ceh/" rel="noopener noreferrer"&gt;CEH&lt;/a&gt; (EC-Council, v13)&lt;/td&gt;
&lt;td&gt;Pentest, découverte&lt;/td&gt;
&lt;td&gt;125 questions en 4&amp;nbsp;heures. Pour s'inscrire&amp;nbsp;: une formation officielle EC-Council, ou 2&amp;nbsp;ans d'expérience en sécurité et un &lt;a href="https://cert.eccouncil.org/application-process-eligibility.html" rel="noopener noreferrer"&gt;dossier d'éligibilité&lt;/a&gt; avec 100&amp;nbsp;$ de frais non remboursables&lt;/td&gt;
&lt;td&gt;Examen non affiché&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.offsec.com/courses/pen-200/" rel="noopener noreferrer"&gt;OSCP+&lt;/a&gt; (OffSec, cours PEN-200)&lt;/td&gt;
&lt;td&gt;Pentester&lt;/td&gt;
&lt;td&gt;Épreuve pratique surveillée de 23&amp;nbsp;h&amp;nbsp;45, puis 24&amp;nbsp;heures pour envoyer le rapport (&lt;a href="https://www.offsec.com/blog/oscp-exam-guide/" rel="noopener noreferrer"&gt;guide d'examen&lt;/a&gt;)&amp;nbsp;; la mention OSCP+ expire après 3&amp;nbsp;ans, l'OSCP n'expire pas&lt;/td&gt;
&lt;td&gt;1&amp;nbsp;749&amp;nbsp;$ pour le cours, 90&amp;nbsp;jours de laboratoire et une tentative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pecb.com/en/education-and-certification-for-individuals/iso-iec-27001/iso-iec-27001-lead-implementer" rel="noopener noreferrer"&gt;ISO/IEC 27001 Lead Implementer&lt;/a&gt; (PECB)&lt;/td&gt;
&lt;td&gt;Consultant GRC&lt;/td&gt;
&lt;td&gt;Formation de 4&amp;nbsp;jours et examen le 5e&amp;nbsp;; la certification complète exige 5&amp;nbsp;ans d'expérience, dont 2 en sécurité de l'information&lt;/td&gt;
&lt;td&gt;Inclus dans le prix de la formation, non affiché&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.isc2.org/certifications/cissp" rel="noopener noreferrer"&gt;CISSP&lt;/a&gt; (ISC2)&lt;/td&gt;
&lt;td&gt;RSSI, architecte&lt;/td&gt;
&lt;td&gt;5&amp;nbsp;ans d'expérience dans au moins 2 des 8 domaines&amp;nbsp;; un diplôme de niveau licence ou master en informatique ou dans un domaine proche, ou une certification de la liste agréée par ISC2, peut compter pour 1&amp;nbsp;an. Sans l'expérience, on devient &lt;a href="https://www.isc2.org/certifications/cissp/cissp-experience-requirements" rel="noopener noreferrer"&gt;Associate of ISC2&lt;/a&gt; avec 6&amp;nbsp;ans pour l'acquérir&lt;/td&gt;
&lt;td&gt;Non affiché sur la page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notre lecture&amp;nbsp;: Security+ pour un premier poste en SOC, OSCP+ pour prouver une capacité pratique en pentest. Vérifiez les prix avant d'acheter.&lt;/p&gt;




&lt;h2&gt;
  
  
  S'entraîner gratuitement et légalement
&lt;/h2&gt;

&lt;p&gt;On apprend la sécurité en pratiquant, mais uniquement sur des systèmes que l'on a le droit d'attaquer. L'article 323-1 du Code pénal punit le fait d'accéder ou de se maintenir frauduleusement dans un système de traitement automatisé de données de trois ans d'emprisonnement et de 100&amp;nbsp;000&amp;nbsp;€ d'amende, et de cinq ans et 150&amp;nbsp;000&amp;nbsp;€ en cas de suppression ou de modification de données ou d'altération du fonctionnement du système (Légifrance, article 323-1 du Code pénal, version en vigueur depuis le 26 janvier 2023, lue sur Légifrance le 5 novembre 2026).&lt;/p&gt;

&lt;p&gt;Trois règles en découlent. Sur une plateforme, n'attaquez que les machines qui vous sont attribuées. En bug bounty, sur &lt;a href="https://www.yeswehack.com/" rel="noopener noreferrer"&gt;YesWeHack&lt;/a&gt; par exemple, respectez le périmètre et les règles du programme. Pour le reste, montez un laboratoire local avec des machines virtuelles volontairement vulnérables, sur votre propre matériel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TryHackMe.&lt;/strong&gt; L'offre gratuite donne un accès limité aux parcours, les salles gratuites et une heure par jour de machine d'attaque en ligne. L'abonnement Premium est affiché à 16,99&amp;nbsp;€ par mois, ou 10,50&amp;nbsp;€ par mois en paiement annuel (&lt;a href="https://tryhackme.com/pricing" rel="noopener noreferrer"&gt;tarifs de TryHackMe&lt;/a&gt;, consultés le 5 novembre 2026).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root-Me.&lt;/strong&gt; Plateforme française de challenges, gérée par une association. Le jour de notre consultation, le &lt;a href="https://www.root-me.org/" rel="noopener noreferrer"&gt;site&lt;/a&gt; affichait une page de protection anti-robots&amp;nbsp;: nous n'avons pas pu relire ses conditions d'accès gratuit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hack The Box.&lt;/strong&gt; La &lt;a href="https://www.hackthebox.com/" rel="noopener noreferrer"&gt;page d'accueil&lt;/a&gt; présente des laboratoires, des cours (Academy) et des compétitions CTF. Les pages consultées ne détaillent pas l'offre gratuite pour les particuliers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PortSwigger Web Security Academy.&lt;/strong&gt; Cours et laboratoires sur les failles web, annoncés «&amp;nbsp;100% free&amp;nbsp;» sur la page officielle de PortSwigger (portswigger.net, lue le 5 novembre 2026).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les CTF.&lt;/strong&gt; Les compétitions «&amp;nbsp;Capture The Flag&amp;nbsp;» se jouent seul ou en équipe, souvent en ligne&amp;nbsp;; l'agenda mondial est recensé sur CTFtime. Le France Cybersecurity Challenge (FCSC) est la compétition organisée par l'ANSSI&amp;nbsp;: ses épreuves des éditions 2019 à 2026 se rejouent toute l'année sur &lt;a href="https://hackropole.fr/fr/" rel="noopener noreferrer"&gt;Hackropole&lt;/a&gt;, qui comptait 627 challenges le 5 novembre 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SecNumacadémie.&lt;/strong&gt; Le MOOC de l'ANSSI est «&amp;nbsp;actuellement fermé&amp;nbsp;» pour refonte&amp;nbsp;: la &lt;a href="https://secnumacademie.gouv.fr/" rel="noopener noreferrer"&gt;page officielle&lt;/a&gt; annonce une nouvelle version «&amp;nbsp;courant 2026&amp;nbsp;», en trois niveaux, avec une attestation de réussite par parcours.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un parcours de départ en trois étapes, selon notre lecture&amp;nbsp;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Les bases.&lt;/strong&gt; Linux et réseaux, avec nos &lt;a href="https://neurautech.com/commandes-linux-de-base/" rel="noopener noreferrer"&gt;commandes Linux de base&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les salles guidées.&lt;/strong&gt; Parcours gratuits de TryHackMe ou de PortSwigger, puis premiers challenges Root-Me ou Hackropole.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les comptes rendus.&lt;/strong&gt; Publiez vos solutions dans un dépôt, avec notre guide &lt;a href="https://neurautech.com/git-et-github-debutant/" rel="noopener noreferrer"&gt;Git et GitHub&lt;/a&gt;, puis valorisez-les dans votre &lt;a href="https://neurautech.com/cv-developpeur-junior/" rel="noopener noreferrer"&gt;CV de développeur junior&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Quel métier pour quel profil ?
&lt;/h2&gt;

&lt;p&gt;Ce tableau reflète notre lecture des sources, pas une règle de recrutement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Votre profil&lt;/th&gt;
&lt;th&gt;Métier à viser d'abord&lt;/th&gt;
&lt;th&gt;Niveau d'entrée&lt;/th&gt;
&lt;th&gt;Route conseillée&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Étudiant en informatique&lt;/td&gt;
&lt;td&gt;Analyste SOC ou ingénieur sécurité junior&lt;/td&gt;
&lt;td&gt;Bac+3 à Bac+5&lt;/td&gt;
&lt;td&gt;Master ou école avec alternance, label SecNumedu à vérifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrateur système ou réseau&lt;/td&gt;
&lt;td&gt;Analyste SOC, ingénieur sécurité&lt;/td&gt;
&lt;td&gt;Expérience technique&lt;/td&gt;
&lt;td&gt;Security+, puis mobilité interne&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Développeur&lt;/td&gt;
&lt;td&gt;DevSecOps, pentest applicatif&lt;/td&gt;
&lt;td&gt;Expérience en développement&lt;/td&gt;
&lt;td&gt;Sécurité du code, challenges web, OSCP+ plus tard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Juriste, auditeur, chef de projet&lt;/td&gt;
&lt;td&gt;Consultant GRC&lt;/td&gt;
&lt;td&gt;Bac+5 souvent attendu&lt;/td&gt;
&lt;td&gt;ISO 27001 Lead Implementer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconversion sans base informatique&lt;/td&gt;
&lt;td&gt;Technicien ou administrateur, puis SOC&lt;/td&gt;
&lt;td&gt;Variable&lt;/td&gt;
&lt;td&gt;Formation certifiante RNCP, puis spécialisation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Profil expérimenté en sécurité&lt;/td&gt;
&lt;td&gt;Architecte, réponse aux incidents, RSSI&lt;/td&gt;
&lt;td&gt;Plusieurs années&lt;/td&gt;
&lt;td&gt;CISSP, management&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le marché caché pèse lourd&amp;nbsp;: 43&amp;nbsp;% des répondants de l'Observatoire ont été recrutés par recommandation, approche directe ou candidature spontanée. Préparez aussi les épreuves techniques&amp;nbsp;: notre article sur l'&lt;a href="https://neurautech.com/entretien-technique-developpeur/" rel="noopener noreferrer"&gt;entretien technique&lt;/a&gt; décrit les étapes habituelles.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que nous n'avons pas pu vérifier
&lt;/h2&gt;

&lt;p&gt;Sources bloquées ou incomplètes le 5 novembre 2026&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Le Panorama des métiers de la cybersécurité de l'ANSSI.&lt;/strong&gt; Le site cyber.gouv.fr a refusé nos requêtes. Les intitulés s'appuient sur l'étude 2025 de l'Observatoire et sur les usages des offres d'emploi&amp;nbsp;; la dernière édition du Panorama n'est pas confirmée.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La liste des formations SecNumedu.&lt;/strong&gt; Même blocage&amp;nbsp;: nous ne donnons ni nombre de formations labellisées ni exemple.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les fiches métiers de l'Apec et de l'Onisep.&lt;/strong&gt; Accès refusé&amp;nbsp;: aucun salaire n'est attribué à l'Apec, et les descriptions de métiers sont notre synthèse, sans relecture de ces fiches ni du Panorama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L'étude 2025 d'ISC2.&lt;/strong&gt; Nous n'avons lu que son communiqué, pas le rapport complet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le calendrier du FCSC 2027.&lt;/strong&gt; Les pages de l'ANSSI qui l'annoncent étaient inaccessibles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les salaires des analystes CSIRT, forensiques et de la menace.&lt;/strong&gt; Nous n'avons trouvé aucune grille sourcée et récente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Le télétravail.&lt;/strong&gt; Aucune source lue ne le chiffre.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root-Me et l'offre gratuite de Hack The Box.&lt;/strong&gt; Conditions non détaillées sur les pages lues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les prix de Security+, du CEH, du CISSP et de l'ISO 27001 Lead Implementer.&lt;/strong&gt; Ils n'étaient pas affichés sur les pages officielles lues.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions fréquentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Peut-on travailler dans la cybersécurité sans diplôme ?
&lt;/h3&gt;

&lt;p&gt;Oui, mais c'est plus long. Dans l'&lt;a href="https://sti.eduscol.education.fr/sites/eduscol.education.fr.sti/files/articles/18365/etude-des-professionnels-de-la-cybersecurite-vf2.pdf" rel="noopener noreferrer"&gt;étude 2025 de l'Observatoire&lt;/a&gt;, 44&amp;nbsp;% des professionnels n'ont ni diplôme ni certification en cybersécurité, mais 63&amp;nbsp;% ont un diplôme en informatique. Sans diplôme, il faut des preuves&amp;nbsp;: certifications, challenges, projets publics.&lt;/p&gt;

&lt;h3&gt;
  
  
  La cybersécurité est-elle un métier d'avenir ?
&lt;/h3&gt;

&lt;p&gt;Les offres ont augmenté de 49&amp;nbsp;% entre 2019 et 2024 selon l'Observatoire, ISC2 estimait le déficit français à 69&amp;nbsp;139 personnes en 2024, et le &lt;a href="https://www.roberthalf.com/fr/fr/tendances/guide-salaires/it-digital" rel="noopener noreferrer"&gt;Guide des salaires 2027 de Robert Half&lt;/a&gt; fait de la cybersécurité la compétence la plus recherchée. Mais la demande vise surtout des profils formés.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combien gagne-t-on dans les métiers de la cybersécurité ?
&lt;/h3&gt;

&lt;p&gt;Selon Robert Half, un ingénieur cybersécurité gagne entre 53&amp;nbsp;000&amp;nbsp;€ (25e percentile) et 82&amp;nbsp;000&amp;nbsp;€ (75e percentile) bruts fixes par an au niveau national, médiane 67&amp;nbsp;000&amp;nbsp;€&amp;nbsp;; un RSSI entre 75&amp;nbsp;000&amp;nbsp;€ et 100&amp;nbsp;000&amp;nbsp;€, médiane 85&amp;nbsp;000&amp;nbsp;€. La grille francilienne de &lt;a href="https://www.licornesociety.com/blog/salaire-cybersecurite" rel="noopener noreferrer"&gt;Licorne Society&lt;/a&gt; place un analyste SOC junior entre 40&amp;nbsp;000 et 48&amp;nbsp;000 euros, et un pentester junior entre 42&amp;nbsp;000 et 50&amp;nbsp;000 euros.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peut-on télétravailler dans la cybersécurité ?
&lt;/h3&gt;

&lt;p&gt;Cela dépend du métier&amp;nbsp;; nous n'avons trouvé aucune statistique fiable. D'après notre lecture des offres, le conseil GRC s'y prête souvent&amp;nbsp;; un SOC en continu ou un poste exigeant une habilitation impose plus de présence sur site. Posez la question en entretien.&lt;/p&gt;




&lt;h2&gt;
  
  
  À propos de l'auteur
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abdelilah Ourti&lt;/strong&gt; est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d'IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur &lt;a href="https://neurautech.com/author/neurautech/" rel="noopener noreferrer"&gt;sa page auteur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Méthode.&lt;/strong&gt; Synthèse de sources publiques consultées le 5 novembre 2026&amp;nbsp;: étude 2025 de l'Observatoire des métiers (ANSSI, Afpa, DGEFP), études d'ISC2 (traduites par nos soins), grilles des cabinets Robert Half et Licorne Society, France compétences et pages officielles des certifications. Aucun recruteur n'a été interrogé, aucune formation n'a été suivie, aucun lien n'est affilié et aucune relation commerciale ne lie l'auteur aux organismes mentionnés.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Une erreur ou un chiffre périmé&amp;nbsp;?&lt;/strong&gt; Écrivez à &lt;a href="mailto:contact@neurautech.com"&gt;contact@neurautech.com&lt;/a&gt;&amp;nbsp;: l'article sera corrigé et la date de mise à jour modifiée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dernière mise à jour&amp;nbsp;: 5 novembre 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image d'en-tête&amp;nbsp;: Tima Miroshnichenko via Pexels (Pexels License).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurite</category>
      <category>carriere</category>
      <category>formation</category>
      <category>certifications</category>
    </item>
  </channel>
</rss>
