<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title><![CDATA[Anthony Pena]]></title>
    <description><![CDATA[Libriste mais pas extrémiste.]]></description>
    <link>https://anthonypena.fr</link>
    <generator>Anthony Pena's blog v1.0.0</generator>
    <lastBuildDate>Wed, 02 Sep 2026 16:18:47 GMT</lastBuildDate>
    <ttl>60</ttl>
    <image>
      <url>https://anthonypena.fr/favicon.png</url>
      <title>Anthony Pena</title>
      <link>https://anthonypena.fr</link>
    </image>
    <atom:link href="https://anthonypena.fr/feed.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title><![CDATA[Revue de presse - Septembre 2026]]></title>
      <guid isPermaLink="false">2026/09/01/revue-de-presse-septembre</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/09/01/revue-de-presse-septembre/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Tue, 01 Sep 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-animateenter--animateleave--virer-angularanimations--easyangularkithttpswwweasyangularkitcomblogangularanimateenterleaveremplacerangularanimations"><a href="https://www.easyangularkit.com/blog/angular-animate-enter-leave-remplacer-angular-animations">animate.enter / animate.leave : virer @angular/animations - EasyAngularKit</a><a href="#article-animateenter--animateleave--virer-angularanimations--easyangularkithttpswwweasyangularkitcomblogangularanimateenterleaveremplacerangularanimations" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Angular #Frontend</p>
<p>Tutoriel simple pour se débarrasser de <code>@angular/animation</code> dans 95% des cas et économiser 55-60kb dans votre bundle. Car aujourd&#39;hui ce package peut être remplacé facilement par quelques lignes de CSS </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-plus-d1-francais-sur-3-utilise-lia-pour-draguer-sur-les-applications-de-rencontrehttpswwwphonandroidcomplusd1francaissur3utiliseliapourdraguersurlesapplicationsderencontrehtml"><a href="https://www.phonandroid.com/plus-d1-francais-sur-3-utilise-lia-pour-draguer-sur-les-applications-de-rencontre.html">Plus d&#39;1 Français sur 3 utilise l&#39;IA pour draguer sur les applications de rencontre</a><a href="#article-plus-d1-francais-sur-3-utilise-lia-pour-draguer-sur-les-applications-de-rencontrehttpswwwphonandroidcomplusd1francaissur3utiliseliapourdraguersurlesapplicationsderencontrehtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Société</p>
<p>C&#39;était certain que ça allait arriver : 1/3 des Français sur les services de rencontres utilisent de l&#39;IA pour draguer, 1/3 y songeant… </p>
<p>Plus de 70% disent ne pas avoir avoué l&#39;avoir utilisé à leur partenaire. Certains s&#39;en servent pour avoir des idées de conversation, d&#39;autres vont jusqu&#39;à déléguer entièrement la discussion… </p>
<p>Comme j&#39;ai dit : fallait s&#39;y attendre, mais c&#39;est pas vraiment dans une société comme ça que j&#39;ai envie de vivre perso… </p>
<h3 id="article-1930--jm-keynes-a-predit-que-nous-ne-travaillerions-que-15h--hadrien-menspellenhttpswwwlinkedincomfeedupdateurnliactivity7495521225176354816updateentityurnurn253ali253afs_updatev2253a2528urn253ali253aactivity253a7495521225176354816252cfeed_detail252cempty252cdefault252cfalse2529"><a href="https://www.linkedin.com/feed/update/urn:li:activity:7495521225176354816?updateEntityUrn%3Durn%253Ali%253Afs_updateV2%253A%2528urn%253Ali%253Aactivity%253A7495521225176354816%252CFEED_DETAIL%252CEMPTY%252CDEFAULT%252Cfalse%2529">1930 : JM Keynes a prédit que nous ne travaillerions que 15h… | Hadrien Mens-Pellen</a><a href="#article-1930--jm-keynes-a-predit-que-nous-ne-travaillerions-que-15h--hadrien-menspellenhttpswwwlinkedincomfeedupdateurnliactivity7495521225176354816updateentityurnurn253ali253afs_updatev2253a2528urn253ali253aactivity253a7495521225176354816252cfeed_detail252cempty252cdefault252cfalse2529" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Société #Emploi #Travail</p>
<p>Je cite le post d&#39;Hadrien :</p>
<blockquote>
<p>1930 : JM Keynes a prédit que nous ne travaillerions que 15h par semaine grâce à la mécanisation et l’automatisation 
2018 : David Graeber soutiens la thèse que nous travaillons probablement déjà 15h par semaine, le reste de notre temps de travail serait comblé de tâches « à la con » quand ce n’est pas tout notre job qui est « à la con »</p>
<p>Quand on lit les témoignages dans Bullshit Jobs on comprend que notre modèle cherche à nous occuper plutôt qu’à nous libérer. </p>
<p>Ça m’a fait réfléchir à un angle de l’impact de l’IA dans nos vies. Si elle parvient à automatiser nombre de nos tâches, on ne travaillera pas moins, on aura juste plus de tâches « à la con ». </p>
<p>Je crois pas qu’on ait envie de ça pour notre futur. Si on veut garder l’IA malgré tout ses impacts négatifs, on prévoit quoi pour sortir des bullshit jobs et travailler moins pour gagner plus ?</p>
</blockquote>
<p>Est-ce qu&#39;il ne serait donc pas temps de lancer une transformation de nos sociétés ? Passer d&#39;un monde où pour vivre il faut un emploi alors qu&#39;on voit que le système craque, à un monde où on repartit les richesses pour que tout le monde vive correctement par défaut ? </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-un-adulte-se-fait-passer-pour-une-enfant-sur-xooloo-la-messagerie-destinee-aux-enfantshttpswwwclubiccomactualite625504unadultesefaitpasserpouruneenfantsurxooloolamessageriedestineeauxenfantshtml"><a href="https://www.clubic.com/actualite-625504-un-adulte-se-fait-passer-pour-une-enfant-sur-xooloo-la-messagerie-destinee-aux-enfants.html">Un adulte se fait passer pour une enfant sur Xooloo, la messagerie destinée aux enfants</a><a href="#article-un-adulte-se-fait-passer-pour-une-enfant-sur-xooloo-la-messagerie-destinee-aux-enfantshttpswwwclubiccomactualite625504unadultesefaitpasserpouruneenfantsurxooloolamessageriedestineeauxenfantshtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #Enfants #Mineur #Réseaux-sociaux</p>
<blockquote>
<p>Grégory Véret a admis que rien n’empêche techniquement un adulte de créer un compte en se décrivant comme un mineur. « La plateforme ne peut pas vérifier que la personne est un adulte », a-t-il précisé. Même limite pour les images à caractère sexuel. Leur détection et leur floutage ne sont pas automatiques, et une protection doit être activée sur l’appareil, une étape que Xooloo intègre au parcours destiné aux parents.</p>
</blockquote>
<p>On pourrait trouver des solutions pour faire de la vérification d&#39;âge (au hasard, on pourrait avoir une plateforme avec un certificat scolaire numérique, qui serait rempli par les écoles, et donc y&#39;aurait une vérification humaine distribué). On pourrait activer par défaut tous les filtres qui floutent les contenus dénudés ou autres contenus adultes. On pourrait avoir une alerte automatique à chaque utilisation de certains mots ou combinaison de mot qui provoquerait une alerte à des modérateurs et/ou les parents.</p>
<p>On pourrait faire beaucoup de choses… Et ça paraîtrait légitime à tout le monde vu comment ça protégerait les enfants (seuls vrais utilisateurs de la plateforme…).</p>
<p>Mais le fondateur le dit lui-même qu&#39;ils ne font pas ça, alors qu&#39;il en va de la sécurité des enfants ! </p>
<h3 id="article-cyberattaques--sebastien-lecornu-veut-creer-une-nouvelle-unite-cyber-durgencehttpswwwclubiccomactualite625939cyberattaquessebastienlecornuveutcreerunnouvelleunitecyberdurgencehtml"><a href="https://www.clubic.com/actualite-625939-cyberattaques-sebastien-lecornu-veut-creer-un-nouvelle-unite-cyber-d-urgence.html">Cyberattaques : Sébastien Lecornu veut créer une &quot;nouvelle unité cyber&quot; d&#39;urgence</a><a href="#article-cyberattaques--sebastien-lecornu-veut-creer-une-nouvelle-unite-cyber-durgencehttpswwwclubiccomactualite625939cyberattaquessebastienlecornuveutcreerunnouvelleunitecyberdurgencehtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Piratage #Sécurité #France</p>
<p>Alors que quasi tout le travail de cybersécurité c&#39;est du long court, de l&#39;anticipation, de la prévention, Lecornu veur monter une équipe de pompier qui sera interministériel… </p>
<p>Donc :</p>
<ul>
<li>on ne va toujours pas former pour de vrai les agents pour limiter les erreurs humaines ;</li>
<li>on ne va pas imposer des mécanismes d&#39;authentification fort comme du MFA avec clé physique ;</li>
<li>on ne va pas faire du pentest continue des applications pour détecter au maximum en amont les failles ;</li>
<li>on ne va pas renforcer la sécurité des systèmes ;</li>
<li>mettre des mécanismes d&#39;alerting pour détecter les attaques en cours ;</li>
</ul>
<p>Mais :</p>
<ul>
<li>on va envoyer des gens après piratage constater les dégâts ;</li>
<li>on va envoyer des renforts trop tard sans aucune connaissance du métier (donc en proposant sûrement des trucs incohérents et inapplicable sur le cas cible) ;</li>
<li>on va cramer du pognon et des équipes pour faire des bilans d&#39;attaque plutôt que renforcer la sécurité à long terme ;</li>
<li>on va exiger des rapports à transmettre directement au premier ministre ;</li>
</ul>
<p>Merci Lecornu, mais on a pas besoin de vous pour gérer la sécurité, on a besoin que vous fassiez confiance dans les experts du secteur, dans des internes avec des budgets au long cours, des plans de transformation cybersécurité pour boucher les trous et corriger les pratiques étape par étape, d&#39;arrêter de faire semblant en prenant des cabinets de conseils 🤬 </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-lancer-tout-son-projet-en-local--une-mauvaise-habitude-httpsdevtosingeboblancertoutsonprojetenlocalunemauvaisehabitude3jd8"><a href="https://dev.to/singebob/lancer-tout-son-projet-en-local-une-mauvaise-habitude--3jd8">Lancer tout son projet en local : une mauvaise habitude ?</a><a href="#article-lancer-tout-son-projet-en-local--une-mauvaise-habitude-httpsdevtosingeboblancertoutsonprojetenlocalunemauvaisehabitude3jd8" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#CI #Métier-de-dev #Dev</p>
<p>J&#39;aime beaucoup ce passage :</p>
<blockquote>
<p>Le local c&#39;est &quot;ma vérité&quot;. La CI c&#39;est &quot;la vérité partagée&quot;. Quand vous vérifiez en local, vous vérifiez pour vous. Quand le test passe en CI, il vérifie pour toute l&#39;équipe, sur un environnement propre, reproductible, identique pour tout le monde.</p>
<p>C&#39;est pas une question d&#39;outil. C&#39;est une question de confiance. Aujourd&#39;hui votre confiance repose sur votre machine, votre état, votre session. L&#39;objectif c&#39;est de déplacer cette confiance vers un filet qui appartient à toute l&#39;équipe.</p>
</blockquote>
<p>Vraiment complètement d&#39;accord : votre CI est là pour casser souvent avant que ça casse votre prod parce que vous avez loupé un truc ; votre CI est là pour valider que le travail commun est ok ; faut-il faire les bons efforts pour que ce commun soit bon c&#39;est tout. </p>
<h3 id="article-le-mystere-du-nombre-6174--shortshttpsyoutubecomshorts7buxn6uojo8"><a href="https://youtube.com/shorts/7BUXN6UoJo8">Le mystère du nombre 6174 ! #shorts</a><a href="#article-le-mystere-du-nombre-6174--shortshttpsyoutubecomshorts7buxn6uojo8" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Mathématiques</p>
<p><a href="https://youtube.com/shorts/7BUXN6UoJo8"><img src="https://i.ytimg.com/vi/7BUXN6UoJo8/hqdefault.jpg" alt="https://youtube.com/shorts/7BUXN6UoJo8" title="Youtube video preview"/></a></p>
<p>Bizarrerie mathématique : la constante de Kaprekar, qui vaut 6174.</p>
<p>Si vous prenez n&#39;importe quel nombre à 4 chiffres (sauf un nombre avec que des chiffres identiques comme 2222), que vous triez d&#39;un côté les chiffres du plus grand au plus petit, de l&#39;autre du plus petit au plus grand, que vous faire la soustraction, puis recommencez avec le nouveau nombre, vous finirez par tomber sur 6174.</p>
<p>Pour les nombres à 3 chiffres c&#39;est 495. </p>
<p>Et on retrouve ça pour d&#39;autres nombre de chiffre. C&#39;est inutile mais fascinant 🤩 </p>
<h3 id="article-gimp-va-introduire-un-nouveau-format-et-ameliorer-le-support-des-psdhttpswwwclubiccomactualite625648gimpvaameliorerlesupportdespsdavecunnouveauformathtml"><a href="https://www.clubic.com/actualite-625648-gimp-va-ameliorer-le-support-des-psd-avec-un-nouveau-format.html">GIMP va introduire un nouveau format et améliorer le support des PSD</a><a href="#article-gimp-va-introduire-un-nouveau-format-et-ameliorer-le-support-des-psdhttpswwwclubiccomactualite625648gimpvaameliorerlesupportdespsdavecunnouveauformathtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#GIMP #OpenSource</p>
<p>Changement assez fort côté GIMP : introduire un nouveau format de projet tout en conservant la capacité d&#39;ouvrir les XCF (donc il faut s&#39;attendre à ce qu&#39;on soit incité à sauvegarder dans le nouveau format quand on ouvre les XCF). </p>
<p>Le but derrière c&#39;est passer d&#39;un format binaire à un projet à base de XML compressé pour gagner en perf à la sauvegarde (on peut enregistrer que ce qui bouge), avoir une sauvegarde automatique, et améliorer la capacité à faire de l&#39;édition non destructrice (on applique des transformations qui s&#39;empilent, sans jamais modifier avant d&#39;exporter en image) </p>
<h3 id="article-fin-de-microsoft-publisher-apres-35-ans-de-service--liens-en-vrac-de-sebsauvagehttpssebsauvagenetlinks6ouklg"><a href="https://sebsauvage.net/links/?6oukLg">Fin de Microsoft Publisher après 35 ans de service - Liens en vrac de sebsauvage</a><a href="#article-fin-de-microsoft-publisher-apres-35-ans-de-service--liens-en-vrac-de-sebsauvagehttpssebsauvagenetlinks6ouklg" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Microsoft #Logiciel</p>
<p>Je dirais pas mieux que Sebsauvage :</p>
<blockquote>
<p>Malgré son <em>immense</em> popularité, Microsoft va tuer le logiciel Publisher.
(Oui si vous avez encore plein de travaux dans ce format fermé et propriétaire (.pub), vous pouvez pleurer. C&#39;est tout l&#39;intérêt des formats ouverts !)</p>
<p>La raison invoquée par Microsoft ? C&#39;est pour « améliorer votre abonnement Microsoft 365 ».  #troll</p>
</blockquote>
<h3 id="article-hype-driven-development--lestamitechhttpsestamitechfrepisodeac2824883c9343b3a27ae6b6ae674e7f"><a href="https://estamitech.fr/episode/ac282488-3c93-43b3-a27a-e6b6ae674e7f">Hype Driven Development — L&#39;EstamiTech</a><a href="#article-hype-driven-development--lestamitechhttpsestamitechfrepisodeac2824883c9343b3a27ae6b6ae674e7f" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Podcast #Métier-de-dev</p>
<p>Je vous le dis directement : ça m&#39;a fait du bien d&#39;écouter le discours de Nicolas Delsaux (directeur technique de Zenika Lilles) qui va à contre courant de la sacro sainte hype ! </p>
<p>Il parle de beaucoup de chose : des langages de programmation, d&#39;IA, de cloud, d&#39;archi, de design pattern, etc.</p>
<p>Et je trouve que sa vision est plutôt claire : rien n&#39;est à jeter, il faut juste remettre à sa place chaque source de hype, il n&#39;y a rien de magiquement universel, il faut utiliser le bon outil pour la bonne tâche, en tant que développeur c&#39;est notre travail de choisir le bon outil, le bon pattern.</p>
<p>Bref : écoutez ce podcast ! </p>
<p>Au passage (si tu passes par là) Ludovic (le créateur de l&#39;Estamicast) : merci pour tes podcasts, j&#39;avoue que je découvre, mais j&#39;en ai écouté pas mal d&#39;épisodes en août et c&#39;est un plaisir à écouter ! </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Tentacule ou comment sauter de repo en repo en claquement de ventouse]]></title>
      <guid isPermaLink="false">2026/08/25/tentacule-ou-comment-sauter-de-repo-en-repo-en-un-claquement-de-ventouse</guid>
      <description><![CDATA[<p>Que ce soit côté pro ou perso, j&#39;ai toujours besoin de naviguer entre plusieurs dépôts git, parfois …</p>
]]></description>
      <link>https://anthonypena.fr/2026/08/25/tentacule-ou-comment-sauter-de-repo-en-repo-en-un-claquement-de-ventouse/index.html</link>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Présentation projet]]></category>
      <category><![CDATA[CLI]]></category>
      <pubDate>Tue, 25 Aug 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Que ce soit côté pro ou perso, j&#39;ai toujours besoin de naviguer entre plusieurs dépôts git, parfois venant de différentes forges (github.com, gitlab.com, gitlab d&#39;entreprise, forge perso, etc.) et il faut l&#39;avouer c&#39;est un moment de friction… J&#39;ai corrigé le souci de mon côté en créant un CLI en Rust (parce qu&#39;envie de refaire du Rust en ce moment), je vous explique !</p>
<h2 id="article-lavant-tentacule">L&#39;avant Tentacule<a href="#article-lavant-tentacule" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai cette problématique du multi-repo depuis un paquet d&#39;année, et jusque-là j&#39;avais opté pour un système très très basique : des alias bash.</p>
<p>Je maintenais donc à la main, un set d&#39;alias du style</p>
<pre><code class="hljs language-Bash"><span class="hljs-built_in">alias</span> go-proj1=$(<span class="hljs-built_in">cd</span> ~/path/to/proj1)
<span class="hljs-built_in">alias</span> go-proj2=$(<span class="hljs-built_in">cd</span> ~/path/to/proj2)
...<div aria-hidden="true" class="language-tag">Bash</div>
</code></pre><p>C&#39;est pas passionnant à maintenir, c&#39;est error-prone (comme c&#39;est constamment des ajustements manuels, c&#39;est facile de faire des typos), c&#39;est un pavé qui prend pas mal de place dans mon <code>.bashrc</code> / <code>.zshrc</code>, il faut penser à l&#39;ajouter à chaque nouveau clone… Mais on va pas se mentir : ça fonctionne très bien !</p>
<h2 id="article-lheure-dune-vraie-solution">L&#39;heure d&#39;une vraie solution<a href="#article-lheure-dune-vraie-solution" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ce que j&#39;ai en tête c&#39;est d&#39;avoir un CLI qui va scanner tous les dépôts sur ma machine, et à la demande je veux pouvoir sauter directement dans le dossier d&#39;un dépôt quand j&#39;ai besoin sans avoir à réfléchir où je suis et/ou comment je m&#39;y déplace.</p>
<p>Dans l&#39;idée c&#39;est facile, parcourir récursivement des dossiers, enregistrer certains chemins dans un fichier, puis pouvoir chercher dans le fichier. C&#39;est super simple ! Finalement c&#39;est une sorte de commande <code>cd</code> mais avec une autre manière de se déplacer.</p>
<p>Mais y&#39;a un point compliqué : on ne peut pas créer un exécutable qui va changer le chemin courant de votre shell.</p>
<p>En effet, <code>cd</code> c&#39;est une fonction dite &quot;builtin&quot; (votre shell peut vous le confirmer si vous faites <code>type cd</code>, vous devriez avoir <code>cd is a shell builtin</code>), c&#39;est à dire que quand vous tapez <code>cd truc</code>, en fait votre shell (bash, zsh, etc.) va appeler directement une fonction interne au binaire qui gère votre shell, pas un programme externe. Donc vous ne pouvez pas remplacer juste <code>cd</code> via une autre commande. Donc il faut tricher.</p>
<p>J&#39;ai envisagé deux options :</p>
<ul>
<li>la première c&#39;est créer une fonction bash qui appellera notre CLI <code>tentacule</code> et donnera la réponse à <code>cd</code> pour se déplacer, c&#39;est pas forcément le plus clair en tant qu&#39;utilisateur, mais c&#39;est simple et ça fonctionne comme système ;</li>
<li>la seconde c&#39;est de créer un shell, qui va intercepter certaines commandes et redonner à un autre shell le reste, je trouve ça encore moins simple à configurer, c&#39;est super intrusif, ça peut introduire des bugs partout… mais ça doit fonctionner ;</li>
</ul>
<p>Vous vous en doutez surement : j&#39;ai pris la première option.</p>
<p>Donc pour configurer <code>tentacule</code>, il faut ajouter une ligne dans votre <code>.bashrc</code> / <code>.zshrc</code> :</p>
<pre><code class="hljs language-Bash"><span class="hljs-keyword">function</span> go { found=<span class="hljs-string">&quot;<span class="hljs-subst">$(tentacule find ${@:1})</span>&quot;</span>;<span class="hljs-keyword">if</span> [ $? -eq 0 ]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">cd</span> <span class="hljs-variable">$found</span>;<span class="hljs-keyword">fi</span> }<div aria-hidden="true" class="language-tag">Bash</div>
</code></pre><p>Si on l&#39;écrit de manière formatée et avec des commentaires ça se comprend assez bien je trouve :</p>
<pre><code class="hljs language-Bash"><span class="hljs-keyword">function</span> go {
    <span class="hljs-comment"># $@ = tableau avec tous les paramètres</span>
    <span class="hljs-comment"># ${@:1} = tableau avec tous les paramètres à partir de l&#x27;index 1</span>
    <span class="hljs-comment">#          (les tableaux en bash sont indéxé à partir de 0)</span>
    <span class="hljs-comment"># </span>
    <span class="hljs-comment"># appeler tentacule find en lui passant les arguments qu&#x27;on </span>
    <span class="hljs-comment"># avait passé à la fonction go, mais en retirant le premier</span>
    <span class="hljs-comment"># argument</span>
    <span class="hljs-comment"># </span>
    <span class="hljs-comment"># donc &quot;go one two&quot; devient &quot;one two&quot; et est passé à la commande</span>
    found=<span class="hljs-string">&quot;<span class="hljs-subst">$(tentacule find ${@:1})</span>&quot;</span>
    <span class="hljs-comment"># $? = le code de retour de la commande précédente</span>
    <span class="hljs-comment">#      (ici c&#x27;est &quot;tentacule find ...&quot;)</span>
    <span class="hljs-comment">#</span>
    <span class="hljs-comment"># si $? est égal à zéro, alors on cd dans le chemin contenu </span>
    <span class="hljs-comment"># dans $found</span>
    <span class="hljs-comment"># sinon on ne fait rien (tentacule va afficher une erreur si le code</span>
    <span class="hljs-comment"># retour n&#x27;est pas 0)</span>
    <span class="hljs-keyword">if</span> [ $? -eq 0 ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">cd</span> <span class="hljs-variable">$found</span>
    <span class="hljs-keyword">fi</span>
}<div aria-hidden="true" class="language-tag">Bash</div>
</code></pre><p>Plutôt simple non ?</p>
<h2 id="article-au-cur-de-la-bestiole-">Au cœur de la bestiole !<a href="#article-au-cur-de-la-bestiole-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Vous pouvez trouver tout le code <a href="https://github.com/kuroidoruido/tentacule">ici</a>, donc je ne vais pas vous montrer tout le code. J&#39;ai juste envie de vous montrer quelques points que je trouve plutôt intéressant.</p>
<p>À noter que j&#39;ai fait un choix très net dès le début : aucune dépendance. Pour ce projet, un peu par challenge personnel, je ne veux dépendre de rien, mais aussi par volonté de réduire l&#39;effort de maintenance à long terme (aucune dépendance à mettre à jour, juste à recompiler si y&#39;a des nouveautés intéressantes dans Rust et/ou sa toolchain).</p>
<p>En termes de fonctionnement global c&#39;est assez simple :</p>
<ul>
<li>prendre les paramètres de la commande ;</li>
<li>les donner à une brique qui va déduire la commande qu&#39;on veut lancer et les paramètres associés ;</li>
<li>prendre cette commande et déduire la fonction qu&#39;on veut lancer ;</li>
<li>lancer la fonction ;</li>
</ul>
<p>C&#39;est basico-basique mais ça fonctionne plutôt bien. Surtout avec le système d&#39;enum de Rust qui permet nativement de faire des <a href="https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es#Type_alg%C3%A9brique">ADT (Algebraic Data Type)</a> :</p>
<pre><code class="hljs language-Rust"><span class="hljs-meta">#[derive(Debug, PartialEq)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">Command</span> {
    Help,
    Version,
    <span class="hljs-title function_ invoke__">Index</span>(IndexSubCommand),
    <span class="hljs-title function_ invoke__">Find</span>(FindSubCommand),
}

<span class="hljs-meta">#[derive(Debug, PartialEq)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">IndexSubCommand</span> {
    Help,
    Refresh,
    List,
}

<span class="hljs-meta">#[derive(Debug, PartialEq)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">FindSubCommand</span> {
    Help,
    <span class="hljs-title function_ invoke__">Repo</span>(<span class="hljs-type">Vec</span>&lt;<span class="hljs-type">String</span>&gt;),
}<div aria-hidden="true" class="language-tag">Rust</div>
</code></pre><blockquote>
<p>Note : <code>Vec&lt;String&gt;</code> c&#39;est équivalent en termes d&#39;usage à un <code>string[]</code> (en TypeScript / JavaScript) ou <code>List&lt;String&gt;</code> (en Java).</p>
</blockquote>
<p>Au premier niveau on a une <code>Command</code>, chaque option de <code>Command</code> a ou pas un paramètre qui est une sous-commande, chaque sous-commande est sur le même modèle. Sur chaque <code>enum</code>, on retrouve <code>#[derive(Debug, PartialEq)]</code> qui permet d&#39;indiquer au compilateur qu&#39;on veut que notre type dérive les <a href="https://fr.wikipedia.org/wiki/Trait_(programmation)">traits</a> <code>Debug</code> (permet d&#39;avoir un affichage automatique pour du debug technique) et <code>PartialEq</code> (permet de comparer les valeurs avec un <code>==</code>).</p>
<p>À partir de ça j&#39;ai juste une fonction qui va inspecter le tableau des paramètres de la commande pour renvoyer la bonne commande.</p>
<p>Pour choisir le bon appel de fonction par rapport à la commande, j&#39;ai quelque chose de très simple :</p>
<pre><code class="hljs language-Rust"><span class="hljs-keyword">use</span> crate::args::{Command, IndexSubCommand, FindSubCommand};

<span class="hljs-keyword">fn</span> <span class="hljs-title function_">run_command</span>(command: Command, root_dir: <span class="hljs-type">String</span>) {
    <span class="hljs-keyword">match</span> command {
        Command::Help =&gt; command::global_help::<span class="hljs-title function_ invoke__">run</span>(),
        Command::Version =&gt; command::version::<span class="hljs-title function_ invoke__">run</span>(),

        Command::<span class="hljs-title function_ invoke__">Index</span>(IndexSubCommand::Help) =&gt; command::index::help::<span class="hljs-title function_ invoke__">run</span>(),
        Command::<span class="hljs-title function_ invoke__">Index</span>(IndexSubCommand::Refresh) =&gt; command::index::refresh::<span class="hljs-title function_ invoke__">run</span>(root_dir).<span class="hljs-title function_ invoke__">expect</span>(<span class="hljs-string">&quot;&quot;</span>),
        Command::<span class="hljs-title function_ invoke__">Index</span>(IndexSubCommand::List) =&gt; command::index::list::<span class="hljs-title function_ invoke__">run</span>().<span class="hljs-title function_ invoke__">expect</span>(<span class="hljs-string">&quot;&quot;</span>),
        Command::<span class="hljs-title function_ invoke__">Find</span>(FindSubCommand::Help) =&gt; command::find::help::<span class="hljs-title function_ invoke__">run</span>(),
        Command::<span class="hljs-title function_ invoke__">Find</span>(FindSubCommand::<span class="hljs-title function_ invoke__">Repo</span>(words)) =&gt; command::find::repo::<span class="hljs-title function_ invoke__">run</span>(words).<span class="hljs-title function_ invoke__">expect</span>(<span class="hljs-string">&quot;&quot;</span>),
    }
}<div aria-hidden="true" class="language-tag">Rust</div>
</code></pre><p>Ici on commence à voir la force du combo ADT + pattern matching : cette fonction est très descriptive. <code>match command</code> va lancer du pattern-matching sur la commande, ensuite pour chaque valeur possible (en pouvant spécifier le pattern sur plusieurs niveaux, <code>Command::Index(IndexSubCommand::Help)</code> et <code>Command::Index(IndexSubCommand::Refresh)</code> sont deux patterns différents) je crée un pattern et je l&#39;associe à un appel de fonction. Comme c&#39;est un pattern-matching sur une enum, si j&#39;oublie un cas, ça ne compilera pas, j&#39;aurais une erreur et je devrais compléter pour continuer.</p>
<p>Avec Rust vous manipulez deux niveaux de langage : le langage Rust lui-même et le langage de macro de Rust.</p>
<p>Voici un exemple simple qui montre ça :</p>
<pre><code class="hljs language-Rust"><span class="hljs-keyword">pub</span> <span class="hljs-keyword">fn</span> <span class="hljs-title function_">get_app_version</span>() <span class="hljs-punctuation">-&gt;</span> <span class="hljs-type">String</span> {
    <span class="hljs-built_in">env!</span>(<span class="hljs-string">&quot;CARGO_PKG_VERSION&quot;</span>).<span class="hljs-title function_ invoke__">to_string</span>()
}<div aria-hidden="true" class="language-tag">Rust</div>
</code></pre><p>Cette fonction vise à renvoyer la version de l&#39;application. Donc on déclare une fonction tout ce qu&#39;il y a de plus simple : pas de paramètre, retourne une chaîne de caractère. Par contre vous noterez l&#39;appel à <code>env!()</code>, et ce n&#39;est pas une typo d&#39;avoir un <code>!</code> après le nom de la fonction, c&#39;est qu&#39;on est pas face à un appel de fonction Rust mais un appel de macro. En fait <code>env!(&quot;CARGO_PKG_VERSION&quot;)</code> sera exécuté / interprété par le compilateur puis remplacé par <code>&quot;0.1.0&quot;</code> (car dans mon cas, quand j&#39;écris ces lignes, j&#39;ai <code>version = &quot;0.1.0&quot;</code> dans mon <code>Cargo.toml</code>).</p>
<p>Donc après la passe d&#39;exécution des macros, la même fonction devient :</p>
<pre><code class="hljs language-Rust"><span class="hljs-keyword">pub</span> <span class="hljs-keyword">fn</span> <span class="hljs-title function_">get_app_version</span>() <span class="hljs-punctuation">-&gt;</span> <span class="hljs-type">String</span> {
    <span class="hljs-string">&quot;0.1.0&quot;</span>.<span class="hljs-title function_ invoke__">to_string</span>()
}<div aria-hidden="true" class="language-tag">Rust</div>
</code></pre><p>C&#39;est très puissant ce système de macro, car ça permet d&#39;avoir pas mal de chose qui sont résolues pendant la compilation, pour permettre des choses plus efficaces à l&#39;exécution. Je vous encourage à aller jeter un coup d&#39;œil à mon <a href="https://github.com/kuroidoruido/tentacule/blob/main/src/utils/logger.rs">logger</a> que j&#39;ai écrit avec des macros.</p>
<p>Pour finir je voudrais parler des tests : pas besoin d&#39;un outil externe, tout est inclus dans la toolchain pour des tests courants. Pas non plus d&#39;obligation de séparer les tests du code métier dans des fichiers séparés. Dans le même fichier que celui qui défini les enums <code>Command</code>, <code>IndexSubCommand</code> et <code>FindSubCommand</code>, j&#39;ai à la fois la fonction <code>get_command</code> qui va parser les arguments et les tests associés dans un module dédié aux tests avec une annotation de configuration de test <code>#[cfg(test)]</code> permettant d&#39;indiquer au compilateur de supprimer ce code pour la release.</p>
<pre><code class="hljs language-Rust"><span class="hljs-meta">#[cfg(test)]</span>
<span class="hljs-keyword">mod</span> tests {
    <span class="hljs-keyword">use</span> super::*;

    <span class="hljs-meta">#[test]</span>
    <span class="hljs-keyword">fn</span> <span class="hljs-title function_">test_unknown_command_return_global_help</span>() {
        <span class="hljs-built_in">assert_eq!</span>(
            <span class="hljs-title function_ invoke__">get_command</span>(<span class="hljs-built_in">vec!</span>[<span class="hljs-type">String</span>::<span class="hljs-title function_ invoke__">from</span>(<span class="hljs-string">&quot;i_do_not_exist&quot;</span>)]),
            ( Command::Help, Flags { log_level: LogLevel::Warn } )
        );
    }

    <span class="hljs-comment">// ...</span>
}<div aria-hidden="true" class="language-tag">Rust</div>
</code></pre><p>Sinon à moins de n&#39;avoir jamais fait de test unitaire, c&#39;est assez limpide comment fonctionne ce test, il faut simplement s&#39;habituer à ce que tout soit en snake_case en Rust (j&#39;avoue plutôt utilisé du camelCase au quotidien faisant surtout du TypeScript et Java).</p>
<h2 id="article-demo-time-">Demo time !<a href="#article-demo-time-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Passons au plus intéressant : ça donne quoi en pratique ?</p>
<figure>
<img src="https://anthonypena.fr/2026/08/25/tentacule-ou-comment-sauter-de-repo-en-repo-en-un-claquement-de-ventouse/img/demo.gif" alt="Démonstration de tentacule avec un refresh de l&#39;index et une navigation" is="img-zoom"/>
<figcaption>Démonstration de tentacule avec un refresh de l&#39;index et une navigation</figcaption>
</figure>
<p>On ne peut pas faire grand-chose avec <code>tentacule</code>, mais on peut faire l&#39;essentiel :</p>
<ul>
<li><code>tentacule help</code> va rappeler l&#39;ensemble des commandes ;</li>
<li><code>tentacule version</code> va donner la version de <code>tentacule</code> ;</li>
<li><code>tentacule index refresh</code> va vous permettre de scanner les dépôts git ;</li>
<li><code>tentacule index list</code> va vous permettre d&#39;afficher les dépôts précédemment scannés ;</li>
<li><code>tentacule find &lt;foo&gt;</code> va vous permettre de rechercher dans l&#39;index une entrée qui matcherait le(s) mot(s) que vous passez ;</li>
</ul>
<p>La force du truc à mon avis c&#39;est qu&#39;on va matcher le path complet, sans tenir compte de la case.</p>
<p>Par exemple, avec cet index :</p>
<pre><code>/home/anthony/Projet/tentacule
/home/anthony/Projet/blog
/home/anthony/Projet/star-blog
/home/anthony/Projet/OctoDeps
</code></pre><p>On aura ce genre de réponse :</p>
<pre><code class="hljs language-Bash">&gt; tentacule find tentacule <span class="hljs-comment"># ici on match exactement le nom du dossier et il n&#x27;y a pas d&#x27;autres options</span>
/home/anthony/Projet/tentacule

&gt; tentacule find ten <span class="hljs-comment"># ici on match partiellement le nom du dossier mais c&#x27;est le seul match</span>
/home/anthony/Projet/tentacule

&gt; tentacule find blog <span class="hljs-comment"># ici &quot;blog&quot; est présent dans deux chemins différents donc on a une erreur</span>
thread <span class="hljs-string">&#x27;main&#x27;</span> (4885) panicked at /home/anthony/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tentacule-0.1.0/src/main.rs:31:45:
: <span class="hljs-string">&quot;Multiple matches: /home/anthony/Projet/blog, /home/anthony/Projet/star-blog&quot;</span>
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

&gt; tentacule find /blog <span class="hljs-comment"># par contre avec &quot;/blog&quot; on a plus qu&#x27;une occurrence, donc ça fonctionne</span>
/home/anthony/Projet/blog

&gt; tentacule find blog star <span class="hljs-comment"># &quot;blog&quot; ça donne une erreur mais si on couple avec &quot;star&quot; on a bien un seul match</span>
/home/anthony/Projet/star-blog

&gt; tentacule find octo <span class="hljs-comment"># ici on a un match car on ignore la case dans le path</span>
/home/anthony/Projet/OctoDeps

&gt; tentacule find Octo <span class="hljs-comment"># ici on ne trouve rien, car on ignore pas la case sur les mots en entrée</span>
thread <span class="hljs-string">&#x27;main&#x27;</span> (5009) panicked at /home/anthony/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tentacule-0.1.0/src/main.rs:31:45:
: <span class="hljs-string">&quot;No repo found&quot;</span>
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace<div aria-hidden="true" class="language-tag">Bash</div>
</code></pre><p>Ça vous donne une idée de l&#39;état actuel du projet. C&#39;est pas parfait, mais ça fonctionne !</p>
<h2 id="article-le-futur-de-ce-cli">Le futur de ce CLI<a href="#article-le-futur-de-ce-cli" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Si vous me suivez, vous me connaissez, j&#39;ai évidemment beaucoup d&#39;idées pour la suite ! 😇</p>
<p>Déjà j&#39;aimerais passer en 1.0.0 rapidement, il faut juste que je travaille quelques point avant :</p>
<ul>
<li>ajouter plus de tests : il y a quelques tests mais pas assez à mon goût, j&#39;aimerais pouvoir être bloqué à la moindre régression ;</li>
<li>avoir un pipeline sur Github Actions sur chaque PR et pour la release : côté PR ça permettrait d&#39;être un peu plus structuré et de valider le code avant de basculer sur master, côté release ça permettrait d&#39;avoir une automatisation de la publication avec tout ce qui va bien ;</li>
<li>avoir des releases définies sur Github pour pouvoir y attacher les binaires de release prêt à l&#39;usage ;</li>
<li>retravailler les sorties d&#39;erreurs : c&#39;est simple côté code, mais côté utilisateur c&#39;est moche et c&#39;est pas propre ;</li>
<li>je vais renommer la fonction <code>go</code> en <code>t</code> ou <code>to</code> : le compilateur du langage Go c&#39;est <code>go</code> donc ça rentrerait en conflit sur les machines des développeurs Go, donc autant changer maintenant… ;</li>
</ul>
<p>Évidemment pas mal d&#39;autres idées qui viendront plus tard.</p>
<p>J&#39;ai en tête d&#39;introduire un fichier de configuration pour paramétrer de manière globale <code>tentacule</code> — à priori définir le dossier racine (en plus de variable d&#39;environnement), spécifier une liste de dossiers/fichiers à ignorer pendant le scan, activer/désactiver le scan des dossiers cachés (actuellement ils sont ignorés, mais ça pourrait être utile de pouvoir l&#39;activer), peut-être des alias de chemin (soit vers des dépôts soit vers complètement d&#39;autres dossiers) — à voir dans le temps comment ça évolue aussi.</p>
<p>J&#39;ai aussi pensé à minima deux autres commandes. La première c&#39;est <code>tentacule clone &lt;repo&gt;</code> qui viendrait cloner un dépôt dans un dossier spécifique, en suivant une certaine hiérarchie du type <code>&lt;root&gt;/&lt;domaine du repo&gt;/&lt;groups et/ou organisations&gt;/&lt;nom du repo&gt;</code>, permettant d&#39;avoir un point central organisé pour ranger tous les dépôts qu&#39;on clone, sans avoir à naviguer dans les dossiers avant de cloner. Comme ce serait une commande <code>tentacule</code> qui viendrait cloner (en appelant <code>git</code> dans le <code>$PATH</code> de l&#39;utilisateur), on pourrait en profiter pour l&#39;ajouter au passage dans l&#39;index, et du coup on pourrait juste faire <code>tentacule clone &lt;repo&gt;</code> puis <code>go repo</code>. La seconde commande c&#39;est <code>tentacule pull</code> (peut-être <code>tentacule fetch</code> dans la même logique) pour appliquer un <code>git pull</code> sur tous les dépôts de l&#39;index d&#39;un coup. C&#39;est un peu bourrin, mais personnellement ça me servirait régulièrement de pouvoir faire ça donc j&#39;y réfléchis.</p>
<p>En l&#39;état, <code>tentacule</code> ne gère pas les worktrees, peut-être que ce serait utile de pouvoir le faire, peut-être que c&#39;est une option qui serait à gérer sur <code>tentacule clone</code> pour setup correctement un worktrees facilement exploitable.</p>
<p>J&#39;aimerais bien explorer l&#39;idée d&#39;un <code>tentacule find --color</code> pour mettre en évidence le match qui est fait pour aider à la prise en main. C&#39;est très optionnel je pense, mais je trouve ça intéressant à développer de mon côté.</p>
<p>Enfin, j&#39;aimerais trouver une solution pour me greffer sur le <code>git clone</code> et faire un refresh automatique à chaque appel. Peut-être pas utile si je fais <code>tentacule clone</code> mais à voir.</p>
<h2 id="article-un-mot-sur-rust">Un mot sur Rust<a href="#article-un-mot-sur-rust" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;en profite pour faire un petit laïus sur Rust, car je trouve ce langage super intéressant et plus je pratique, plus j&#39;en suis convaincu !</p>
<p>Déjà c&#39;est super facile de se lancer je trouve. On a pas une phase de mise en place compliqué : il suffit d&#39;installer <code>rustup</code> (qui est une sorte <code>nvm</code> ou <code>sdkman</code>) en 1 ligne de shell, puis lui demander d&#39;installer une toolchain (= suite d&#39;outil pour travailler avec Rust) via <code>rustup toolchain install</code> et c&#39;est bon tout est configuré. Pour créer un nouveau projet c&#39;est simple <code>cargo new &lt;nom du projet&gt;</code>, pour exécuter <code>cargo run</code>, pour lancer les tests <code>cargo test</code>, pour formatter le code <code>cargo fmt</code>, pour avoir du lint <code>cargo clippy</code>, pour compiler <code>cargo build</code>, pour publier un crate (= package partagé avec les sources + la version compilée) <code>cargo publish</code>. Aucun setup préalable pour cette suite d&#39;outils, si y&#39;a un truc qui demande une configuration (comme <code>cargo publish</code>) on aura des messages clairs, des liens, des références pour nous guider. Je trouve ça vraiment incroyable d&#39;avoir quelque chose d&#39;aussi propre !</p>
<p>Côté performance on est très bon, c&#39;est très très proche de ce qu&#39;on aurait en C mais sans les problèmes du C : c&#39;est ancien, c&#39;est très peu cadré, on peut vite faire n&#39;importe quoi (particulière avec la mémoire vu qu&#39;on manipule beaucoup de pointeur), c&#39;est difficile à mettre en place quand on se lance. Et le top c&#39;est qu&#39;on est face à un langage plutôt haut niveau, on retrouve du pattern matching, on a des choses comme des if expression, la syntaxe est légère, on travaille avec des streams (via <code>.iter()</code>) partout sur la manipulation de tableau donc quand on arrive de Java ou TypeScript c&#39;est super naturel.</p>
<p>Le langage est assez rigide, mais on est bien guidé : il y a beaucoup de warnings et erreurs quand on essaie de compiler (<code>cargo run</code> va commencer par compiler, donc même chose), chaque warning/erreur donne des pistes de corrections et la documentation pour comprendre pourquoi c&#39;est un problème ce qu&#39;on a écrit. Globalement on aura plus de mal à compiler qu&#39;avec d&#39;autres langages, mais on sait que ça fonctionne à la sortie. Parce que Rust va vérifier énormément de chose pour s&#39;assurer qu&#39;on ait le moins possible d&#39;erreur de gestion de mémoire.</p>
<p>J&#39;en suis à me dire qu&#39;avec le mouvement &quot;tout codé avec l&#39;IA&quot; (pas d&#39;accord mais bon…) Rust devrait devenir une référence du fait que tout est très explicite donc ça doit être très facile de travailler avec l&#39;IA.</p>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai envie de dire : encore un side project pour moi. C&#39;est petit, ça va s&#39;améliorer avec le temps, mais c&#39;est super intéressant !</p>
<p>J&#39;ai mis quelques heures pour avoir ce résultat, j&#39;aurais pu aller plus vite vu le code avec de l&#39;IA mais mon idée c&#39;était me remettre à Rust, je m&#39;en fiche de prendre du temps, je veux apprendre et comprendre ce que je fais pour maintenir ça dans le temps, pas juste cracher une application jetable. Par contre oui j&#39;ai pris des raccourcis par moments, à commencer par le parcours des dossiers : aller fouiller la doc pour retrouver tous les appels à faire ça prend du temps, demander à Mistral une première version ça m&#39;a pris 1min et j&#39;ai pris le temps de tout restructurer complètement autrement pour que ça colle plus à la structure que je voulais.</p>
<p>Je suis content de ce que j&#39;ai fait, j&#39;avais envie de le partager, c&#39;est fait. J&#39;en reparlerai sûrement ! Au plaisir d&#39;avoir des retours si vous testez !</p>
<p>Sources :</p>
<ul>
<li><a href="https://github.com/kuroidoruido/tentacule">Code source du CLI</a></li>
<li><a href="https://crates.io/crates/tentacule">CLI sur crates.io</a></li>
<li><a href="https://rust-lang.org/">Site du langage Rust</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es#Type_alg%C3%A9brique">ADT (Algebraic Data Type)</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Trait_(programmation)">Trait (programmation)</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A giant, gentle octopus sitting cross-legged on a floating wooden desk, surrounded by ancient magical books representing Git repositories. Each book has kraft paper labels with project names like &#39;tentacule&#39;, &#39;blog&#39;, &#39;OctoDeps&#39;, and &#39;star-blog&#39; written in elegant calligraphy. The octopus uses its eight tentacles to manipulate the books, with one tentacle holding a wooden quill writing in a central grimoire (the Tentacule index), and another pointing to a holographic screen with a wooden frame displaying a list of repositories. The background features an infinite wooden library with curved, gravity-defying shelves and floating books. Maple leaves (8-10, in red, orange, and yellow) fall gently around the scene. Warm, golden afternoon light illuminates the scene, with sunbeams passing through stained glass windows shaped like Git logos or Rust symbols. Soft glowing particles float around the books, symbolizing Rust processes. The octopus has a slightly furry texture with subtle printed circuit patterns on its skin, and its eyes resemble green monochrome terminal screens. A red panda (firefox) is curled up on a cushion in the bottom right corner (≤ 1/3 of the height), slightly turned in 3/4 view, with a golden halo and surrounded by maple leaves. A small Ghibli-inspired robot tidies books in the background. The overall style is Studio Ghibli, with soft lines, warm colors (beige, pale blue, warm orange, moss green), and a cozy, dreamlike atmosphere.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Une page se tourne]]></title>
      <guid isPermaLink="false">2026/08/11/une-page-se-tourne</guid>
      <description><![CDATA[<p>Certains le savaient déjà, mais j&#39;ai quitté SFEIR il y a un gros mois et je trouvais ça intéressant …</p>
]]></description>
      <link>https://anthonypena.fr/2026/08/11/une-page-se-tourne/index.html</link>
      <category><![CDATA[Ego]]></category>
      <category><![CDATA[Edito]]></category>
      <pubDate>Tue, 11 Aug 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Certains le savaient déjà, mais j&#39;ai quitté SFEIR il y a un gros mois et je trouvais ça intéressant d&#39;en parler.</p>
<blockquote>
<p>Disclaimer : je ne vais pas dénigrer SFEIR, si vous êtes là pour ça, vous pouvez passer votre chemin, il n&#39;y aura pas de sang ici… L&#39;idée c&#39;est de partager sur mon passage chez SFEIR, sur pourquoi j&#39;avais signé et pourquoi je pars. Tout ce que je vais écrire ici c&#39;est mon ressenti, mon vécu, c&#39;est pas une critique de l&#39;entreprise ni des gens qui la compose, c&#39;est juste une expression de comment ça s&#39;est passé pour moi.</p>
</blockquote>
<h2 id="article-au-commencement-il-y-avait-un-tout-petit-bureau-">Au commencement il y avait un tout petit bureau …<a href="#article-au-commencement-il-y-avait-un-tout-petit-bureau-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>L&#39;histoire de SFEIR Nantes a commencé en juin 2018. Jean-François Garreau (le Directeur Technique, que je connaissais déjà via le GDG Nantes vu que j&#39;étais pas mal présent en meetup à l&#39;époque), Sabrina Rivier (la Directrice Commerciale) et Annabelle Koster (la Talent Advocate, que je connaissais déjà bien, car elle travaillait aussi chez SII et se faisait une vraie place sur les meetups) montent l&#39;agence avec une vraie vision, une vraie envie de faire vivre la marque SFEIR à Nantes à travers l&#39;expertise tech en s&#39;entourant de personne qui pourraient aussi faire rayonner la marque et apporter de l&#39;expertise en mission et au sein de l&#39;agence.</p>
<p>À l&#39;époque j&#39;étais salarié de SII Atlantique, en mission chez OUI Sncf, dans une super équipe, avec des gens incroyables, j&#39;apprenais tous les jours des trucs, on faisait des trucs super intéressant, les utilisateurs des produits qu&#39;on développait était physiquement à quelques mètres de nous sur les bureaux autours. Puis pour divers raisons, mon équipe allait disparaitre, avec en parallèle pas grand-chose qui bougeait côté SII (comprendre que j&#39;ai fait pas mal de propositions pour faire des choses, en grande partie en donnant de mon temps perso, mais que rien ne passait). Il était temps pour moi de partir. </p>
<p>J&#39;ai tenté ma chance en postulant chez SFEIR. Au vu des échanges que j&#39;avais eus avec des Sfeirien sur le stand du Devfest Nantes, avec la conviction que je n&#39;avais aucune chance que ça passe mais en me disant que ça me donnerait un palier à atteindre pour re-postuler plus tard. Premier entretien en algo avec Jean-François, dans ma tête je me dis que c&#39;est déjà fini, j&#39;ai aucune chance face à Jef de donner quelque chose… Quelques jours plus tard Annabelle me dit que je dois aller sur Paris pour faire les deux autres tests techniques (à l&#39;époque, le seul dev à Nantes c&#39;était Jef, or dans le framework de recrutement de SFEIR, on doit être évalué par trois pairs), qui ont été autant d&#39;appréhension que l&#39;algo pour finalement une réussite. Quand j&#39;ai appris que j&#39;allais avoir une proposition, j&#39;ai signé sans trop réfléchir plus loin : dès les tests j&#39;avais un challenge (alors que SII ne m&#39;en proposait aucun), dès les échanges avec les évaluateurs je sentais un mindset commun, une certaine volonté de challenger avec bienveillance, de construire ensemble, pile ce que je cherchais.</p>
<p>Pour tout dire, il y a pas mal de choses que j&#39;aimais chez SFEIR. Déjà le fait que la direction à tous les niveaux se faisait à deux têtes : le directeur technique et directeur commercial partage le pouvoir et doivent tout décider ensemble ; pour moi c&#39;est la garantie que la tech (un bon 90% de l&#39;effectif d&#39;une ESN comme SFEIR) sera écouté, aura un impact. Le fait que l&#39;agence de Nantes soit petite (3 personnes quand j&#39;ai passé mes tests, 5 quand j&#39;ai effectivement commencé), donc tout à construire, avec moyen de mettre de moi dans la trajectoire de l&#39;agence. Une volonté de créer une communauté de passionné de tech à Nantes avec lesquels échanger au besoin, mais aussi s&#39;intégrer au groupe avec pas mal d&#39;échange entre agence. Beaucoup d&#39;option pour faire des choses : conférences, meetup, organiser des événements, partager sur des sujets tech, etc.</p>
<h2 id="article--et-puis-7-annees-sont-passes-">… et puis 7 années sont passés …<a href="#article--et-puis-7-annees-sont-passes-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>7 ans plus tard (7 ans le 4 mars 2026, donc même un peu plus que ça), j&#39;étais encore là.</p>
<p>J&#39;ai pu faire beaucoup de chose chez SFEIR. J&#39;ai été formateur (Angular, RxJS, React, TypeScript, Cypress, Playwright et Quarkus). J&#39;ai écrit des formations. J&#39;ai été speaker. J&#39;ai fait passer des tests techniques aux candidats. J&#39;ai été organisateur d&#39;un meetup interne pendant un peu plus de 2 ans seul (avant de passer la main sur l&#39;orga mais en donnant des coups de mains au besoin). J&#39;ai été organisateur d&#39;événements pas du tout tech aussi (repas de Noël et soirée chandeleur). J&#39;ai aussi fait de l&#39;accompagnement et du coaching autour de pleins de sujet dont les certifications Angular et React. J&#39;ai aussi pris une casquette dans le staff avec le rôle de Staff Engineer, donné mon avis sur la trajectoire de la boite. Mais aussi un rôle d&#39;élu au CSE. Beaucoup de moment à rire aussi, des personnes que j&#39;apprécie sincèrement et avec qui j&#39;ai adoré travailler (de loin parce que pas sur les mêmes projets mais aussi directement dans la même équipe pour certains). Et plein d&#39;autres choses.</p>
<p>J&#39;ai donné beaucoup d&#39;énergie perso pour SFEIR. Parce que j&#39;ai estimé que ça valait le coup. Parce que j&#39;avais envie de le faire. Parce que j&#39;avais un manager qui me comprenait et savait me montrer des portes que je pouvais ouvrir quand des opportunités apparaissaient et qu&#39;il pensait que j&#39;étais la bonne personne pour ça. Parce que clairement, 7 ans chez SFEIR c&#39;est aussi parce que j&#39;ai toujours eu un bon manager. Au début c&#39;était Jean-François, puis Damien, puis à nouveau Jean-François. Je ne serais pas resté aussi longtemps sans ça, c&#39;est certain !</p>
<p>Mais en 7 ans on change. En tout cas, en 7 ans j&#39;ai changé. J&#39;ai commencé chez SFEIR avec très peu confiance en moi et ma capacité à réaliser des choses compliquées, j&#39;en pars avec beaucoup plus de confiance, je sais que je peux faire plein de choses, je me projette sur des rôles très différents, et même si j&#39;ai toujours beaucoup de doute sur mes compétences, sur qui je suis, etc. j&#39;ai appris à tenter plus, à me faire confiance, à prendre des risques. Et aussi des changements dans ma vie personnelle, un déménagement à côté de Cholet (environ 1h de train/voiture de Nantes), une vie de famille qui impose quelques changements de rythmes de vie.</p>
<p>En 7 ans l&#39;agence a changé aussi. Quand j&#39;ai démarré en 2019, SFEIR Nantes c&#39;était un tout petit bureau un peu sombre dans un espace de coworking avec 5-6 personnes, et 8 places assises, aujourd&#39;hui SFEIR c&#39;est avec un bureau de presque 200m², un petit open space, une salle de formation, une soixantaine de personnes à l&#39;agence.</p>
<p>En 7 ans SFEIR a changé. Un directeur qui part, une réorganisation, une volonté de faire grossir la boite autrement, la fin de la direction à deux têtes à tous les niveaux, une perte de sens de pas mal de décisions…</p>
<p>Après 7 ans, je ne me sentais plus vraiment aligné avec l&#39;entreprise et sa trajectoire, je ne me voyais plus évoluer non plus chez SFEIR, j&#39;étais fatigué de voir des certains sujets qui ne bougeait pas, fatigué de lever des alertes qui n&#39;était pas écouté côté direction à Paris, fatigué de m&#39;investir dans une double vie pro (une vie pro chez SFEIR et une vie pro chez mon client), me sentir de moins en moins constructif (même si on ne me l&#39;a jamais dit, je le voyais que j&#39;aurais pas réagi comme ça 1 ou 2 ans plus tôt ; sincèrement désolé si j&#39;ai pu blesser certains sans m&#39;en rendre compte).</p>
<h2 id="article--il-etait-temps-pour-moi-de-prendre-un-autre-chemin-">… il était temps pour moi de prendre un autre chemin …<a href="#article--il-etait-temps-pour-moi-de-prendre-un-autre-chemin-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Même si quitter l&#39;équipe SFEIR Nantes, qui était un peu ma seconde famille après tout ce temps, était difficile, il fallait que je réagisse.</p>
<p>J&#39;étais tout doucement en train de me perdre moi. Je commençais à montrer des signes de burn out. Après 10 ans en ESN, je n&#39;en pouvais plus de ce système. Et je me sentais de moins en moins à ma place à l&#39;agence (le fait de ne plus vivre à Nantes et donc moins être présent à l&#39;agence y a joué c&#39;est certain, mais mon envie de partir à commencer à germer avant même de quitter Nantes).</p>
<p>J&#39;ai beaucoup de projet en tête, beaucoup de chose que j&#39;aimerais réaliser / créer mais le panel d&#39;activité de SFEIR m&#39;empêchait de le faire car j&#39;aurais été en conflit contractuel. Je n&#39;en parlerais pas ici pour l&#39;instant, ça viendra (ou pas) le moment venu, pour l&#39;instant ça reste dans un coin de ma tête.</p>
<h2 id="article-une-nouvelle-mission-ou-pas-">Une nouvelle mission… Ou pas !<a href="#article-une-nouvelle-mission-ou-pas-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>En parallèle de tout un cheminement qui m&#39;a pris bien entre 1 et 2 ans, j&#39;ai rejoint France Travail en tant que prestataire. En travaillant pour une entreprise avec une mission service public, j&#39;ai pu mettre mes compétences au service d&#39;un morceau de bien commun, au service de l&#39;emploi des autres (je sais que tout ce système a ses limites, mais ce n&#39;est pas en le critiquant qu&#39;on change les choses, c&#39;est en agissant à mon sens).</p>
<p>En tout cas, même si tout n&#39;est pas parfait chez France Travail, je m&#39;y sens bien. Mon équipe est extra, mon projet intéressant. </p>
<p>Et puis j&#39;ai eu l&#39;opportunité de passer interne, j&#39;ai eu l&#39;opportunité d&#39;évoluer au passage (passer de Lead Dev à Tech Lead), j&#39;ai eu l&#39;option de signer pour rester dans un cadre qui me convenait bien, pour réaliser une roadmap que j&#39;étais en train de commencer à construire pour les 2 prochaines années.</p>
<p>J&#39;ai commencé il y a peu chez France Travail en interne. Je ne sais pas comment ça se passera dans le temps, mais je me projette dans le modèle de fonctionnement qui finalement ressemble un peu à une ESN sur pas mal d&#39;aspects et je pense que certaines grosses DSI par lesquelles je suis passée devraient s&#39;inspirer du modèle de fonctionnement de France Travail.</p>
<blockquote>
<p>Note : pourquoi je dis que le fonctionnement ressemble à une ESN ? Chez France Travail on a deux managers : un Responsable Opérationnel (RO) et une Responsable Pour la Carrière (RPC). Le RO nous définit notre rôle au quotidien dans l&#39;équipe, nos responsabilités, notre mission. Notre RPC va lui suivre notre carrière, notre évolution personnelle, notre projection à long terme, notre employabilité, nous suivre de projet en projet (en interne on dit de missionement en missionement), en se basant sur un mélange entre nos envies et les besoins de l&#39;entreprise. Finalement comme en ESN on a un manager côté ESN qui va nous aider à rester en correspondance du besoin du marché et nous accompagner en termes d&#39;évolution salariale et professionnel, et un manager côté client qui va faire le suivi au quotidien dans le projet.</p>
</blockquote>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Alors que pendant mes études je me disais que je ne voulais surtout pas travailler en ESN (à l&#39;époque on disait encore SSII (Société de Service en Ingénierie Informatique)), j&#39;aurais travaillé 10 ans en tant que prestataire. J&#39;aurais travaillé chez 7 clients différents, j&#39;aurais travaillé sur plus d&#39;une quinzaine de projets/produits en build (construit depuis rien et emmené en production) et run (sur des projets déjà existant, à devoir les maintenir, faire les correctifs et les faire évoluer techniquement et fonctionnellement). En ESN et particulièrement chez SFEIR, j&#39;aurais pu grandir, pas après pas.</p>
<p>Sans ordre particulier, et plus toujours chez SFEIR au moment où j&#39;écris ça, merci à Jef, Annabelle, Damien, Adrien, Gildas, Morgane, Emmanuel, Yoann, Frédéric, Valentin, Claude, Justine, Julien, Julien  (pas une erreur, pas faute d&#39;avoir dit à Justine que recruter des homonymes c&#39;est pas pratique 🤪), Mathob, Benjamin, Benoit, Benoit (encore une sombre histoire d&#39;homonymes…), Hoani, William, Alexis, Arthur, Jean-Alain, Florian, Florian (bon c&#39;est fini les homonymes ?), Denis, Guillaume, Guillaume (toujours pas on dirait…), Stéphane, Jonathan, Jonathan (c&#39;est quoi ce boulot Justine ? 😵), Thomas, Nebras, et tant d&#39;autres à Nantes ou même globalement chez SFEIR. Si vous passez par là, vraiment dites-vous que sans vous je ne serais pas là, et que je suis très heureux d&#39;avoir pu apprendre tant de chacun de vous ! J&#39;espère avoir pu vous apporter deux trois trucs moi aussi !</p>
<p>En bref : je suis content d&#39;avoir fait ces 7 ans chez SFEIR, mais je suis aussi content de partir au final, je pars pour une nouvelle aventure en mettant un point sur l&#39;histoire SFEIR qui commençait à devenir un peu trop lourde. </p>
<p>Merci aussi à Lise, Marietta, Thibaud, Guillaume et Nicolas de m&#39;avoir fait confiance en m&#39;accompagnant sur passage en interne chez France Travail !</p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Two floating islands in a golden sky, connected by a sculpted wooden bridge crossing the image from left to right. The left island (symbolizing SFEIR) is autumnal, with trees featuring red, orange, and yellow leaves, discrete holographic screens (wooden frames) displaying lines of code, and anthropomorphic animals (axolotls, pandas, cats, and squirrels) waving goodbye. The right island (symbolizing France Travail) is spring-like, with blooming trees and vibrant flowers, futuristic buildings blended into nature, and anthropomorphic animals (phoenix, firefox, red pandas, and birds) eagerly waiting. A red panda (anthropomorphic, male, 33 years old, round face, full cheeks, marked chin, curly hair tied in a low bun, short dense beard, dark brown slightly squinted eyes, black rectangular thin glasses, subtle silver chain necklace, robust build, broad shoulders, wearing a t-shirt and jeans) is crossing the bridge from left to right, carrying a backpack filled with notebooks and technical books. Maple leaves (8-10, red/orange/yellow) float around him, and a soft golden halo surrounds him. The scene is inspired by Studio Ghibli, with warm, poetic, and dreamy colors (beiges, soft oranges, warm browns for the left island, and soft greens, pale pinks for the right island), and a blend of organic and high-tech elements. The bridge is decorated with carved patterns and lanterns.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Aout 2026]]></title>
      <guid isPermaLink="false">2026/08/04/revue-de-presse-aout</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/08/04/revue-de-presse-aout/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Tue, 04 Aug 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-docs-add-v23-release-and-change-to-yearly-release-cycle-by-thesmiler--pull-request-69817--angularangular--githubhttpsgithubcomangularangularpull69817"><a href="https://github.com/angular/angular/pull/69817">docs: add v23 release and change to yearly release cycle by thesmiler · Pull Request #69817 · angular/angular · GitHub</a><a href="#article-docs-add-v23-release-and-change-to-yearly-release-cycle-by-thesmiler--pull-request-69817--angularangular--githubhttpsgithubcomangularangularpull69817" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Angular #Frontend</p>
<p>La version 22 d&#39;Angular est sortie début juin 2026, la version 23 sortira en juin 2027. À partir de maintenant il y aura 1 seule version majeure d&#39;Angular chaque année, suivi de 4 à 6 versions mineures. </p>
<p>Allonger le cycle de release va permettre à l&#39;équipe Angular d&#39;avoir plus de temps pour développer certaines fonctionnalités tout en permettant aux utilisateurs d&#39;Angular de moins subir les breaking changes aussi souvent (quand bien même c&#39;était pas vraiment un sujet à mon sens, vu que le CLI encaisse presque tous les breaking-changes tout en ayant un framework rétro compatible très fortement donc on était même pas obligé de basculer). </p>
<p>Je pense que l&#39;effet secondaire qu&#39;on risque d&#39;observer c&#39;est que certains projets vont mettre encore plus de temps à faire les migrations majeures par contre… </p>
<h3 id="article-github--tokiorstopcoat-a-batteriesincluded-framework-for-building-web-apps--githubhttpsgithubcomtokiorstopcoat"><a href="https://github.com/tokio-rs/topcoat">GitHub - tokio-rs/topcoat: A batteries-included framework for building web apps · GitHub</a><a href="#article-github--tokiorstopcoat-a-batteriesincluded-framework-for-building-web-apps--githubhttpsgithubcomtokiorstopcoat" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Rust #Web #Frontend #Backend</p>
<p>Des frameworks web fullstack y&#39;en à la pelle. Là je retrouve plein de bonnes idées à mon sens :</p>
<ul>
<li>c&#39;est basé sur Tokio (LA lib rust la plus puissante pour gérer de l&#39;asynchrone en Rust, pile le truc le plus utile pour faire un moteur de serveur web) ;</li>
<li>y&#39;a du templating pseudo-JSX mais compilé strictement par le compilateur Rust ;</li>
<li>y&#39;a un système de Signal ;</li>
<li>SSR par défaut sauf si on utilise des éléments de réactivité ;</li>
<li>compilation en JavaScript au besoin des bribes de templates ;</li>
<li>basé sur des annotations (<code>#[component]</code>, <code>#[page(&quot;/&quot;)]</code>, <code>#[tokio::main]</code> par exemples) ;</li>
<li>bundling automatique des assets ;</li>
</ul>
<p>On sent des inspirations prises à droite et à gauche pour construire Topcoat ! Par contre c&#39;est encore indiqué comme :</p>
<blockquote>
<p>Early-stage and experimental. Expect breaking changes.</p>
</blockquote>
<p>Donc il faut suivre. On peut jouer avec, mais attention si vous voulez aller en production ! </p>
<h3 id="article-the-website-specificationhttpsspecificationwebsite"><a href="https://specification.website/">The Website Specification</a><a href="#article-the-website-specificationhttpsspecificationwebsite" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Web #Frontend</p>
<blockquote>
<p>A platform-agnostic specification of all the technical details that matter for a website, from <code>&lt;title&gt;</code> to <code>/.well-known/security.txt</code> to WCAG contrast. Written for humans and agents.</p>
</blockquote>
<p>Et vraiment je pense qu&#39;on est pas loin de retrouver tout ce qui est important 😯 </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-github--kyutailabspockettts-a-tts-that-fits-in-your-cpu-and-pocket--githubhttpsgithubcomkyutailabspockettts"><a href="https://github.com/kyutai-labs/pocket-tts">GitHub - kyutai-labs/pocket-tts: A TTS that fits in your CPU (and pocket) · GitHub</a><a href="#article-github--kyutailabspockettts-a-tts-that-fits-in-your-cpu-and-pocket--githubhttpsgithubcomkyutailabspockettts" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Text-To-Speech</p>
<p>Si je suis souvent critique envers l&#39;IA c&#39;est principalement pour deux choses : le bullshit qui l&#39;entoure et l&#39;absurde taille des modèles (particulièrement vrai avec les LLMs). Là c&#39;est l&#39;opposé : un modèle tout petit, qui ne dépend pas du tout d&#39;une carte graphique (ça tourne avec PyTorch CPU) et qui fait du TTS (Text To Speech) facilement et rapidement.</p>
<p>Je suis pas anti-IA, je suis pour de l&#39;IA raisonnée, réfléchit, et pensé pour être utilisé par le plus grand nombre.</p>
<h3 id="article-mon-rapport-si-ambigu-a-claude--chez-bodulhttpsblogbodulfr20260714monrapportsiambiguaclaude"><a href="https://blog.bodul.fr/2026/07/14/mon-rapport-si-ambigu-a-claude/">Mon rapport si ambigu à Claude – Chez Bodul</a><a href="#article-mon-rapport-si-ambigu-a-claude--chez-bodulhttpsblogbodulfr20260714monrapportsiambiguaclaude" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Métier-de-dev</p>
<p>Ludovic nous donne son ressenti de comment il utilise mais aussi comment il ressent l&#39;IA aujourd&#39;hui. Le changement du métier de dev. La manière dont les devs qu&#39;il qualifie de plutôt &quot;artisan&quot; (partisan de faire à la main, proprement et durablement quitte à y passer un peu plus de temps) se sentent de moins en moins en phase avec le métier. </p>
<p>Article qui n&#39;apporte aucune solution (ce n&#39;est pas le but, ici Ludovic donne son ressenti rien et c&#39;est très bien), mais c&#39;est intéressant à lire. Personnellement je vois de plus en plus de retour du style, que ce soit en ligne ou dans les gens que je croise. Et de mon côté je n&#39;oublie pas non plus qu&#39;il existe encore des devs qui n&#39;utilisent pas du tout l&#39;IA au quotidien car pas les outils à dispo au boulot et qui sont donc complètement en dehors de tout ça </p>
<h3 id="article-vibe-coder-vs-software-engineer--yusuf-aytashttpsyusufaytascomvibecodervssoftwareengineer"><a href="https://yusufaytas.com/vibe-coder-vs-software-engineer">Vibe Coder vs Software Engineer | Yusuf Aytas</a><a href="#article-vibe-coder-vs-software-engineer--yusuf-aytashttpsyusufaytascomvibecodervssoftwareengineer" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Métier-de-dev</p>
<p>Je cite 3 extraits :</p>
<blockquote>
<p>Use vibe coding where the cost of being wrong is low, and use engineering discipline where the cost of being wrong belongs to customers, teams, or the business.</p>
</blockquote>
<blockquote>
<p>Engineering requires some level of apprenticeship. Vibe coding tempts you into working alone. People work and learn in teams. Software engineers improve their craft by working with others. The job is not just code. The job is judgment, not output. A software engineer has judgment about what&#39;s risky and what&#39;s not. That judgment is built through contact with the system and people.</p>
</blockquote>
<blockquote>
<p>A software engineer is needed when the main cost is ownership. They control what enters the system, how it is reviewed, how it is secured, how it is tested, how it is operated, and how it will be changed later. The distinction is operational. It is also not a fixed identity. The same person should vibe code in discovery and switch into engineering for delivery. The skill is knowing which mode you are in, and not letting the habits of one leak into the other. Vibe coding can help you learn faster. Software engineering helps you avoid paying for that learning forever.</p>
</blockquote>
<p>Vraiment un article important à lire. Il correspond à mon sens assez bien à ma vision : l&#39;IA pour le code c&#39;est un outil de plus pour nous aider à produire le code ; le code c&#39;est presque la brique la moins importante du métier, ce qui compte c&#39;est le produit et l&#39;appropriation du code qui constitue le produit ; si vous générez le code en fermant les yeux, sans aucune validation, sans aucune bonne pratique (y&#39;a rien de nouveau derrière ça, les bonnes pratiques de dev existent depuis plusieurs décennies pour certaines, et y&#39;a des noms plus récents qui ont écrit des bouquins entiers dessus : Robert Cecil Martin, Martin Fowler, etc.) ce que vous produisez c&#39;est juste une soupe impossible à maintenir, impossible à déployer avec confiance, c&#39;est juste un machin semble être un produit mais n&#39;en est pas un. </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-wichtige-information--zego-textilveredelungszentrumhttpswwwzegotvzcomwichtigeinformation"><a href="https://www.zego-tvz.com/wichtige-information/">Wichtige Information - ZEGO Textilveredelungszentrum</a><a href="#article-wichtige-information--zego-textilveredelungszentrumhttpswwwzegotvzcomwichtigeinformation" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité</p>
<p>Pour faire court : une boîte de textile allemande se place en insolvabilité pour tenter de redresser la barre à la suite d&#39;une cyberattaque qui a mis à l&#39;arrêt toute la boîte pendant 3 semaines en mars/avril… La cybersécurité ça coûte toujours trop cher, jusqu&#39;à ce que ça plombe la boîte, peut-être pour la dernière fois… </p>
<p>C&#39;est un exemple parmi tant d&#39;autres de boîte qui n&#39;a rien de tech mais qui s&#39;est pris une claque à cause d&#39;un trou sans sécurité. Je pense que c&#39;est important d&#39;en parler ! </p>
<p>Je pose là une traduction Google Translate pour ceux qui comme moi parle couramment l&#39;allemand :</p>
<blockquote>
<p>Déclaration d&#39;insolvabilité – Et pourquoi nous continuons à aller de l&#39;avant</p>
<p>Mesdames, Messieurs,
Chers partenaires commerciaux,</p>
<p>Nous nous adressons à vous aujourd&#39;hui pour vous communiquer une nouvelle qu&#39;il nous est personnellement très difficile d&#39;annoncer.</p>
<p>La société ZEGO Textilveredelungszentrum GmbH a déposé une déclaration d&#39;insolvabilité.</p>
<p>Cette décision a constitué l&#39;une des étapes les plus difficiles des 37 années d&#39;existence de notre entreprise. Elle n&#39;a pas été prise à la légère ; elle intervient après que nous avons examiné et épuisé toutes les options à notre disposition.</p>
<p>Ces derniers mois, nous nous sommes battus de toutes nos forces pour notre entreprise, nos employés, nos clients et nos fournisseurs. Notre objectif a toujours été de maintenir l&#39;activité et de ramener ZEGO sur une trajectoire stable.</p>
<p>Cependant, la cyberattaque du 29 mars 2026 a frappé notre entreprise avec une telle violence que, malgré tous nos efforts, nous n&#39;avons pas réussi à nous en relever complètement. Ses conséquences ont notamment entraîné un arrêt de la production de près de six semaines et de lourdes difficultés financières. En fin de compte, ces répercussions ont compromis notre situation financière au point de rendre nécessaire le dépôt de bilan.</p>
<p>Cette démarche est pour nous extrêmement douloureuse.</p>
<p>Depuis de nombreuses années, ZEGO est synonyme de fiabilité, de qualité et de partenariats constructifs. Bon nombre de nos clients et fournisseurs nous accompagnent depuis longtemps. Nos relations commerciales ont souvent évolué vers des partenariats fondés sur la confiance — voire vers de véritables amitiés — pour lesquels nous vous sommes infiniment reconnaissants.</p>
<p>C&#39;est précisément pour cette raison qu&#39;il nous tient à cœur de partager ce qui suit avec vous aujourd&#39;hui :</p>
<p>L&#39;insolvabilité ne signifie pas nécessairement la fin d&#39;une entreprise.</p>
<p>Au contraire, cette procédure offre l&#39;opportunité de restructurer et de repositionner l&#39;entreprise, ainsi que de stabiliser sa situation économique. Nous sommes pleinement déterminés à atteindre cet objectif.</p>
<p>Nous continuons à nous battre pour la survie de ZEGO Textilveredelungszentrum GmbH.</p>
<p>Notre but est de collaborer avec toutes les parties prenantes pour élaborer des solutions viables, préserver les emplois, maintenir nos relations avec les clients et assurer l&#39;avenir de notre entreprise. À cet égard, nous continuons de compter sur le soutien et la confiance de nos partenaires commerciaux.</p>
<p>Nous vous demandons donc instamment de rester à nos côtés durant cette période difficile. Chaque forme de soutien, chaque effort de collaboration et chaque marque de confiance contribuent à jeter les bases de la pérennité de l&#39;entreprise. Nous tenons à vous remercier chaleureusement pour votre soutien, votre fidélité et la confiance que vous nous avez témoignée jusqu&#39;à présent.</p>
<p>Nous vous tiendrons informés en toute transparence de l&#39;évolution de la situation et restons à votre entière disposition pour toute question.</p>
<p>Œuvrons ensemble pour que cette période difficile ne marque pas la fin, mais un nouveau départ pour ZEGO.</p>
<p>Cordialement,</p>
<p>Johannes Zenglein
ZEGO Textilveredelungszentrum GmbH</p>
</blockquote>
<h3 id="article-comprendre-lauthentification-avec-github-oauth---codegaragehttpscodegaragecomblogcomprendrelauthentificationavecgithuboauth"><a href="https://code-garage.com/blog/comprendre-l-authentification-avec-github-oauth">Comprendre l’authentification avec Github (OAuth)  - Code-Garage</a><a href="#article-comprendre-lauthentification-avec-github-oauth---codegaragehttpscodegaragecomblogcomprendrelauthentificationavecgithuboauth" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Github #OAuth2 #Sécurité</p>
<p>Je cite directement le résumé final qui indique bien ce que vous explique l&#39;article et le mode de fonctionnement d&#39;une authentification avec Github :</p>
<blockquote>
<ol>
<li>Votre application redirige l&#39;utilisateur vers GitHub.</li>
<li>GitHub vérifie son identité et renvoie un code temporaire.</li>
<li>Votre serveur échange ce code contre un token, récupère l&#39;adresse email de l&#39;utilisateur, puis génère son propre JWT.</li>
<li>Au final, GitHub ne fait qu&#39;une seule chose : <strong>confirmer l&#39;identité de l&#39;utilisateur</strong>.</li>
</ol>
</blockquote>
<p>Pour le reste je vous invite à lire l&#39;article, c&#39;est simple, c&#39;est bien expliqué, ça peut s&#39;adapter à pas mal de cas d&#39;authentification via une source externe.</p>
<h3 id="article-7-ministres-francais-espionnes-par-le-maroc--voici-ce-que-revele-la-nouvelle-enquete-pegasushttpswwwclubiccomactualite621592pegasusmarochtml"><a href="https://www.clubic.com/actualite-621592-pegasus-maroc.html">7 ministres français espionnés par le Maroc : voici ce que révèle la nouvelle enquête Pegasus</a><a href="#article-7-ministres-francais-espionnes-par-le-maroc--voici-ce-que-revele-la-nouvelle-enquete-pegasushttpswwwclubiccomactualite621592pegasusmarochtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #Vie-privée</p>
<p>Résumé : on <strong>sait</strong> que 7 ministres ou anciens ministres ont été espionnés par le Maroc entre 2019 et 2020 via l&#39;utilisation de Pegasus (outils d&#39;espionage numérique par intrusion / exploitation de faille zero-days non divulgués vendu par la société NSO). À priori ce serait via des failles zero-clic, donc sans aucune action de l&#39;utilisateur. On a aucune idée de ce que le Maroc a obtenu comme information et si les prises de position aligné sur le Maroc de la France depuis sont liés. </p>
<p>On <strong>ne sait pas</strong> par contre si d&#39;autres ministres ont été espionnés par Pegasus, ni si le Président a été espionné, ou même qui que ce soit d&#39;autres. Ne pas avoir trouvé de trace, ne signifie pas qu&#39;il n&#39;y a pas eu d&#39;espionnage, ça peut-être aussi une attaque légèrement différente ou via une faille qui ne laisse pas de trace ou des traces plus discrètes. </p>
<p>Avec ce genre d&#39;outils : on ne sait rien, ça compromet la sécurité et la vie privée de n&#39;importe qui… </p>
<h3 id="article-ublock-origin-nest-pas-un-adblocker--middleearthhttpsblogmiddleearthfrublockoriginnestpasunadblockerhtml"><a href="https://blog.middleearth.fr/ublock-origin-nest-pas-un-adblocker.html">uBlock Origin n&#39;est pas un adblocker — MiddleEarth</a><a href="#article-ublock-origin-nest-pas-un-adblocker--middleearthhttpsblogmiddleearthfrublockoriginnestpasunadblockerhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #Vie-privée #Malware #Navigateur</p>
<p>Les pubs diffusent des malwares (et des arnaques), de plus en plus, et du coup bloquer les pubs devient une mesure de sécurité en plus de la protection de la   vie privée (les bandeaux pub traquent les utilisateurs de site en site) et de l&#39;économie de bande passante qui est obtenue au passage… </p>
<p>Avec uBlock Origin vous aurez un blocage propre et efficace de nombreux trucs ! </p>
<p>AdBlock Plus deal avec les boîtes de pubs pour qu&#39;une partie des pubs restent en ligne quand bien même vous avez AdBlock Plus depuis de nombreuses années. Chrome / Chromium et ses dérivés ne permettent plus que les Web Extension Manifest v3 ce qui dans le moteur de Chrome implique de facto que vous ne pouvez plus avoir un blocage de pub pertinent (je passe les détails techniques largement diffusés en ligne).</p>
<blockquote>
<p>Note : si vous vous demandez pourquoi Chrome et ses dérivés n&#39;aiment pas les bloqueurs de pub, rappelez-vous que c&#39;est développé par Google et qu&#39;une grosse part de leurs revenues vient des pubs. </p>
</blockquote>
<p>Bref : installez <strong>uBlock Origin</strong>, sur <strong>Firefox</strong>, vous aurez un vrai navigateur et un vrai bloqueur de publicité. </p>
<h3 id="article-ce-quil-faut-savoir-sur-le-retrait-de-oneplus-en-europe-mises-a-jour-suivi-support-clienthttpswwwclubiccomactualite621580cequilfautsavoirsurleretraitdeonepluseneuropemisesajoursuivisupportclienthtml"><a href="https://www.clubic.com/actualite-621580-ce-qu-il-faut-savoir-sur-le-retrait-de-oneplus-en-europe-mises-a-jour-suivi-support-client.html">Ce qu&#39;il faut savoir sur le retrait de OnePlus en Europe (mises à jour, suivi, support client)</a><a href="#article-ce-quil-faut-savoir-sur-le-retrait-de-oneplus-en-europe-mises-a-jour-suivi-support-clienthttpswwwclubiccomactualite621580cequilfautsavoirsurleretraitdeonepluseneuropemisesajoursuivisupportclienthtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Smartphone #Tech #Android #Oneplus #Oppo #Sécurité</p>
<p>Si comme moi vous avez un Oneplus (j&#39;utilise un Oneplus 11 depuis sa sortie début 2023, ce dernier avait remplacé un Oneplus 6 que j&#39;avais aussi depuis sa sortie), vous allez voir des changements prochainement : la marque Oneplus sort définitivement de tous les marchés excepté la Chine… </p>
<p>Conséquence annoncée :</p>
<ul>
<li>On perd le service client Oneplus au profit de celui d&#39;Oppo (la maison mère de Oneplus depuis pas mal d&#39;année déjà, on sait qu&#39;Oppo est investisseur de Oneplus depuis 2014) ;</li>
<li>Prochainement on devra dire adieu à OxygenOS en faveur de ColorOS (soyez patient pour migrer à mon avis…), ou on perdra les mises à jour majeures d&#39;Android et sûrement aussi les patchs de sécurité ;</li>
<li>Plus de nouveau smartphone Oneplus à venir chez nous ;</li>
</ul>
<p>De mon côté je vais rester sur mon Oneplus 11 tant qu&#39;il fonctionnera (à priori) et on verra vers quoi j&#39;irai dans le futur. Avec l&#39;explosion du prix des composants, c&#39;est de toutes façons le pire moment pour changer de matériel 😅 </p>
<p>Si vous cherchez un smartphone en ce moment, je vous conseillerais à priori de regarder du côté de <a href="https://nothing.tech">Nothing</a>, entreprise fondée par Carl Pei (comme Oneplus) avec une philosophie proche initialement. C&#39;est sûrement chez eux que j&#39;irais si je devais changer dans les prochains mois de mon côté en tout cas </p>
<h2 id="article-jeuxvideos">Jeux-videos<a href="#article-jeuxvideos" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-the-spine-archive--custom-nintendo-switch-spines-toolhttpsthespinearchivexyz"><a href="https://thespinearchive.xyz/">The Spine Archive | Custom Nintendo Switch Spines Tool</a><a href="#article-the-spine-archive--custom-nintendo-switch-spines-toolhttpsthespinearchivexyz" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Nintendo #Jeux-videos</p>
<p>De base la tranche est rouge uniforme avec juste le nom du jeu en blanc, ce qui n&#39;est pas très beau, pas toujours facile à lire et rend moins visuelle la recherche d&#39;un jeu. Ce site rassemble donc des tranches de jaquette alternatives pour les jeux Nintendo Switch 1 et 2, faites par des indépendants, qu&#39;on peut imprimer gratuitement pour glisser devant la tranche de la jaquette de nos jeux pour rendre plus sympa la tranche de nos jeux. </p>
<p>Je trouve l&#39;idée super cool, mais peu probable que je fasse tous mes jeux switch comme j&#39;en ai plus de 200 😅 </p>
<h3 id="article-little-writer-desktop-companion-on-steamhttpsstoresteampoweredcomapp4672770little_writer_desktop_companion"><a href="https://store.steampowered.com/app/4672770/Little_Writer_Desktop_Companion/">Little Writer Desktop Companion on Steam</a><a href="#article-little-writer-desktop-companion-on-steamhttpsstoresteampoweredcomapp4672770little_writer_desktop_companion" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Jeux-videos</p>
<blockquote>
<p>Your little companion is an ambitious writer with very little discipline. Type, and they&#39;ll write too. Every keystroke moves their work forward. In this idle productivity game, help them become a renowned author while you get things done. </p>
</blockquote>
<p>C&#39;est plutôt marrant, l&#39;idée c&#39;est d&#39;avoir une petite fenêtre flottante qui montre un petit personnage en train de taper du texte quand vous tapez du texte. Plus vous tapez au clavier (hors du jeu, sur l&#39;activité que vous voulez), plus vous faites progresser votre petit écrivain. J&#39;aime bien l&#39;idée, parce que ça vous donne implicitement des objectifs à vous remplir (taper un certain nombre de mots, taper à une certaine vitesse, etc.), tout étant peu intrusif à l&#39;écran.</p>
<p>Par contre autant c&#39;est gratuit et offline (sur le papier), autant ça veut dire que Little Writer Desktop Companion va intercepter tous vos appuis claviers, donc il a le potentiel d&#39;être un keylogger, donc je suis partagé… </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-reactos-opensource-windows-project-now-capable-of-running-halflife-2--phoronixhttpswwwphoronixcomnewshalflife2reactos"><a href="https://www.phoronix.com/news/Half-Life-2-ReactOS">ReactOS &quot;Open-Source Windows&quot; Project Now Capable Of Running Half-Life 2 - Phoronix</a><a href="#article-reactos-opensource-windows-project-now-capable-of-running-halflife-2--phoronixhttpswwwphoronixcomnewshalflife2reactos" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Open-Source #ReactOS #OS #Open-source #Windows</p>
<p>Encore une étape de franchi pour ReactOS (ré-implémentation de l&#39;api de Windows mais sans le moindre lien avec Microsoft et 100% en open source) qui fait maintenant tourner sans souci Half-Life 2. Ça parait anecdotique mais ça ne l&#39;est pas, il faut un max de truc pour que ça marche les jeux-vidéos ! </p>
<p>Dans le billet on voit aussi la première implémentation d&#39;un appel système NT6 (équivalent de Windows Vista) donc ça ouvre une nouvelle porte ! </p>
<h3 id="article-claviers-asus-rog-et-linux--fuyez--ou-bricolez-dur--le-blog-de-seboss666httpsblogseboss666info202606claviersasusrogetlinuxfuyezoubricolezdur"><a href="https://blog.seboss666.info/2026/06/claviers-asus-rog-et-linux-fuyez-ou-bricolez-dur/">Claviers ASUS ROG et Linux : fuyez ! (ou bricolez dur) – Le blog de Seboss666</a><a href="#article-claviers-asus-rog-et-linux--fuyez--ou-bricolez-dur--le-blog-de-seboss666httpsblogseboss666info202606claviersasusrogetlinuxfuyezoubricolezdur" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Clavier #Linux #USB</p>
<p>Seboss666 a eu quelques galères avec son clavier ASUS qui envoie des inputs qui mettent les ordis Linux en vrac. Ça sent le non-respect du standard USB cette histoire mais bon… </p>
<p>En tout cas, note pour plus tard : ne jamais acheter de clavier ASUS et rester chez Logitech (MX Keys à date) quand bien même j&#39;aime beaucoup les machines / cartes-mères de marques 😅 </p>
<h3 id="article-the-temper-programming-language--temper-programming-languagehttpstemperlangdev"><a href="https://temperlang.dev/">The Temper programming language - Temper Programming Language</a><a href="#article-the-temper-programming-language--temper-programming-languagehttpstemperlangdev" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Language #OpenSource #Open-Source #Open-source #TypeScript #JavaScript #Java #C# #Rust #Lua</p>
<p>Je cite la première phrase de la doc :</p>
<blockquote>
<p>The Temper programming language cross-translates to other programming languages.</p>
</blockquote>
<p>Et le premier extrait de code :</p>
<pre><code class="hljs language-Temper">export let half(x: Int): Int {
  x / 2
}
</code></pre><p>La version transpilée en Java :</p>
<pre><code class="hljs language-Java"><span class="hljs-keyword">package</span> com.example.numerics;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">NumericsGlobal</span> {
    <span class="hljs-keyword">private</span> <span class="hljs-title function_">NumericsGlobal</span><span class="hljs-params">()</span> {
    }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-title function_">half</span><span class="hljs-params">(<span class="hljs-type">int</span> x__1)</span> {
        <span class="hljs-keyword">return</span> x__1 / <span class="hljs-number">2</span>;
    }
}<div aria-hidden="true" class="language-tag">Java</div>
</code></pre><p>Ou en TypeScript :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-keyword">const</span> {
  <span class="hljs-attr">trunc</span>: trunc__1
} = globalThis.<span class="hljs-property">Math</span>;
<span class="hljs-comment">/**
 * <span class="hljs-doctag">@param</span> {<span class="hljs-type">number</span>} <span class="hljs-variable">x_0</span>
 * <span class="hljs-doctag">@returns</span> {<span class="hljs-type">number</span>}
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">half</span>(<span class="hljs-params">x_0</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-title function_">trunc__1</span>(x_0 / <span class="hljs-number">2</span>);
};<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Ou en Python :</p>
<pre><code class="hljs language-Python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">half</span>(<span class="hljs-params">x__1: <span class="hljs-string">&#x27;int&#x27;</span></span>) -&gt; <span class="hljs-string">&#x27;int&#x27;</span>:
  <span class="hljs-keyword">return</span> x__1 // <span class="hljs-number">2</span><div aria-hidden="true" class="language-tag">Python</div>
</code></pre><p>Y&#39;a aussi C#, Rust et Lua. </p>
<p>Je cite un autre passage parlant :</p>
<blockquote>
<p>Most engineering organizations use multiple languages: Python for data science, others for mobile apps, JavaScript on the web, and a different language on the server.</p>
<p>Temper helps break down silos by letting a small team maintain core type definitions and logic to all the other silos.</p>
</blockquote>
<p>En résumé, Temper c&#39;est un langage qui se veut assez simple mais expressif, pas dans le but de créer des applications mais de créer des librairies de types et d&#39;utilitaires qui sont partageables facilement à travers toute la stack que vous avez, à moindre effort. Je trouve ça plutôt malin ! </p>
<h3 id="article-sqlite-should-have-ruststyle-editions--morts-ramblingshttpsmortcoffeehomesqliteeditions"><a href="https://mort.coffee/home/sqlite-editions/">SQLite should have (Rust-style) editions - Mort&#39;s Ramblings</a><a href="#article-sqlite-should-have-ruststyle-editions--morts-ramblingshttpsmortcoffeehomesqliteeditions" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#SQLite #Rust</p>
<p>Quelques notes sur le fonctionnement par défaut de SQLite. Plutôt des notes négatives pour le coup. Sans dire que SQLite est mauvais (c&#39;est très bien au contraire), ça fait du bien de voir des vrais critiques négatives sur SQLite je trouve </p>
<p>Ce que je retiens :</p>
<ul>
<li>&quot;Bad default #1: Foreign key constraints are ignored by default&quot; : donc définir des clés étrangères ne sert à rien par défaut… </li>
<li>&quot;Bad default #2: Columns can store the wrong data type&quot; : donc vous mettez INTEGER commme type sur une colonne, bah ok vous pouvez mettre un INT mais vous pouvez insérer une chaîne de caractère contenant un INT ça va passer aussi (car converti à l&#39;insertion) mais aussi n&#39;importe quoi qui n&#39;est pas un INT ça sera stocké tel quel… Sauf si vous specifiez <code>strict</code> sur chaque définition de table… </li>
<li>&quot;Bad default #3: SQLITE_BUSY errors with concurrent writers&quot; : autant de readers de la base qu&#39;on veut en parallèle mais un seul writer, ça fonctionne sans lock / sans timeout (par défaut) donc un second writer qui arrive en parallèle ne va pas attendre, juste échouer directement… </li>
<li>&quot;Bad default 4: Performance&quot; : il y a des petites limites de performances facile à corriger (en particulier sur l&#39;écriture des logs) pour un usage serveur, pour le coup l&#39;auteur fait référence à d&#39;autres articles pour ce point</li>
</ul>
<p>Tout ça c&#39;est corrigeable avec des PRAGMA (règles à définir globalement sur votre instance SQLite) mais ça devrait être par défaut aujourd&#39;hui, je suis d&#39;accord avec l&#39;auteur de l&#39;article. </p>
<p>La proposition de l&#39;auteur serait d&#39;avoir un <code>PRAGMA edition = 2026;</code> (très similaire à ce qu&#39;on retrouve chez Rust) qui serait une configuration implicite pour </p>
<pre><code>PRAGMA foreign_keys = ON;
PRAGMA busy_timeout = 5000;
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
</code></pre><p>(ligne à ligne : activer la validation des clés étrangères ; s&#39;assurer qu&#39;on ne bloque pas directement les écritures concurrentes ; éviter les problèmes de performance sur l&#39;écriture des logs ; réduire les synchronisations avec le disque pour limiter les problèmes de performance) </p>
<p>Je trouve l&#39;idée plutôt pas mal. Ça ouvre pas mal de porte à des breaking changes en douceur (on peut introduire une config qui par défaut à une valeur qui ne casse rien mais si on spécifie qu&#39;on vise une édition plus récente, ça change la config et on doit suivre la nouvelle règle), ça permet aussi de décorréler la mise à jour de la librairie / l&#39;outil de la mise à jour des pratiques (particulièrement une bonne chose pour la sécurité, car vous pouvez garder une seule branche à corriger dans le temps). C&#39;est quelque chose qui serait profitable à voir un peu partout </p>
<h3 id="article-windows-cache-un-identifiant-secret-que-microsoft-file-au-fbi--korbenhttpskorbeninfowindowsgdididentifiantmouchardvpnhtml"><a href="https://korben.info/windows-gdid-identifiant-mouchard-vpn.html">Windows cache un identifiant secret que Microsoft file au FBI - Korben</a><a href="#article-windows-cache-un-identifiant-secret-que-microsoft-file-au-fbi--korbenhttpskorbeninfowindowsgdididentifiantmouchardvpnhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Microsoft #Vie-privée #OS #Windows</p>
<p>Un hackeur qui se fait avoir parce qu&#39;il utilise Windows 11 derrière sa pile de VPN (sûrement en se disant qu&#39;avoir un WSL c&#39;est largement aussi safe qu&#39;un Linux 🤷‍♂️) parce que Windows vous colle un identifiant unique (GDID = Global Device IDentifier) à l&#39;installation, identifiant qui est leak à droite à gauche, stocké avec votre IP à chaque fois que vous vous connectez à Internet. Évidemment, PatriotAct oblige, si le FBI ou CIA demande à Microsoft ils <strong>doivent</strong> leur filer les infos associées à votre GDID (votre historique d&#39;IP, de connexion, etc.). </p>
<p>Comment on se débarrasse du GDID ? Vous ne pouvez pas. Comment on change de GDID ? Vous ne pouvez pas. Comment vous pouvez voir votre GDID ? Vous ne pouvez pas.</p>
<p>Merci Microsoft de respecter notre droit à la vie privée 💩 </p>
<h3 id="article-low-resource-computinghttpslrccsdartmouthedu"><a href="https://lrc.cs.dartmouth.edu/">Low Resource Computing</a><a href="#article-low-resource-computinghttpslrccsdartmouthedu" class="anchor" aria-label="permalink">🔗</a></h3>
<p>Je cite directement toute la page d&#39;accueil qui correspond parfaitement à ce que je pense (j&#39;ai songé plusieurs fois à plaquer le web pour partir sur cette voie ces dernières années) :</p>
<blockquote>
<p>Looking Back, Looking Forward</p>
<p>Computation started as a puzzle. We built national banking systems using 92kIPS microprocessors. We built rendering engines using a PDP-8 and a DAC. We flew to the moon with a 2MHz CPU, a slide rule, and a dream. The resources behind these accomplishments look modest only in hindsight. What is trivial now was enough then.</p>
<p>Somewhere along the way, we lost sight of this goal. Software wastes hardware because it can afford to do so. We use Electron, wrangling the whole Chrome V8 engine, just to edit text; we ask gigawatt data centers what the weather will be tomorrow. It&#39;s a competition to see how much compute and money we can throw at our problems before they fix themselves. Exascale datacenters keep growing, gigawatt compute farms keep chugging more electricity, and billion-dollar networks keep asking for more money. It&#39;s a race to the bottom, and other than being boring and expensive, it&#39;s impossible to keep growing like this forever.</p>
<p>This year, LRC is looking at the past as an inspiration for the future. As mainstream computers hog more and more resources, meaningful computation remains essential at the scale of kilobytes, kilohertz, and nanowatts. This workshop is all about countering the fad of infinite growth, it&#39;s about putting processing power back in individuals&#39; hands, and it&#39;s about contributing to a more reasonable and sustainable future. How far can today&#39;s modest resources really go?</p>
<p>Let&#39;s find out. </p>
</blockquote>
<p>Par contre c&#39;est dommage, y&#39;a rien en ligne (ou pas trouvé), donc à moins d&#39;avoir un coup de chance et qu&#39;ils viennent des USA pour faire une édition pas loin c&#39;est dead on restera sur l&#39;introduction… </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Angular modern code style]]></title>
      <guid isPermaLink="false">2026/07/21/angular-modern-code-style</guid>
      <description><![CDATA[<p>Angular évolue pas mal depuis 3 ans et la version 16. Pas mal de choses ont changés dans la manière …</p>
]]></description>
      <link>https://anthonypena.fr/2026/07/21/angular-modern-code-style/index.html</link>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Frontend]]></category>
      <pubDate>Tue, 21 Jul 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Angular évolue pas mal depuis 3 ans et la version 16. Pas mal de choses ont changés dans la manière d&#39;écrire du code, et c&#39;est parfois compliqué de suivre tout ce qu&#39;on peut faire et comment le faire bien. Revenons sur tout ça !</p>
<blockquote>
<p>Note : tout ce que je vais dire dans cet article, il est possible de le retrouver de manière &quot;interactive&quot; sur une petite application que j&#39;ai créée (avec Angular évidemment) et déployée <a href="https://kuroidoruido.github.io/ng-modern-code-style/">ici</a>. Cette application &quot;guideline&quot; est pensée pour montrer comment passer d&#39;un composant utilisant les anciens code-styles vers un composant plus au goût du jour.</p>
</blockquote>
<h2 id="article-ecosysteme-et-quotidien-de-dev">Écosystème et quotidien de dev<a href="#article-ecosysteme-et-quotidien-de-dev" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Avant même de parler de code style, il faut rappeler qu&#39;Angular c&#39;est plus qu&#39;un framework : c&#39;est un écosystème de librairies et d&#39;outils pour nous aider au quotidien, pour répondre à différent besoin, certains officiels, d&#39;autres non.</p>
<p>Le premier à citer pour moi c&#39;est l&#39;<a href="https://angular.dev/tools/devtools">Angular DevTools</a>, car il va vous permettre d’introspecter votre application pendant la phase de développement pendant qu&#39;elle tourne. C&#39;est très pratique, ça donne une autre vision de l&#39;application, et même si ça demande un peu d&#39;habitude, ça peut vraiment aider à comprendre plus vite ce qui coince.</p>
<p>Ensuite pour moi en 2026, on est obligé de parler IA. Angular propose un fichier <code>AGENTS.md</code> (ou ̀<code>CLAUDE.md</code>, etc.) qui est très complet, et il donne une bonne base pour comprendre comment on doit faire du Angular dans le monde moderne. Il y a évidemment quelques portes ouvertes qui sont enfoncées (ce fichier est prévu pour cadrer un Agent IA à la base, donc c&#39;est logique), mais il y a un début de piste pour accompagner chaque développeur aussi.</p>
<p>Une étape du quotidien à ne pas négliger c&#39;est les migrations de versions. Si on les fait régulièrement et en suivant des bonnes pratiques, c&#39;est très simple, sinon ça peut devenir un calvaire. C&#39;est facile d&#39;être accompagné pour cette étape, et il faut pour moi commencer par aller lire le <a href="https://blog.angular.dev/">blog officiel</a> qui va annoncer les nouveautés importantes de chaque mise à jour. Je recommande aussi d&#39;aller voir le <a href="https://blog.ninja-squad.fr/">blog de la Ninja Squad</a> où pour chaque version on retrouvera un billet beaucoup plus détaillé, rentrant en profondeur dans ce qui change et s&#39;il faut faire attention à certains points. Il faut aussi inspecter les dépendances du projet, qui peuvent nous lier à une version Angular et nous empêcher de migrer. Pour réaliser la migration il faut absolument suivre le <a href="https://angular.dev/update-guide">guide de mise à jour officiel</a>, car il va nous indiquer tout ce qu&#39;il faut absolument vérifier avant de commencer la mise à jour, la commande à lancer pour réaliser la mise à jour et ce qu&#39;il faut valider après coup. Personnellement pour chaque migration, je vais m&#39;assurer que je n&#39;ai rien oublié côté script de migration via <a href="https://www.angular.courses/caniuse?tab%3Dfeatures">Angular Can I Use</a> et vérifier aussi quelles nouvelles fonctionnalités je peux maintenant utiliser (particulièrement utile si vous avez un peu de retard sur les versions !). On termine par un coup d&#39;œil pour s&#39;assurer qu&#39;aucune dépendance liée à Angular n&#39;a été oublié et qu&#39;un <code>npm ci</code> (après suppression des <code>node_modules</code>) fonctionne toujours bien.</p>
<h2 id="article-parlons-composant-simple">Parlons composant simple<a href="#article-parlons-composant-simple" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Même si tout le monde n&#39;est pas d&#39;accord avec ça : je vous recommande d&#39;utiliser des Single File Component (SFC). C&#39;est quoi un SFC ? Simplement un composant qui est entièrement écrit dans le fichier TypeScript, avec le template dans la propriété <code>template</code> (et non <code>templateUrl</code>, qui permet de pointer un fichier HTML), et le style dans <code>styles</code>. Ça va vous débloquer plusieurs choses : vous allez moins naviguer de fichier en fichier, vous serez incité à créer des petits composants (réutilisable ou non) pour ne pas avoir un fichier trop gros. Un composant n&#39;est qu&#39;une classe TypeScript et un template, ne sacralisez pas la création d&#39;un composant : faites des petits composants avec une responsabilité limitée et tout deviendra plus simple et plus maintenable dans le temps. Rappelez-vous aussi que rien n&#39;interdit en Angular d&#39;avoir plusieurs composants / directives dans le même fichier !</p>
<p>Il faut évidemment utiliser les nouveaux control flow. Adieu les <code>*ngIf</code>, <code>*ngFor</code> et <code>*ngSwitch</code>, bonjour les <code>@if</code>, <code>@for</code> et <code>@switch</code>. Ils sont plus simples à utiliser, beaucoup plus performant, bien mieux typé, ne demande aucun import. Pour le <code>@for</code> vous serez aussi obligé de passer un <code>track</code> pour qu&#39;Angular sache comment il doit identifier chaque entrée du <code>@for</code> et limiter les re-rendu inutile. Il faut autant que possible éviter de passer <code>$index</code>, qui risque de dégrader les performances si vous avez besoin de re-rendre souvent la liste à cause d&#39;ajout / suppression.</p>
<p>Côté entrée/sortie, exit aussi des <code>@Input()</code> et <code>@Output()</code>, bienvenue aux <code>input()</code> et <code>output()</code>. Je dirais même que vous voulez au maximum écrire <code>input.required&lt;TheInputType&gt;()</code> pour indiquer explicitement quelles sont les entrées obligatoires au bon fonctionnement de votre composant, et aussi leur type pour que ce soit vérifié à la compilation ! Comme nos entrées / sorties sont censés être immuables, profitez-en pour les passer systématiquement en <code>public readonly</code>, de cette façon c&#39;est TypeScript qui s&#39;assurera que vous ne fassiez pas d&#39;erreur. </p>
<p>Dans la même logique, ajoutez <code>private readonly</code> devant chaque propriété que vous définissez dans votre classe, <code>protected readonly</code> si vous avez besoin d&#39;y accéder dans le template. Encapsuler au maximum vos composants est toujours une bonne chose, et protéger au maximum les états internes est important. Au passage ça donnera une indication claire aux autres développeurs sur où est utilisé un élément (<code>private</code> = uniquement dans la classe TypeScript, <code>protected</code> = dans la classe et/ou le template, <code>public</code> = à l&#39;extérieur). En TypeScript, ne pas indiquer de modificateur de portée impliquera que l&#39;élément sera <code>public</code> implicitement.</p>
<p>Même si historiquement on conseillait d&#39;utiliser beaucoup plus les Pipe pour les formatages, et au final à l&#39;usage, on se rend compte qu&#39;il vaut mieux utiliser simplement un <code>computed()</code>. La syntaxe est plus courte, on retrouve quasiment les mêmes avantages que les Pipes (à part la réutilisabilité), c&#39;est assez naturel quand on manipule beaucoup de Signal.</p>
<p>Respecter le naming convention d&#39;Angular c&#39;est important aussi. Les basiques c&#39;est avoir un <code>app-</code> au début du sélecteur de chaque composant, utiliser systématiquement du kebab-case pour le nom du sélecteur, du PascalCase pour les noms de composant (sans spécifier Component à la fin). Techniquement ça fonctionne bien sans ça, mais ça permet de plus facilement s&#39;y retrouver, plus facilement suivre ce qu&#39;on fait, être raccord entre les différents membres de l&#39;équipe.</p>
<p>Pour finir : ne pas oublier la plateforme. Quand vous faite du Angular, vous allez utiliser la plateforme web, utilisez une solution native de la plateforme web plutôt qu&#39;une solution Angular sera toujours mieux !</p>
<p>Voici un exemple avec deux composants qui respectent ce code style :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span>, computed, input } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {
    <span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>;
    <span class="hljs-attr">firstname</span>: <span class="hljs-built_in">string</span>;
    <span class="hljs-attr">lastname</span>: <span class="hljs-built_in">string</span>;
}

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;app-person-card&quot;</span>,
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
        &lt;div class=&quot;card&quot;&gt;
            &lt;h3&gt;{{fullName()}}&lt;/h3&gt;
        &lt;/div&gt;
        `</span>,
    <span class="hljs-attr">styles</span>: <span class="hljs-string">`
        .card {
            border: 1px solid light-dark(lightblue, orange);
            padding: 0.5em 1rem;
        }
        `</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PersonCard</span> {
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">readonly</span> person = input.<span class="hljs-property">required</span>&lt;<span class="hljs-title class_">Person</span>&gt;();
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> fullName = <span class="hljs-title function_">computed</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.person().firstname}</span> <span class="hljs-subst">${<span class="hljs-variable language_">this</span>.person().lastname}</span>`</span>);
}

<span class="hljs-keyword">const</span> <span class="hljs-attr">PEOPLE</span>: <span class="hljs-title class_">Person</span>[] = [
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;0&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Aïcha&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Diallo&quot;</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;1&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Lucas&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Martinez&quot;</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;2&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Léa&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Nguyen&quot;</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;3&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Karim&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Benali&quot;</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;4&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Mei&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Chen&quot;</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;5&quot;</span>, <span class="hljs-attr">firstname</span>: <span class="hljs-string">&quot;Élodie&quot;</span>, <span class="hljs-attr">lastname</span>: <span class="hljs-string">&quot;Moreau&quot;</span> },
];

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;app-person-list&quot;</span>,
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
        @for (person of PEOPLE; track person.id) {
            &lt;app-person-card [person]=&quot;person&quot; /&gt;
        }
        `</span>,
    <span class="hljs-attr">styles</span>: <span class="hljs-string">`
        :host {
            display: flex;
            gap: 0.25em;
            flex-wrap: wrap;
        }
        `</span>,
    <span class="hljs-attr">imports</span>: [<span class="hljs-title class_">PersonCard</span>],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PersonList</span> {
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> <span class="hljs-variable constant_">PEOPLE</span> = <span class="hljs-variable constant_">PEOPLE</span>;
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><h2 id="article-et-on-ajoute-un-service-">Et on ajoute un service !<a href="#article-et-on-ajoute-un-service-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Le grand classique c&#39;est de voir des choses comme ça :</p>
<pre><code class="hljs language-TypeScript">
<span class="hljs-meta">@Component</span>({ ... })
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PersonList</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">OnInit</span> {
    <span class="hljs-keyword">protected</span> <span class="hljs-attr">people</span>: <span class="hljs-title class_">Person</span>[] = [];

    <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> <span class="hljs-attr">http</span>: <span class="hljs-title class_">HttpClient</span></span>) {}

    <span class="hljs-title function_">ngOnInit</span>(<span class="hljs-params"></span>) {
        <span class="hljs-variable language_">this</span>.<span class="hljs-property">http</span>.<span class="hljs-title function_">get</span>(<span class="hljs-string">&quot;/assets/demo/components-and-services/people.json&quot;</span>).<span class="hljs-title function_">subscribe</span>(<span class="hljs-function">(<span class="hljs-params"><span class="hljs-attr">people</span>: <span class="hljs-built_in">any</span></span>) =&gt;</span> {
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">people</span> = people;
        });
    }
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Trop de problèmes… On passe toujours pas de l&#39;injection dans le constructeur, on a toujours un <code>ngOnInit()</code>, on utilise le <code>HttpClient</code> dans le composant directement, on fait un subscribe (sans unsubscribe de surcroit), on ne type correctement…</p>
<p>En Angular moderne, vous pouvez faire beaucoup plus simple. Déjà vous pouvez passer directement par <code>inject()</code> pour injecter vos différents services en propriété (<code>private readonly</code> évidemment !). Comme on a besoin que d&#39;un seul appel, on peut directement faire d&#39;un coup l&#39;injection et l&#39;appel, en typant directement le <code>inject(HttpClient).get&lt;Person[]&gt;(...)</code> pour éviter un <code>any</code>. On peut éviter le <code>.subscribe()</code> en passant par un <code>toSignal(...)</code> et laisser Angular gérer ça pour nous.</p>
<p>Tant qu&#39;à faire on peut déplacer toute cette logique d&#39;appel vers un service dédié. Si on a besoin, on pourra alors même faire un cache interne au service pour s&#39;assurer qu&#39;on ne fait pas un appel HTTP pour chaque utilisation du service.</p>
<p>En résumé, l&#39;idée c&#39;est de viser quelque chose qui ressemble à ça :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">HttpClient</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/common/http&quot;</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span>, <span class="hljs-title class_">Injectable</span>, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;
<span class="hljs-keyword">import</span> { toSignal } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core/rxjs-interop&quot;</span>;
<span class="hljs-keyword">import</span> { catchError, <span class="hljs-keyword">of</span>, shareReplay } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;rxjs&quot;</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">PersonCard</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;./person-card&quot;</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {
    <span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>;
    <span class="hljs-attr">firstname</span>: <span class="hljs-built_in">string</span>;
    <span class="hljs-attr">lastname</span>: <span class="hljs-built_in">string</span>;
}

<span class="hljs-meta">@Injectable</span>({ <span class="hljs-attr">providedIn</span>: <span class="hljs-string">&quot;root&quot;</span> })
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PeopleService</span> {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> http = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">HttpClient</span>);
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> people$ = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">httpGetPeople</span>().<span class="hljs-title function_">pipe</span>(<span class="hljs-title function_">shareReplay</span>(<span class="hljs-number">1</span>));

    <span class="hljs-title function_">getPeople</span>(<span class="hljs-params"></span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">people$</span>;
    }

    <span class="hljs-keyword">private</span> <span class="hljs-title function_">httpGetPeople</span>(<span class="hljs-params"></span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">http</span>.<span class="hljs-property">get</span>&lt;<span class="hljs-title class_">Person</span>[]&gt;(<span class="hljs-string">&quot;/assets/demo/components-and-services/people.json&quot;</span>).<span class="hljs-title function_">pipe</span>(
            <span class="hljs-title function_">catchError</span>(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(err);
                <span class="hljs-keyword">return</span> <span class="hljs-title function_">of</span>([]);
            }),
        );
    }
}

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;app-person-list&quot;</span>,
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
        @for (person of people(); track person.id) {
            &lt;app-person-card [person]=&quot;person&quot; /&gt;
        }
        `</span>,
    <span class="hljs-attr">styles</span>: <span class="hljs-string">`
        :host {
            display: flex;
            gap: 0.25em;
            flex-wrap: wrap;
        }
    `</span>,
    <span class="hljs-attr">imports</span>: [<span class="hljs-title class_">PersonCard</span>],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PersonList</span> {
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> people = <span class="hljs-title function_">toSignal</span>(<span class="hljs-title function_">inject</span>(<span class="hljs-title class_">PeopleService</span>).<span class="hljs-title function_">getPeople</span>(), { <span class="hljs-attr">initialValue</span>: [] });
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Côté composant c&#39;est vraiment beaucoup plus simple, on retrouve juste une déclaration d&#39;un accès à une liste de personne. Dans le service on retrouve notre appel HTTP mais aussi une gestion d&#39;erreur (simpliste mais présente pour l&#39;exemple), on retrouve aussi une mécanique simple de partage de ressource entre différent appelants (comme on pose dès le début un <code>Observable</code> <code>people$</code> qui est un appel HTTP suivi d&#39;un <code>shareReplay(1)</code>, le premier subscriber va déclencher l&#39;appel HTTP, les suivants consommeront directement la réponse). Au passage cette mécanique nous permet d&#39;encapsuler entièrement l&#39;appel HTTP, donc si demain on veut changer quoi que ce soit (changer l&#39;URL, ajouter une transformation avant/après chaque appel, etc.) on pourra le faire en impactant pas les appelant ou à minima en sachant très facilement qui dépend de cet appel (seulement les appelants de <code>getPeople()</code> qui ne peuvent que lire cet <code>Observable</code> et rien de plus).</p>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>On trouve beaucoup de ressources en ligne qui indiquent comment faire bien un point particulier en Angular, on retrouve peu de contenu qui vous donne un guide pour passer sur le code style moderne avec les explications qui vont bien. Je ne sais pas si ce que j&#39;ai fait répondra vraiment à ce besoin, mais je vais essayer de maintenir mon application à jour au fil des versions, d&#39;améliorer le contenu au fil du temps, pour le rendre toujours utile au plus grand nombre.</p>
<p>Sources :</p>
<ul>
<li><a href="https://kuroidoruido.github.io/ng-modern-code-style/">Guide interactif</a></li>
<li><a href="https://angular.dev/tools/devtools">Angular DevTools</a></li>
<li><a href="https://blog.angular.dev/">Blog officiel Angular</a></li>
<li><a href="https://blog.ninja-squad.fr/">Blog de la Ninja Squad</a></li>
<li><a href="https://angular.dev/update-guide">Guide de mise à jour officiel</a></li>
<li><a href="https://www.angular.courses/caniuse?tab%3Dfeatures">Angular Can I Use</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A serene Studio Ghibli-inspired scene of a Zen garden where Angular component flowers bloom, viewed from a close-up perspective. Each flower has a label with modern Angular features like &#39;@for&#39;, &#39;computed()&#39;, &#39;toSignal&#39;, and &#39;inject()&#39;. The flowers representing SFC (Single File Component) are peonies with petals shaped like TypeScript files. A magical watering can (teapot-shaped) is watering the flowers, making them grow, while weeds labeled &#39;*ngFor without track&#39; and &#39;any&#39; wither away. A red panda, sitting cross-legged, is trimming a bush shaped like the &#39;PersonCard&#39; component. In the background, a torii gate has a sign reading &#39;Angular DevTools&#39;. The atmosphere is peaceful with green/blue gradients and golden reflections on the petals. The scene is set in autumn with a warm, golden light, wooden textures, and 8-10 floating maple leaves in red, orange, and yellow. The red panda is in the bottom right, less than 1/3 of the height, with a glowing halo around the high-tech elements.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Juillet 2026]]></title>
      <guid isPermaLink="false">2026/07/08/revue-de-presse-juillet</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/07/08/revue-de-presse-juillet/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Wed, 08 Jul 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-cloudflare-rachete-voidzero-la-societe-open-source-derriere-vite-et-les-outils-de-compilation-javascript-qui-lentourent-afin-de-placer-sa-plateforme-pour-developpeurs-au-cur-du-developpement-web-avec-liahttpsjavascriptdeveloppezcomactu383913cloudflarerachetevoidzerolasocieteopensourcederriereviteetlesoutilsdecompilationjavascriptquilentourentafindeplacersaplateformepourdeveloppeursaucoeurdudeveloppementwebaveclia"><a href="https://javascript.developpez.com/actu/383913/Cloudflare-rachete-VoidZero-la-societe-open-source-derriere-Vite-et-les-outils-de-compilation-JavaScript-qui-l-entourent-afin-de-placer-sa-plateforme-pour-developpeurs-au-coeur-du-developpement-web-avec-l-IA/">Cloudflare rachète VoidZero, la société open source derrière Vite et les outils de compilation JavaScript qui l&#39;entourent, afin de placer sa plateforme pour développeurs au cur du développement web avec l&#39;IA</a><a href="#article-cloudflare-rachete-voidzero-la-societe-open-source-derriere-vite-et-les-outils-de-compilation-javascript-qui-lentourent-afin-de-placer-sa-plateforme-pour-developpeurs-au-cur-du-developpement-web-avec-liahttpsjavascriptdeveloppezcomactu383913cloudflarerachetevoidzerolasocieteopensourcederriereviteetlesoutilsdecompilationjavascriptquilentourentafindeplacersaplateformepourdeveloppeursaucoeurdudeveloppementwebaveclia" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Vite #Frontend #VoidZero #Cloudflare</p>
<p>VoidZero, donc Vite et tous les outils sous-jacents, part sous la gouverne de Cloudflare. Evan You reste à la tête de la roadmap de toute la suite open source. </p>
<p>Avec Evan You à la tête, on peut espérer que tout reste cohérent et que tout continue sur la même trajectoire. Si on le voit partir, il sera temps de paniquer j&#39;imagine 😅 </p>
<h3 id="article-openng-foundationhttpswwwopenngorg"><a href="https://www.openng.org/">OpenNG Foundation</a><a href="#article-openng-foundationhttpswwwopenngorg" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Angular #Frontend</p>
<p>Super initiative : Gérôme Grignon et Dominic Bachmann ont décidé de lancer une fondation pour porter des librairies Angular qui sont un peu partout pourtant abandonnés. L&#39;idée c&#39;est de permettre aux équipes qui utilisent ces libs de basculer sur le fork supporté par la fondation pour ensuite suivre les nouvelles versions d&#39;Angular soit en maintenant la lib soit en proposant des schematics de migration vers des briques standard et modernes d&#39;Angular pour retirer la dépendance.</p>
<p>Pour décider quelles libs seront maintenues par ce biais, on peut soumettre une lib en postant une issue sur le Github et avoir une évaluation de la nécessité de maintenir. </p>
<p>Les process sont encore en construction, mais je pense que ça peut donner des très bonnes choses dans le futur ! </p>
<h3 id="article-desktop-apps--deno-docshttpsdocsdenocomruntimedesktop"><a href="https://docs.deno.com/runtime/desktop/">Desktop apps | Deno Docs</a><a href="#article-desktop-apps--deno-docshttpsdocsdenocomruntimedesktop" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Deno #TypeScript #App #Frontend</p>
<p>Grosse nouveauté de la part de Deno : la possibilité de créer des applications Desktop (en CLI ou avec des fenêtres graphiques) avec Deno avec un simple <code>deno desktop</code> ! 😲 </p>
<p>C&#39;est un truc de fou. C&#39;est pas encore dans la version stable, mais je trouve ça déjà fou ! </p>
<h3 id="article-whats-new-in-angular-220--ninja-squadhttpsblogninjasquadcom20260603whatisnewangular220"><a href="https://blog.ninja-squad.com/2026/06/03/what-is-new-angular-22.0">What&#39;s new in Angular 22.0? - Ninja Squad</a><a href="#article-whats-new-in-angular-220--ninja-squadhttpsblogninjasquadcom20260603whatisnewangular220" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Angular #Frontend</p>
<p>Beaucoup de petites nouveautés sur cette version comme d&#39;habitude. Je vous encourage à aller voir l&#39;article de Cédric qui détaille tout très bien !</p>
<p>Ce que je retiens surtout :</p>
<ul>
<li>le passage en stable des Signal Forms ;</li>
<li><code>OnPush</code> par défaut sur tous les composants (sur une application perso dont je parle bientôt, la migration de v21 à v22 m&#39;a ajouté <code>changeDetection: ChangeDetectionStrategy.Eager</code> sur tous mes composants, et je les ai enlevés sans incidence, mais à tester de votre côté !) ;</li>
<li><code>resource()</code>, <code>rxResource()</code> et <code>httpResource()</code> passent en stable ;</li>
<li>introduction de <code>@Service()</code> qui est presque équivalent à <code>@Injectable({ providedIn: &#39;root&#39; })</code> (presque, car on ne peut utiliser que <code>inject()</code> pour faire de l&#39;injection et quelques autres petites subtilités) mais maintenant recommandé ;</li>
<li>le client <code>Http</code> utilise maintenant <code>fetch()</code> par défaut (attention à la migration qui va vous ajouter <code>withXhr()</code> automatiquement pour rester en <code>XMLHttpRequest</code> pour éviter le breaking change) ;</li>
<li>pas mal de petites améliorations sur la compilation/validation des templates ;</li>
</ul>
<p>Pas de très gros changement, mais encore et toujours la continuité des évolutions qui vont amener des choses bienvenues !</p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-uber--lia-coute-cher-alors-les-employes-devront-moins-lutiliser-a-lavenirhttpswwwclubiccomactualite615268uberliacoutecheralorslesemployesdevrontmoinslutiliseralavenirhtml"><a href="https://www.clubic.com/actualite-615268-uber-l-ia-coute-cher-alors-les-employes-devront-moins-l-utiliser-a-l-avenir.html">Uber : l&#39;IA coûte cher, alors les employés devront moins l&#39;utiliser à l&#39;avenir</a><a href="#article-uber--lia-coute-cher-alors-les-employes-devront-moins-lutiliser-a-lavenirhttpswwwclubiccomactualite615268uberliacoutecheralorslesemployesdevrontmoinslutiliseralavenirhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA</p>
<p>500 millions de dollars dépensé en 1 mois. Plafond à $1500/mo/outils/dev. Bon bah voilà même des grosses boîtes comme Uber commencent à mettre le holà.</p>
<p>Il faut renflouer les caisses après avoir passé 3 ans à cramer le pognon des investisseurs 😅 </p>
<h3 id="article-un-editeur-de-logiciels-va-priver-ses-5000-employes-daugmentations-pour-consacrer-ces-fonds-aux-investissements-en-ia-les-pdg-persistent-dans-lia-en-depit-des-retours-de-productivite-et-financiers-decevantshttpsintelligenceartificielledeveloppezcomactu383904unediteurdelogicielsvapriverses5000employesdaugmentationspourconsacrercesfondsauxinvestissementsenialespdgpersistentdansliaendepitdesretoursdeproductiviteetfinanciersdecevants"><a href="https://intelligence-artificielle.developpez.com/actu/383904/Un-editeur-de-logiciels-va-priver-ses-5000-employes-d-augmentations-pour-consacrer-ces-fonds-aux-investissements-en-IA-Les-PDG-persistent-dans-l-IA-en-depit-des-retours-de-productivite-et-financiers-decevants/">Un éditeur de logiciels va priver ses 5000 employés d&#39;augmentations pour consacrer ces fonds aux investissements en IA. Les PDG persistent dans l&#39;IA en dépit des retours de productivité et financiers décevants</a><a href="#article-un-editeur-de-logiciels-va-priver-ses-5000-employes-daugmentations-pour-consacrer-ces-fonds-aux-investissements-en-ia-les-pdg-persistent-dans-lia-en-depit-des-retours-de-productivite-et-financiers-decevantshttpsintelligenceartificielledeveloppezcomactu383904unediteurdelogicielsvapriverses5000employesdaugmentationspourconsacrercesfondsauxinvestissementsenialespdgpersistentdansliaendepitdesretoursdeproductiviteetfinanciersdecevants" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Emploi</p>
<p>Donc en résumé :</p>
<ul>
<li>on arrive toujours pas à montrer une rentabilité franche sur les projets IA ;</li>
<li>on voit le prix des outils d&#39;IA exploser, donc la rentabilité s&#39;éloigner ;</li>
<li>travailler avec des outils d&#39;IA coûte plus cher que faire travailler des humains ;</li>
<li>on voit toujours une impasse écologique à date à continuer de faire croître les usages IA (pas dans l&#39;article, mais facile de trouver des sources) ;</li>
</ul>
<p>Conclusion : il faut continuer à claquer un max d&#39;argent dans l&#39;IA pour pas perdre la course face aux autres boîtes 😅 quitte à ne plus augmenter du tout ses employés pour avoir du cash à mettre dans ce mirage 🤔 </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-github--webbacreativetechnologiesvice-vice-is-a-security-auditing-cli-tool-that-finds-vulnerabilities-in-your-web-applications--githubhttpsgithubcomwebbacreativetechnologiesvice"><a href="https://github.com/Webba-Creative-Technologies/vice">GitHub - Webba-Creative-Technologies/vice: VICE is a security auditing CLI tool that finds vulnerabilities in your web applications. · GitHub</a><a href="#article-github--webbacreativetechnologiesvice-vice-is-a-security-auditing-cli-tool-that-finds-vulnerabilities-in-your-web-applications--githubhttpsgithubcomwebbacreativetechnologiesvice" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#HTTP #Sécurité #Web</p>
<p>Je cite un bout du post LinkedIn de l&#39;auteur :</p>
<blockquote>
<p>On a construit VICE pour répondre à cette question.</p>
<p>C&#39;est un outil open source qui audite la sécurité de tes apps web. Tu lui donnes une URL, il fait comme un attaquant : il crawle le site avec un vrai navigateur, cherche les secrets dans le JS, teste les RLS Supabase, scanne les ports de ton VPS, tente du brute force sur ton login, vérifie les headers HTTP, et te sort un rapport avec un score de A à F.</p>
<p>Il a aussi un mode local : tu le lances dans ton projet et il analyse ton code source. Il trouve les injections SQL, les XSS, les .env mal configurés, les dépendances vulnérables, et te dit exactement quoi corriger avec des exemples de code.</p>
<p>22 modules. Un seul outil. Open source.</p>
</blockquote>
<h3 id="article-une-hackeuse-a-pris-le-controle-du-streaming-du-mondial-2026-et-a-failli-troller-3-milliards-de-telespectateurshttpswwwclubiccomactualite619945unehackeuseaprislecontroledustreamingdumondial2026etafaillitroller3milliardsdetelespectateurshtml"><a href="https://www.clubic.com/actualite-619945-une-hackeuse-a-pris-le-controle-du-streaming-du-mondial-2026-et-a-failli-troller-3-milliards-de-telespectateurs.html">Une hackeuse a pris le contrôle du streaming du Mondial 2026 et a failli troller 3 milliards de téléspectateurs</a><a href="#article-une-hackeuse-a-pris-le-controle-du-streaming-du-mondial-2026-et-a-failli-troller-3-milliards-de-telespectateurshttpswwwclubiccomactualite619945unehackeuseaprislecontroledustreamingdumondial2026etafaillitroller3milliardsdetelespectateurshtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #Hack</p>
<p>Bobdahacker a pu se créer un compte agent FIFA et accéder à tout ce qui faisait fonctionner les diffusions live de la Coupe du Monde 2026 (flux streams, sources des flux, paramétrages, etc.) </p>
<p>Le maillon le plus faible de la chaîne de sécurité c&#39;est l&#39;humain :</p>
<ul>
<li>les devs qui n&#39;ont mis une sécurité que côté client ;</li>
<li>les gens qui ont posé le process de création de compte ;</li>
<li>les gens qui valident la création de compte ;</li>
<li>les gens qui ont décidé d&#39;affecter les droits à n&#39;importe quel agent pour l&#39;accès à ces briques-là ;</li>
</ul>
<p>Sérieux souci de sécurité à la FIFA 😅 </p>
<h3 id="article-google-veut-scanner-votre-main-pour-prouver-que-vous-etes-humain--korbenhttpskorbeninfogooglerecaptchascanmainhtml"><a href="https://korben.info/google-recaptcha-scan-main.html">Google veut scanner votre main pour prouver que vous êtes humain - Korben</a><a href="#article-google-veut-scanner-votre-main-pour-prouver-que-vous-etes-humain--korbenhttpskorbeninfogooglerecaptchascanmainhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Google #Vie-privée #Sécurité</p>
<p>En résumé : faire du CAPTCHA mais en se basant sur 21 points spécifiques de notre main pour valider que c&#39;est une main humaine… </p>
<p>Je cite Korben qui résume bien le truc :</p>
<blockquote>
<p>Côté vie privée, Google jure sur la tête de ses morts que toutes les vidéos et les photos prises par le CAPTCHA sont supprimées une fois le défi relevé, qu&#39;aucun son n&#39;est enregistré et que rien n&#39;est associé à votre identité mais peu importe ce qu&#39;ils nous baragouinent, on n&#39;a aucun moyen de le vérifier de toute façon.</p>
<p>Puis que ce soit votre main, votre visage ou vos fesses, prendre 21 points de mesure sur votre anatomie, ça reste de la biométrie quand même. Rien qu&#39;avec ça, vous pouvez identifier une personne avec 99% de précision… Donc n&#39;allez pas me dire qu&#39;ils n&#39;ont pas autre chose en tête avec cette connerie.</p>
</blockquote>
<p>Un usage biométrique pour faire de la sécurité contournée en 10s via des photos, qu&#39;ils savent qu&#39;on peut contourner en 2 clics en basculant sur l&#39;ancien système (Google ne peut pas obliger ce système : y&#39;a des utilisateurs sans main ou qui ne peuvent pas les bouger), c&#39;est clairement pas la sécurité le but derrière… </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-lets-encrypt-interdit-lutilisation-de-son-ses--services-aux-pays-sanctionnes-par-les-etatsunis--carlchenetmastodonsocialhttpssebsauvagenetpframapiaforgs116719310027759727"><a href="https://sebsauvage.net/p/#/framapiaf.org/s/116719310027759727">Let&#39;s Encrypt interdit l&#39;utilisation de son (ses ?) service·s aux pays sanctionnés par les États-Unis — carlchenet@mastodon.social</a><a href="#article-lets-encrypt-interdit-lutilisation-de-son-ses--services-aux-pays-sanctionnes-par-les-etatsunis--carlchenetmastodonsocialhttpssebsauvagenetpframapiaforgs116719310027759727" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#USA #Internet #HTTP #Web</p>
<p>Let&#39;s Encrypt se soumet aux blocages demandés par les USA. Pourquoi ? Let&#39;s Encrypt c&#39;est géré par l&#39;ISRG (Internet Security Research Group). Et sur le site de l&#39;ISRG on peut lire </p>
<blockquote>
<p>ISRG is a California public benefit corporation[…]</p>
</blockquote>
<p>Donc en résumé : à date Let&#39;s Encrypt c&#39;est américain donc soumis aux Lois américaines 🤷‍♂️ et croyez-moi : ça me soule parce que c&#39;est très bien, mais il va falloir commencer à chercher des alternatives souveraines… </p>
<h3 id="article-github--weeblabsdspi-a-fully-featured-audio-dsp-firmware-for-the-raspberry-pi-pico-rp2040-and-pico-2-rp2350--githubhttpsgithubcomweeblabsdspi"><a href="https://github.com/WeebLabs/DSPi">GitHub - WeebLabs/DSPi: A fully featured audio DSP firmware for the Raspberry Pi Pico (RP2040) and Pico 2 (RP2350) · GitHub</a><a href="#article-github--weeblabsdspi-a-fully-featured-audio-dsp-firmware-for-the-raspberry-pi-pico-rp2040-and-pico-2-rp2350--githubhttpsgithubcomweeblabsdspi" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Raspberry-Pi #RP2040 #RP2350</p>
<p>Assez impressionné de voir un moteur DSP pour Raspberry Pi Pico (RP2020) ou Pico 2 (RP2350) très complet, surtout vu le prix de ces puces ! Ça ouvre pas de porte pour du matériel ouvert et vraiment pas cher ! </p>
<h3 id="article-developer-advocate-cest-une-bonne-situation-ca---calmhttpscalmshowblogbonnesituation"><a href="https://calm.show/blog/bonne-situation/">Developer Advocate, c&#39;est une bonne situation ça ? - CALM</a><a href="#article-developer-advocate-cest-une-bonne-situation-ca---calmhttpscalmshowblogbonnesituation" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Métier-de-dev #Dev #DevRel</p>
<p>Article de Thierry Chantier sur son parcours et ses questionnements autour du métier de Developer Advocate (aussi appelé Developer Relation ou DevRel ou d&#39;autres noms).</p>
<p>C&#39;est toujours intéressant de voir des gens se questionner sur leur métier et voir où ça les emmène. On voit dans le cas de Thierry que finalement le métier lui est un peu tombé dessus parce qu&#39;il faisait naturellement le travail mais en temps perso</p>
<p>Merci Thierry pour ce REX ! </p>
<h3 id="article-assurance-leocare--avis-tres-negatif--le-hollandais-volanthttpslehollandaisvolantnetd20260620003139assuranceleocareavistresnegatif"><a href="https://lehollandaisvolant.net/?d%3D2026/06/20/00/31/39-assurance-leocare-avis-tres-negatif">Assurance Léocare : avis (très) négatif - Le Hollandais Volant</a><a href="#article-assurance-leocare--avis-tres-negatif--le-hollandais-volanthttpslehollandaisvolantnetd20260620003139assuranceleocareavistresnegatif" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Assurance</p>
<p>Je partage car beaucoup d&#39;informations intéressantes sur Léocare (une société d&#39;assurance) mais même sur les procédures avec les assurances en général </p>
<p>En tout cas : 1) je n&#39;irais jamais chez Léocare 2) je n&#39;ai jamais eu ce genre de souci avec Pacifica (mon plus gros problème avec eux à date c&#39;est le besoin récurrent de passer par téléphone pour la plupart des démarches, mais toujours faites hyper vite en contrepartie) </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Organiser une conférence ça veut dire quoi ?]]></title>
      <guid isPermaLink="false">2026/06/16/organiser-une-conference-ca-veut-dire-quoi</guid>
      <description><![CDATA[<p>J&#39;en parle régulièrement mais depuis 2 ans maintenant je suis un des co-organisateur d&#39;une conférenc…</p>
]]></description>
      <link>https://anthonypena.fr/2026/06/16/organiser-une-conference-ca-veut-dire-quoi/index.html</link>
      <category><![CDATA[NG Baguette Conf]]></category>
      <category><![CDATA[REX]]></category>
      <pubDate>Tue, 16 Jun 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>J&#39;en parle régulièrement mais depuis 2 ans maintenant je suis un des co-organisateur d&#39;une conférence autour du framework Angular (et accessoirement Vice-Président de l&#39;association qui porte la conférence). Ça fait quelque temps que je réfléchissais à faire (ou pas) un article sur le sujet, vous expliquer comment on vit le truc de l&#39;intérieur, comment on fonctionne, comment tout se finance. L&#39;envers du décor, tout ce qu&#39;on ne voit pas habituellement quand on est participant.</p>
<blockquote>
<p>Préambule : si je fais cet article, ce n&#39;est pas pour me plaindre : j&#39;ai choisi d&#39;être membre de l&#39;association (étant un des fondateurs), j&#39;ai choisi d&#39;être organisateur en connaissance de cause, mais je trouvais ça important de partager sur une réalité qui n&#39;est pas trop vu des participants, parce que ça me parait toujours important de partager sur nos expériences, et que ça pourrait aider d&#39;autres organisateurs de conférences à relativiser et/ou à se lancer.</p>
</blockquote>
<h2 id="article-de-angular-devs-france-a-ng-baguette-conf-en-passant-par-angular-nexus">De Angular Devs France à NG Baguette Conf en passant par Angular Nexus<a href="#article-de-angular-devs-france-a-ng-baguette-conf-en-passant-par-angular-nexus" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Pour créer une conférence il nous fallait un cadre légal : une identité juridique, un compte bancaire, et un nom. Si dès 2023, on a communiqué sous le nom Angular Devs France, on voulait un nom plus percutant pour la conférence, et après pas mal de réflexion, on s&#39;était arrêté sur Angular Nexus (Nexus signifiant &quot;connexion&quot; en grec, ça représentait plutôt bien ce qu&#39;on cherchait à réaliser).</p>
<p>Vous n&#39;avez jamais vu la conférence Angular Nexus ? Ne vous en faites pas, vous n&#39;avez rien loupé, elle n&#39;a jamais eu lieu. C&#39;est un projet de 2024 mort dans l&#39;œuf… Mais qui nous aura permis de prendre du recul et réfléchir !</p>
<p>Par contre, nous avons monté une association avec ce nom. Après quelques changements et quelques péripéties administratives, nous sommes aujourd&#39;hui deux membres dans le bureau (Gérôme est président et moi-même je suis vice-président (après avoir eu le rôle de trésorier 😈)), ainsi que deux membres Camille et Yann-Thomas. On a choisi d&#39;avoir un bureau très simple et des statuts qui nous permettent d&#39;évoluer facilement pour garder de la souplesse.</p>
<p>En 2025, on a réalisé une première édition d&#39;une conférence : NG Baguette Conf (en partant d&#39;une blague qui circulait qu&#39;une conférence française devrait forcément s&#39;appeler &quot;NG Baguette&quot;). En janvier 2025, nous n&#39;avions pas de compte en banque, pas de statuts exploitables et on s&#39;est fixé de jouer notre conférence fin mai. On a eu la chance et un peu de culot, on a pu réserver gracieusement une partie des locaux de Onepoint Nantes et on a eu de l&#39;aide pour la partie traiteur. En un peu plus de 4 mois, nous sommes passés d&#39;une chaîne Youtube à une conférence en physique, des tops speakers européen et une centaine de personnes qui nous ont fait confiance. Pour être honnête : j&#39;avançais la tête dans le guidon sans y croire complètement, il a fallu que je voie les gens défiler à la billetterie pour réaliser !</p>
<p>Puis on a remis une pièce pour une seconde édition, en augmentant l&#39;ambition.</p>
<h2 id="article-lete-2025">L&#39;été 2025<a href="#article-lete-2025" class="anchor" aria-label="permalink">🔗</a></h2>
<p>En Juin 2025, Gérôme, Camille, Yann-Thomas et moi avons fait le bilan de NG Baguette Conf 2025 :</p>
<ul>
<li>On avait un peu moins de 600€ sur le compte en banque (tout notre budget 2025 étant globalement parti dans la nourriture pour le déjeuner) ;</li>
<li>On avait des contacts à Nantes, même si plus personne de l&#39;équipe n&#39;y vivait (Gérôme et moi vivions encore à Nantes jusqu&#39;à début 2025) ;</li>
<li>On avait des retours sur la première édition nous montrant que refaire une édition à Nantes serait une erreur ;</li>
<li>On avait envie de refaire une édition, mais en changeant tout ce qui paraissait non viable et en suivant les quelques retours qu&#39;on avait eus via le formulaire de feedback ;</li>
</ul>
<p>On décide de passer du samedi au vendredi. On décide d&#39;augmenter le prix du billet participant, la première édition ayant été compliquée du fait qu&#39;on faisait reposer une trop grosse part de notre budget sur les sponsors et avec des billets d&#39;entrées quasi donné (25-30€). On décide de déplacer la conférence sur Paris, plus central que Nantes, plus facile d&#39;accès en train.</p>
<p>On se lance dans la recherche d&#39;un lieu pour fixer la date ! Ah non… Réaliser NG Baguette Conf 2025 a été une course épuisante, on a pas réussi à avoir de l&#39;énergie pour bosser le sujet dans l&#39;été, on a réussi à reprendre qu&#39;en début octobre 2025…</p>
<blockquote>
<p>Ce qu&#39;il faut bien comprendre avec NG Baguette Conf, c&#39;est que nous avons été quatre à travailler sur tout, quatre c&#39;est peu, et organiser un événement comme ça demande beaucoup d&#39;énergie. Nous sommes tous les quatre bénévoles (clairement, si on devait être objectif : NG Baguette Conf nous coûte de l&#39;argent aujourd&#39;hui), nous avons un travail de développeur à temps plein à côté.
On ne le vit pas comme un fardeau, on ne le vit pas négativement, je pense juste que c&#39;est important qu&#39;on soit transparent sur ce genre de choses.</p>
</blockquote>
<h2 id="article-la-sorbonne-sciences">La Sorbonne Sciences<a href="#article-la-sorbonne-sciences" class="anchor" aria-label="permalink">🔗</a></h2>
<p>On a démarché beaucoup de lieux, on a comparé les prix et prestations de beaucoup d&#39;options avant d&#39;en arriver à La Sorbonne Sciences.</p>
<p>On avait quelques contraintes :</p>
<ul>
<li>Un budget relativement contenu : on est une petite conférence, avec un petit budget, on veut garder un billet participant contenu ;</li>
<li>Un amphithéâtre avec au moins 150 places : on partait d&#39;une édition avec une grosse centaine de personnes avec l&#39;optique de gonfler le nombre de participants (on ne veut pas faire une grosse conférence à plusieurs centaines de personnes, mais avoir un peu plus de participant donne de la souplesse sur ce qu&#39;on peut réaliser) ;</li>
<li>Avoir un espace dans lequel se restaurer : proposer un repas à chaque personne présente est très important pour nous, c&#39;est un moment pour faire un clin d&#39;œil au nom de notre conférence (le centre du repas est un sandwich baguette), mais surtout c&#39;est un moment où les participants peuvent échanger, et aussi un moment pendant lequel on peut échanger avec les participants ;</li>
<li>Une pièce à l&#39;écart pour servir de salle speakers ;</li>
<li>Pouvoir circuler relativement facilement entre les trois espaces ;</li>
</ul>
<blockquote>
<p>Dans l&#39;équipe nous sommes tous développeurs, nous sommes tous speakers et nous sommes maintenant tous organisateurs d&#39;une conférence. C&#39;est en cumulant ces 3 casquettes qu&#39;on dessine ce qu&#39;est la conférence.</p>
<p>L&#39;expérience speaker peut vous sembler secondaire, mais pas à nous. Quand on est speaker, on investit énormément de temps personnel (comptez entre 10 et 20h de préparation minimum pour une session de 45-50min), on investit de l&#39;énergie pour proposer un sujet, le préparer, se déplacer jusqu&#39;à la conférence et le jouer. Il y a quelques points qui font que l&#39;expérience qu&#39;on a en tant que speaker est bien meilleure : avoir un contact privilégié avec une personne de l&#39;organisation, avoir un espace où se poser au calme (parfois pour répéter, parfois pour des retouches de dernière minutes, parfois pour travailler pour son employeur), avoir un moment pour rencontrer l&#39;équipe organisatrice et/ou le MC qui va nous introduire.</p>
<p>Si dans l&#39;équipe on tient à l&#39;expérience participant, on tient aussi à l&#39;expérience speaker. C&#39;est cette expérience qui fait que nos speakers reviendront, c&#39;est cette expérience qui fera qu&#39;on aura des très bonnes propositions d&#39;éditions en éditions.</p>
</blockquote>
<p>Je ne citerais pas de lieu en particulier (je ne veux pas donner une quelconque impression de bashing, ce n&#39;est pas le cas), mais les budgets sur Paris sont élevés, on avait souvent des devis entre 10 000 et 15 000€ (voir beaucoup plus) ce qui n&#39;était pas envisageable.</p>
<p>La Sorbonne nous a proposé un budget de 6 700€ tout compris, un amphithéâtre de 221 places, un patio accolé et couvert (on vise mai et la pluie potentielle qui va avec) et une salle de classe un peu à l&#39;écart.</p>
<h2 id="article-avec-ou-sans-viande-">Avec ou sans viande ?<a href="#article-avec-ou-sans-viande-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Le second gros point de recherche, vous vous en doutez surement, c&#39;est la nourriture.</p>
<p>Notre conférence s&#39;appelle &quot;NG <strong>Baguette</strong> Conf&quot;, si avec baguette dans le nom, on ne sert pas de baguette, pour nous, c&#39;est un échec. On vise un menu relativement simple : un sandwich baguette et un dessert (type gâteau boulangerie / pâtisserie). Ce n&#39;est pas grand luxe, c&#39;est très français, c&#39;est à la fois facile et compliqué. C&#39;est facile parce que je pense que chacun chez lui est capable de faire un sandwich qui tient debout sans trop d&#39;effort, c&#39;est compliqué parce qu&#39;il faut arriver à un sandwich qui plaira au plus grand nombre, un sandwich qui laissera un bon souvenir aux participants.</p>
<p>Évidemment, on veut bichonner nos participants, et on veut offrir un petit-déjeuner, on veut aussi offrir du café, du thé, des jus de fruit, ainsi qu&#39;une collation l&#39;après-midi.</p>
<p>Quand on vise entre 150 et 180 personnes à nourrir il faut qu&#39;on trouve un traiteur ou une boulangerie qui respecte ce qu&#39;on souhaite faire, il faut qu&#39;on trouve un prix cohérent. Avec avoir démarché pas mal de boulangerie et traiteur, au vu de la quantité dont on avait besoin, on arrivait généralement entre 4 000 et 6 000 €, en sachant que certains nous proposaient des devis beaucoup plus élevés. (encore une fois, pas de bashing, on comprenait généralement pourquoi c&#39;était plus cher, mais juste ce n&#39;est pas pour nous)</p>
<p>Au final nous avons arrêté notre choix sur le traiteur Votre Instant Gourmand. Pourquoi ? De base, ils ne font pas de sandwich (plutôt habitué aux menus mariages ou des apéros dinatoire) mais ils ont compris notre univers et acceptés de composer quelque chose de sur mesure sans avoir un prix délirant. On a aussi eu des conseils de leur part, des réponses claires, précises et rapide à chacune de nos questions, et pour finir la possibilité de fixer un nombre final de part au plus tard 10 jours avant la date. Ils nous proposaient d&#39;avoir du personnel le jour J pour l&#39;installation et le service, ce qui allait nous rendre beaucoup plus sereins pour tout gérer.</p>
<p>On a validé un budget de 5 400€ pour la nourriture. Notre second plus gros poste de dépense.</p>
<figure>
<img src="https://anthonypena.fr/2026/06/16/organiser-une-conference-ca-veut-dire-quoi/img/IMG_4569.min.jpg" alt="Photo du stand du traiteur avec les sandwichs mis en place pour le déjeuner" is="img-zoom"/>
<figcaption>Photo du stand du traiteur avec les sandwichs mis en place pour le déjeuner</figcaption>
</figure>
<h2 id="article-les-petites-depenses">Les &quot;petites dépenses&quot;<a href="#article-les-petites-depenses" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Si on arrive déjà à plus de 10 000€, il faut aussi se dire qu&#39;on a pas que ça comme dépense. Il y a plein de choses qui nous coûte de l&#39;argent.</p>
<p>Déjà, chaque participant pendant l&#39;événement a un badge (simple carton A6), une étiquette autocollante à son nom et un tour de cou. Ça nous coûte environ 100€, j&#39;imprime les étiquettes à la maison avec mon imprimante thermique et 3-4 rouleaux de papier autocollant, on passe par un imprimeur pour les badges, les tours de cou sont commandés à part avec en tête l&#39;idée de réutiliser ceux des années précédentes (on encourage les participants qui ne souhaitent pas garder les tours de cou à nous les rendre, c&#39;est plus économique et plus écologique ; ceux qui souhaitent le garder le peuvent, si ça doit partir à la poubelle on préfère le récupérer). C&#39;est une dépense à laquelle on en peut pas couper : il faut qu&#39;on soit capable d&#39;identifier les participants, qu&#39;on sache qui a mangé (on coche le badge le midi), qu&#39;on s&#39;assure qu&#39;aucun billet n&#39;est utilisé plusieurs fois.</p>
<p>Nos bénévoles et MC portent chacun une marinière, ainsi qu&#39;un béret rouge, côté organisateur nous avons des t-shirts floqués (avec nos noms et le logo NG Baguette Conf sur le cœur ; ces t-shirts ont été faits en 2025) et un béret rouge. Ça nous a coûté environ 100€ (environ 7.5€ / marinière + environ 3€ / bérets). Ça peut paraitre inutile mais c&#39;est important car ça permet de débloquer très facilement deux points : les personnes responsables de l&#39;événement sont clairement identifiables et ça donne du caractère à l&#39;expérience participant.</p>
<p>Nous offrons à chaque speaker et à chaque MC un petit cadeau pour les remercier d&#39;avoir pris de leur temps pour NG Baguette Conf, sans eux l&#39;événement n&#39;existerait pas et c&#39;est important. Nous organisons aussi une soirée la veille où speakers, MCs, bénévoles et organisateurs sont conviés, c&#39;est un moment convivial qui permet qu&#39;on se connaisse tous un peu mieux, qui permet de rendre les échanges du lendemain beaucoup plus fluide, qui permet aussi simplement de créer du lien (2 des speakers étaient déjà speakers l&#39;an dernier, notre MC de 2025 était speaker cette année, un de nos deux MC était speaker l&#39;année dernière). Tout ça nous coûte un peu moins de 400€.</p>
<p>Notre banque nous coûte de l&#39;argent aussi. Nous sommes une association Loi 1901, pour recevoir de l&#39;argent, nous devons posséder un compte bancaire professionnel. Nous passons par une banque en ligne gratuite pour la tenue de compte mais qui se rémunère en prenant une commission sur chaque virement que l&#39;on reçoit. Pour l&#39;édition 2026, ça nous revient à un peu moins de 180€.</p>
<p>Il y a quelques autres petites dépenses plus anecdotiques.</p>
<h2 id="article-on-paie-ca-comment-">On paie ça comment ?<a href="#article-on-paie-ca-comment-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Si on a pas mal de dépenses, avec un total approchant les 11 000€, nous avons seulement deux sources d&#39;argents : la billetterie et les sponsors.</p>
<p>Pour la billetterie, nous passons par Hello Asso qui nous permet d&#39;avoir une billetterie gratuite, sans commission. Ce n&#39;est pas parfait, mais remplie globalement nos besoins. Le prix des entrées nous permet d&#39;être relativement serein en théorie : </p>
<ul>
<li>30 billets &quot;early&quot; à 69€ : avant l&#39;annonce du programme, à prix plus bas, nous permettant d&#39;avoir de la trésorerie au plus tôt (on ne va pas très loin avec 600€ et autant que possible on essaie d&#39;éviter d&#39;avancer sur nos fonds persos) ;</li>
<li>120 billets &quot;standard&quot; à 99€ : le tarif standard pour financer tout le reste ;</li>
<li>avec une marge de 30 places &quot;late&quot; à 119€ prévues si on épuise tout le reste de la billetterie pour permettre à plus de gens de venir et gérer le fait qu&#39;on sera à un timing très proche de la conférence (ce qui augmente notre effort et nos coûts, car on doit commander plus au dernier moment) ;</li>
</ul>
<blockquote>
<p>À noter qu&#39;on a pas sorti ces prix de notre chapeau. Nous avons regardé le prix des conférences parisiennes (généralistes (comme Devoxx) et spécialisés (React Conf, dotJS, etc.)), et aussi les autres conférences Angular européenne (ngPoland, ngDE, ngRome, etc.). Notre objectif était très clair : être beaucoup moins cher que les autres, rendre la conférence super accessible autant que possible, car on ne fait pas ça pour l&#39;argent ou la gloire, on fait ça pour offrir un moment à la communauté. On ne veut pas être une conférence élitiste, on veut que les gens puissent se poser la question de venir même en fond propre.</p>
</blockquote>
<p>Si on compte de manière brute les billets early et standard, on arrive à presque 14 000€. En résumé : si on remplit presque la salle, vous financez entièrement la conférence.</p>
<p>Mais on sait qu&#39;on est jamais sûr de tout vendre, on sait aussi que viser un peu plus c&#39;est toujours mieux, ça donne de la marge, ça donne de la souplesse, ça donne des options pour faire mieux que ce qu&#39;on voulait faire à la base et améliorer l&#39;expérience de tout le monde. Donc il y a aussi la partie sponsoring.</p>
<p>Côté sponsoring, on a ouvert 2 niveaux :</p>
<ul>
<li>8 &quot;standard&quot; à 500€ : globalement du sponsoring dit &quot;virtuel&quot;, on vous inclut dans toutes nos communications donc votre marque sera promue largement ;</li>
<li>3 &quot;premium&quot; à 1 500€ : même chose que standard mais avec en plus 2 billets participants inclus et un stand sur place pour rencontrer les participants et communiquer directement sur votre activité avec eux ;</li>
</ul>
<blockquote>
<p>Là aussi, on n&#39;y a pas été au doigt mouillé : on sait qu&#39;on est une petite conférence, mais aussi qu&#39;on a un public spécialisé, on a comparé les prix des packs de sponsoring de beaucoup de conférences en France pour se faire un avis sur une sorte de ratio prix par participant et fixer notre tarif et là encore, on sait qu&#39;on est vraiment pas cher. Mais là encore, c&#39;est ce qu&#39;on souhaite, on aimerait avoir des sponsors qui nous suivent au fil des éditions, même si c&#39;est des petites structures.</p>
</blockquote>
<p>Donc un potentiel à 8 500€ supplémentaires si on est optimiste.</p>
<h2 id="article-la-realite">La réalité<a href="#article-la-realite" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Jusque-là je parle de théorie, d&#39;un monde idéal où tout se passe bien.</p>
<p>Nous avons vendu les 30 premiers billets en 2 jours : soit 2 070€ de trésorerie. Ensuite on a attendu le lancement du programme pour ouvrir les billets standards. Et à l&#39;ouverture, ça n&#39;a pas été aussi facile… 🫠 On a vu les billets se vendre au compte goutte au fil des semaines, parfois une semaine complète sans un seul billet vendu… On a même à partir de fin avril diffusé des codes promos (qui ont été très peu utilisés). On a vendu au final 72 billets standards et 13 billets late. La billetterie atterrie a un peu moins de 10 700€ et 115 billets vendus (presque 25% de moins que ce qu&#39;on budgétisait).</p>
<p>Côté sponsoring, nous sommes arrivés trop tard faces aux budgets marketings qui étaient déjà consommés ou affectés à autre chose (du peu qu&#39;on a pu échanger, le marketing a été fortement orienté vers l&#39;IA depuis 2 ans…). Nous avons été soutenus par quatre entreprises : deux en standard et deux en premium. Ce qui nous a amené 4 000€.</p>
<p>Quand on voit le bilan, on se dit que tout va bien (et oui au final, tout va bien), mais ce n&#39;est pas si simple : à 1 mois de l&#39;événement nous n&#39;avions pas atteint notre point d&#39;équilibre (le moment où notre recette paie l&#39;ensemble de l&#39;événement). Nous commencions déjà à évoquer de combler en fond propre et fermer l&#39;association. Le stress était très fort. Nous avons effacé au maximum les dépenses non absolument nécessaires. Nous avons débattu chaque dépense jusqu&#39;au 2 semaines avant l&#39;événement.</p>
<p>Côté lieu, le prix n&#39;est pas compressible. On a beaucoup échangé avec le traiteur pour fixer au plus tard le nombre de part commandé pour éviter à la fois le gaspillage de nourriture et d&#39;argent. On a aussi commandé au plus tard l&#39;impression des badges pour avoir très peu de marge. On a réservé le lieu de la soirée speaker qu&#39;une semaine avant pour être certain d&#39;avoir le budget, avec en tête de l&#39;annuler si on avait pas le budget.</p>
<p>On a vécu une phase compliquée. On est arrivé à la conférence dans l&#39;idée que ce serait la dernière édition.</p>
<p>À noter aussi que plus haut je disais qu&#39;on prévoyait un espace couvert car &quot;on vise mai et la pluie potentielle qui va avec&quot;, cette année on a pas vraiment eu de problème de pluie, on a eu un épisode de chaleur, il faisait 34°C le jour J !</p>
<h2 id="article-hors-budget-mais-pas-hors-sujet">Hors budget mais pas hors sujet<a href="#article-hors-budget-mais-pas-hors-sujet" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Il y a pas mal de choses qui ne rentrent pas du tout dans ce budget, qui est totalement invisible pour la plupart des gens : l&#39;énergie et l&#39;argent personnels qu&#39;on investit en tant qu&#39;organisateur.</p>
<p>Le premier moment où on a investi en perso cette année c&#39;est je pense la visite du lieu. En effet on a une personne de l&#39;équipe qui vit à Paris, mais ce n&#39;est pas toujours simple de faire concorder les emplois du temps : parce qu&#39;il était plus disponible à ce moment-là, Gerome est allé sur Paris pour faire la visite, sans dépenser l&#39;argent de l&#39;association. C&#39;est une journée allongée, des contraintes en plus, de l&#39;argent personnel mis sur la table.</p>
<p>Je peux sans souci aussi ajouter le travail sur le site internet, sur le dossier sponsoring, sur les démarchages / prises de contacts, la communication sur LinkedIn (vous n&#39;imaginez pas le temps que ça prend de faire une bonne communication sur les réseaux sociaux…).</p>
<p>Pour être présent à la conférence, il fallait qu&#39;on soit tous les quatre sur Paris, Camille vit à Paris, elle a juste posé des congés, mais Gérôme, Yann-Thomas et moi avons pris des congés, pris le train / bus pour nous rendre sur Paris dès le jeudi matin, on a pris un hébergement pour 2 nuits. Tout ça sur nos propres deniers.</p>
<p>Un autre exemple qu&#39;on peut mettre en avant c&#39;est la photo et la captation. Yann-Thomas et moi avons du matériel photo personnel d&#39;assez bonne qualité, on utilise donc notre propre matériel pour faire nous-mêmes les photos pendant l&#39;événement. Faire les photos ça veut aussi dire qu&#39;il faut qu&#39;on fasse nous-même aussi la phase de développement : trier les photos, retoucher ce qui doit l&#39;être, mettre en ligne pour vous permettre de garder des souvenirs de ce moment avec des belles photos. Là encore c&#39;est beaucoup de temps investi pour faire ça car sur la journée nous avons pris à nous deux plus de 900 photos.</p>
<p>Nous avons fait le choix dès la première édition d&#39;enregistrer les talks. Pour la première édition, nous avions plus ou moins improvisé une configuration qui ressemblait à la captation de nos live avec Angular Devs France. Cette année on a décidé de se poser un peu plus et de monter un peu en grade sur la configuration : on a capturé avec un PC en régie via <a href="https://obsproject.com/">OBS Studio</a>. Pour capturer l&#39;écran des speakers, j&#39;ai pris ma carte de capture HDMI et mon PC. J&#39;ai aussi pris un peu de câble pour re-router le signale vidéo. Yann-Thomas a réussi à emprunter une carte pour capturer la partie audio. J&#39;ai préparé toute la configuration en amont avec pas mal d&#39;essais (pas assez apparemment vu qu&#39;on a pas pu faire exactement ce qu&#39;on voulait 😅), des retouches dans la nuit précédente la conférence comme on a vu que le rendu n&#39;allait pas vis-à-vis de la luminosité du vidéo-projecteur, un peu de montage d&#39;image pour prévoir tous les layouts et transitions, et après la conférence du montage pour pouvoir avoir un résultat acceptable pour Youtube.</p>
<p>On peut aussi sans souci citer nos bénévoles. De notre côté, il a fallu qu&#39;on contacte nos MCs, qu&#39;on échange avec eux sur le rôle et les détails. Il a aussi fallu qu&#39;on fasse pas mal de démarchage pour trouver nos six bénévoles, qu&#39;on documente les rôles, qu&#39;on définisse les plannings, qu&#39;on s&#39;assure de ne rien oublier, qu&#39;on communique avec eux, qu&#39;on fasse des réunions d&#39;informations. De leur côté aussi c&#39;est un investissement : ils ont dû poser leur journée, ils ont donné de leur énergie pour nous aider à ce que la conférence se passe bien, vraiment ils ont tous été super ! Et pourtant ce n&#39;est pas si simple que ça pour nous de déléguer une partie de la responsabilité de l&#39;événement sur lequel on travaille depuis autant de mois 😅</p>
<p>Tout ça c&#39;est des choses qu&#39;on voit moins, c&#39;est un peu caché et je trouve ça dommage. Beaucoup de participant ne réalise pas tout le travail gratuit qu&#39;on fait sous le manteau.</p>
<figure>
<img src="https://anthonypena.fr/2026/06/16/organiser-une-conference-ca-veut-dire-quoi/img/IMG_4869.min.jpg" alt="Toutes les personnes qui font que NG Baguette Conf 2026 a existé" is="img-zoom"/>
<figcaption>Toutes les personnes qui font que NG Baguette Conf 2026 a existé</figcaption>
</figure>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Si on organise une conférence dont le nom est une blague sur l&#39;image frenchy de la baguette, il s&#39;agit bien de la seule conférence Angular francophone, un projet sérieux, avec des speakers/talks de qualités, une vraie ambition derrière, une équipe passionnée.</p>
<p>On a adoré passer la journée avec vous. On a adoré voir nos speakers sur scène partager avec un amphi plein de gens captivés par le moment ! On a adoré vous voir le sourire aux lèvres toute la journée. On a adoré les échanges qu&#39;on a pu avoir et qu&#39;on a pu voir !</p>
<p>Même si ça a été difficile, le bilan de la conférence est positif d&#39;un peu plus de 2 000€. Et je peux d&#39;or et déjà vous annoncer qu&#39;ils seront utilisés pour une troisième édition d&#39;NG Baguette Conf.</p>
<p>Merci à tous ceux qui auront pris le temps de lire l&#39;article jusqu&#39;au bout. Merci à tous ceux qui ont rendu cette aventure possible !</p>
<p>J&#39;en profite pour citer l&#39;article de <a href="https://codeka.io/2025/11/07/je-suis-orga-dun-%C3%A9v%C3%A9nement-tech/">Julien Wittouck sur l&#39;organisation de Cloud Nord</a> qui m&#39;a donné l&#39;impulsion pour écrire mon propre article. Vraiment merci Julien, pour ton article, mais aussi pour notre échange à la soirée speaker de Devfest Nantes qui m&#39;a pas mal aidé à relativiser plein de chose, et évidemment pour tout le taff que tu fais pour la communauté !</p>
<p>Crédit photo : Anthony PENA &amp; Yann-Thomas Le Moigne pour NG Baguette Conf 2026</p>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Juin 2026]]></title>
      <guid isPermaLink="false">2026/06/02/revue-de-presse-juin</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/06/02/revue-de-presse-juin/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Tue, 02 Jun 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-css-vs-javascript--josh-w-comeauhttpswwwjoshwcomeaucomanimationcssvsjavascript"><a href="https://www.joshwcomeau.com/animation/css-vs-javascript/">CSS vs. JavaScript • Josh W. Comeau</a><a href="#article-css-vs-javascript--josh-w-comeauhttpswwwjoshwcomeaucomanimationcssvsjavascript" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#CSS #Frontend #JavaScript #Performance #UI #Web</p>
<p>Article super intéressant qui explique avec une animation super simple pourquoi on a généralement des animations bien plus fluides avec du CSS que du JavaScript et comment on peut contourner ça. </p>
<p>En résumé, on a généralement quelque chose de plus fluide en CSS, car tout le JS s&#39;exécute dans le main thread et il peut se retrouver bloqué par autre chose donc ça bloque complètement notre animation. Le CSS est exécuté dans son propre thread et n&#39;est donc pas impacté par ça. Mais on peut éventuellement passer par la Web Animations API pour contourner le problème (on va pouvoir se greffer sur le même thread que celui qui gère les animations CSS et ne pas être impacté par la charge du main thread). </p>
<p>Maintenant : il reste important d&#39;utiliser le bon outil pour la bonne tâche, le CSS pour des animations suffit largement la plupart du temps, sera plus stable (aussi bien en termes de comportement que de performance), et on évitera d&#39;augmenter la taille du bundle inutilement. Par contre utiliser du JavaScript quand vous avez des cas complexes de gestion de physique ou autres là ça se défend. </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-mythos-finds-a-curl-vulnerability--danielhaxxsehttpsdanielhaxxseblog20260511mythosfindsacurlvulnerability"><a href="https://daniel.haxx.se/blog/2026/05/11/mythos-finds-a-curl-vulnerability/">Mythos finds a curl vulnerability | daniel.haxx.se</a><a href="#article-mythos-finds-a-curl-vulnerability--danielhaxxsehttpsdanielhaxxseblog20260511mythosfindsacurlvulnerability" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #CVE #Claude #IA #curl</p>
<p>Le lead de curl (sûrement une des briques logiciels les plus utilisés au monde et à peu près partout autour de nous) explique comment fonctionne l&#39;analyse de sécurité dans curl et surtout le retour qu&#39;ils ont eu d&#39;un audit réalisé par Claude Mythos : 1 CVE Low trouvée. </p>
<p>Conclusion : l&#39;outil est puissant mais pas si dangereux que ce que certains essais de dire. Si vous n&#39;avez aucune expertise et/ou aucun audit sécurité, clairement vous allez voir remonter des bugs en quantité monstrueuse (et galérer à analyser les rapports), si vous avez déjà une bonne stratégie sécurité, vous aurez juste un outil de plus </p>
<h3 id="article-im-tired-of-talking-to-aihttpsorchidfilescomimtiredofaigeneratedanswers"><a href="https://orchidfiles.com/im-tired-of-ai-generated-answers/">I’m tired of talking to AI</a><a href="#article-im-tired-of-talking-to-aihttpsorchidfilescomimtiredofaigeneratedanswers" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #LLM</p>
<p>L&#39;auteur pointe quelques cas de son quotidien où il tente de discuter avec des humains mais se retrouve soit face à des gens qui donnent des réponses venant d&#39;un LLM soit directement à un agent IA… </p>
<p>Le futur est là ! Ça ne fait pas plaisir du tout de se dire que ça va devenir de plus en plus courant… </p>
<h3 id="article-the-social-contract-of-writing--joladevhttpsjoladevpoststhesocialcontractofwriting"><a href="https://jola.dev/posts/the-social-contract-of-writing">The social contract of writing | jola.dev</a><a href="#article-the-social-contract-of-writing--joladevhttpsjoladevpoststhesocialcontractofwriting" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #LLM #Blog #Blogging #Société</p>
<p>Deux passages résume très bien l&#39;article (même si je vous encourage à le lire entier) :</p>
<blockquote>
<p>Anything written after November 30, 2022 is to some degree affected by the proliferation of LLMs. You can’t get around that, other than by exclusively reading old content.</p>
</blockquote>
<blockquote>
<p>You took the time to read my writing, I appreciate that. I fulfilled my half of the contract too, I spent much of a day writing this, while watching old movies on the TV. I enjoy writing and I’ve been doing it all my life, although with varying levels of consistency. I’m going to try to make this more of a routine thing now. It feels meaningful. Worth doing.</p>
</blockquote>
<p>Je suis 100% d&#39;accord avec l&#39;article : écrire c&#39;est établir un contrat social qui implique qu&#39;on a fait l&#39;effort de structurer sa pensée et pour les gens qui feront l&#39;effort de le lire. Je fais partie des gens qui lisent beaucoup, y compris pour faire de la veille, j&#39;aime ça mais ça me coûte de l&#39;énergie que je pourrais investir ailleurs (tout coûte de l&#39;énergie à part manger (si vous mangez correctement) et dormir). Si je lis du contenu produit par un LLM ça veut dire que la personne a investi moins d&#39;effort à l&#39;écrire que moi à le lire…</p>
<p>Par contre je suis malheureusement d&#39;accord aussi que quoi qu&#39;on en pense, les LLMs ont changés notre manière d&#39;écrire (vocabulaire, tournure de phrase, etc.) et ça on peut difficilement y couper tant c&#39;est implicite (vous ne choisissez pas d&#39;utiliser du vocabulaire que les LLMs utilisent, vous vous êtes imbibée de ce vocabulaire et c&#39;est devenu le vôtre). On peut limiter ça, pas l&#39;annuler complètement. </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-hash-md5--60-des-mots-de-passe-craques-en-moins-dune-heure--korbenhttpskorbeninfohashmd5crackableuneheurehtml"><a href="https://korben.info/hash-md5-crackable-une-heure.html">Hash MD5 - 60% des mots de passe craqués en moins d&#39;une heure - Korben</a><a href="#article-hash-md5--60-des-mots-de-passe-craques-en-moins-dune-heure--korbenhttpskorbeninfohashmd5crackableuneheurehtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité</p>
<p>Kaspersky annonce que &quot;60% des mots de passe hashés en MD5 peuvent être cassés en moins d&#39;une heure…&quot; donc clairement si vous avez encore du MD5 qui traîne, il faut passer à autre chose… </p>
<p>Ils annoncent aussi &quot;L&#39;étude souligne aussi que 53% des mots de passe du corpus se terminent par des chiffres.&quot;. En quoi c&#39;est important ? Les hacks de mots de passes vont tenter en priorité des bruteforces avec des chiffres en fin de mot de passe, donc si vous avez un chiffre en fin de mot de passe vous êtes encore plus sensible… </p>
<h2 id="article-jeuxvideos">Jeux-videos<a href="#article-jeuxvideos" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-vaskange-worldhttpswwwvaskangeworld"><a href="https://www.vaskange.world/">Vaskange World</a><a href="#article-vaskange-worldhttpswwwvaskangeworld" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Jeux-videos #Navigateur #Web</p>
<p>C&#39;est vraiment trop trop bien !! </p>
<p>Un jeu entièrement dans le navigateur où vous devez explorer le monde en faisant des zooms / dézooms / scroll. C&#39;est beau, ça marche bien, c&#39;est simple à prendre en main ! 🤩 </p>
<h3 id="article-while-it-is-true-that-iwata-did-write-a-new-compression-algorithm-for-goldsilver-it-did-not-save-any-space-in-fact-it-actually-cost-space-the-reason-for-the-new-compression-algorithm-was-to-increase-the-speed-of-decompressionhttpswwwredditcomrtruepokemoncommentshwluk9while_it_is_true_that_iwata_did_write_a_new"><a href="https://www.reddit.com/r/TruePokemon/comments/hwluk9/while_it_is_true_that_iwata_did_write_a_new/">While it is true that Iwata did write a new compression algorithm for Gold/Silver, it did not save any space. In fact, it actually cost space. The reason for the new compression algorithm was to increase the speed of decompression.</a><a href="#article-while-it-is-true-that-iwata-did-write-a-new-compression-algorithm-for-goldsilver-it-did-not-save-any-space-in-fact-it-actually-cost-space-the-reason-for-the-new-compression-algorithm-was-to-increase-the-speed-of-decompressionhttpswwwredditcomrtruepokemoncommentshwluk9while_it_is_true_that_iwata_did_write_a_new" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Compression #Optimisation #Jeux-videos #Pokemon</p>
<p>Post super intéressant sur la compression utilisée entre Pokemon Gen 1 (Bleu / Rouge) et Gen 2 (Or / Argent). En effet il y a eu un changement de compression entre les deux générations, et on dit toujours que c&#39;est la nouvelle compression de la Gen 2 a permis d&#39;ajouter la région de Kanto (Gen 1) dans la cartouche de la Gen 2 car ça permettait de gagner de la place, alors qu&#39;en fait non.</p>
<p>L&#39;auteur du post explique qu&#39;en fait on perd de la place (4-5% d&#39;espace consommé en plus pour l&#39;algo utilisé en Gen 2 vs celui utilisé en Gen 1), mais que ce choix est justifié par une meilleure vitesse de décompression (à animation égale, on passerait d&#39;environ 100 frames à environ 40 frames pour le chargement).</p>
<p>On a tendance à oublier qu&#39;il y a beaucoup d&#39;algo de compression / archivage, et que tous n&#39;ont pas le même objectif, tous ne font pas les mêmes compromis, et c&#39;est ça qui permet de répondre à tous les cas d&#39;usages !</p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-jai-ete-augmente-voila-le-planhttpssiegfried202603augmentationrefrss"><a href="https://sieg.fr/ied/2026/03/augmentation/?ref%3Drss">J&#39;ai été augmenté, voilà le plan.</a><a href="#article-jai-ete-augmente-voila-le-planhttpssiegfried202603augmentationrefrss" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Métier-de-dev #Dev #Carrière</p>
<p>Je pointe cet article de Siegfried, mais il faut aussi aller lire le précédent (qui est en lien au tout début de l&#39;article) sur son augmentation mais surtout son rapport à sa position dans son organisation, son implication, son évolution et son rôle.</p>
<p>Ça me fait forcément pas mal réfléchir en ce moment (ceux qui travaillent avec moi se doute du pourquoi, pour les autres j&#39;en parlerai au début de l&#39;été). En tout cas c&#39;est intéressant.</p>
<p>Je cite aussi <a href="https://piaille.fr/@bodul/116135621865577312">Ludovic Borie</a> (qui a répondu au premier billet de Siegfried) :</p>
<blockquote>
<p>Il est marrant ton article sur l’augmentation salariale. En tant que manager je trouve ça rude, surtout quand on parle en pourcentage. Ton 4% est un 15 / 20% d’un SMIC. Donc la somme ne me choque pas.
Par contre, on est toujours dans l’équilibre employeur employé, sur 4 éléments : </p>
<ol>
<li>En tant qu’employé, je rends ce service et j’ai envie de faire « ça »</li>
<li>En tant qu’employeur, j’ai besoin de ces compétences</li>
<li>En tant qu’employé, je souhaite ce salaire pour ça</li>
<li>En tant qu’employeur, je suis prêt à payer ça.
A partir du moment où l’équilibre 1/2 ou 3/4 est cassé, il y a frustration. C’est l’équilibre à régler,pas la somme</li>
</ol>
</blockquote>
<p>Puis <a href="https://piaille.fr/@bodul/116135651870138903">ici</a> :</p>
<blockquote>
<p>Tout ça pour dire, je t’encourage plutôt à réfléchir en termes de parcours et de destination (aka je veux atteindre ça), plutôt que de pourcentage. Etre clair avec eux sur la destination et voir si c’est complètement en déphasage avec ce qu’ils pensent ou sont prêts à mettre eux. Et si jamais ils trouvent pas ça déconnant, voir les étapes et le temps que ça prendra pour faire descendre la frustration.</p>
</blockquote>
<h3 id="article-omarchy-is-not-a-distrohttpsabyssfishyour_dotfiles_are_not_a_distro"><a href="https://abyss.fish/your_dotfiles_are_not_a_distro">omarchy is not a distro</a><a href="#article-omarchy-is-not-a-distrohttpsabyssfishyour_dotfiles_are_not_a_distro" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#ArchLinux #Linux #OS</p>
<p>L&#39;auteur pose des mots sur l&#39;effet que me fait Omarchy mais que j&#39;arrivais pas exprimer (en me disant que sans avoir testé je voulais pas exprimer un avis tranché) : Omarchy c&#39;est beau, ça a l&#39;air efficace, tout ce que vous voulez mais c&#39;est Archlinux (ça pour le coup je maîtrise plutôt bien comme je l&#39;utilise depuis 2009-2010) et les dotfiles de DHH 🤷‍♂️ </p>
<p>J&#39;ai rien de personnel contre DHH, mais Omarchy n&#39;est pas une distribution, même pas dérivé de Archlinux : c&#39;est Archlinux. Par contre presque tout dans Omarchy se base sur AUR (Arch User Repository, donc des paquets communautaires pas des vrais paquets officiels), y&#39;a des configs très personnels (genre des raccourcis claviers pour lancer hey.com (la boîte de mail de DHH), un pour lancer Grok, un pour créer un post sur Twitter (oui sur le desktop)) et des scripts surcouche à Archlinux </p>
<p>Au pire : c&#39;est un environnement de bureau (allez, si on plisse les yeux on pourrait y croire, mais oui c&#39;est Hyprland en vrai qui fait quasi tout le boulot là encore). </p>
<p>Bref : j&#39;avais pas envie de tester, encore moins envie 🤷‍♂️ </p>
<h3 id="article-oui-facebook-et-instagram-peuvent-lire-vos-conversations-whatsapp-en-clair-sur-iphone-sans-vous-avertirhttpswwwclubiccomactualite614092ouifacebooketinstagrampeuventlirevosconversationswhatsappenclairsuriphonesansvousavertirhtml"><a href="https://www.clubic.com/actualite-614092-oui-facebook-et-instagram-peuvent-lire-vos-conversations-whatsapp-en-clair-sur-iphone-sans-vous-avertir.html">Oui, Facebook et Instagram peuvent lire vos conversations WhatsApp en clair sur iPhone sans vous avertir</a><a href="#article-oui-facebook-et-instagram-peuvent-lire-vos-conversations-whatsapp-en-clair-sur-iphone-sans-vous-avertirhttpswwwclubiccomactualite614092ouifacebooketinstagrampeuventlirevosconversationswhatsappenclairsuriphonesansvousavertirhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Meta #Whatsapp #Vie-privée #Apple #iOS #macOS #iPhone #Instagram #Facebook</p>
<p>Je cite :</p>
<blockquote>
<p>Les chercheurs de Mysk ont identifié que WhatsApp enregistre l&#39;historique des conversations dans un fichier nommé &quot;Axolotl.sqlite&quot;. Ce dernier est placé dans un conteneur partagé entre les applications d&#39;un même développeur, désigné sous l&#39;identifiant &quot;group.net.whatsapp.WhatsApp.shared&quot;. Il s&#39;agit en fait d&#39;une fonctionnalité native d&#39;iOS et de macOS. Apple autorise en effet les applications d&#39;un même éditeur à partager un espace de stockage commun, lequel est conçu pour faciliter les échanges de données entre elles. </p>
</blockquote>
<p>Je serais pas du tout surpris qu&#39;on découvre des choses similaires sur Android et Windows. </p>
<p>Meta s&#39;en fichent de votre vie privée, ce qu&#39;ils veulent c&#39;est vos données. Ok pour vous donner l&#39;impression de chiffrer en chiffrant pour le transfert mais rien de plus 🤷‍♂️ </p>
<h3 id="article-le-cookie-est-mort-alors-ils-ont-cuisines-une-nouvelle-merde-pour-vous-traquer--ced_haurushttpsfixupxcomistatus2059589570652479789"><a href="https://fixupx.com/i/status/2059589570652479789">Le cookie est mort alors ils ont cuisinés une nouvelle merde pour vous traquer — @Ced_haurus</a><a href="#article-le-cookie-est-mort-alors-ils-ont-cuisines-une-nouvelle-merde-pour-vous-traquer--ced_haurushttpsfixupxcomistatus2059589570652479789" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Vie-privée #Opérateur-Télécom #Télécoms #Orange #Internet #Cookie</p>
<p>Je cite le tweet complet pour être sûr que tout le monde puisse le lire :</p>
<blockquote>
<p>Le cookie est mort alors ils ont cuisinés une nouvelle merde pour vous traquer 👉 </p>
<p>Utiq, c&#39;est un système de tracking qui n&#39;a pas besoin de cookie. Il utilise votre opérateur télécom.</p>
<p>Le site que vous visitez transmet votre IP à Utiq. Utiq la transmet à Orange, SFR ou Bouygues. Votre opérateur crée un identifiant lié à votre numéro de téléphone. Et cet identifiant vous suit sur tous les sites partenaires.</p>
<p>Vider votre cache ne change rien. La navigation privée non plus. C&#39;est cross-plateforme. Votre IP = votre identifiant publicitaire. Formidable.</p>
<p>Derrière Utiq, on trouve Deutsche Telekom, Orange, Telefónica et Vodafone. Les opérateurs qui transportent vos données depuis 20 ans viennent de décider qu&#39;ils allaient aussi les monétiser.</p>
<p>C&#39;est présenté comme une alternative &quot;éthique et européenne&quot; aux GAFAM. 😂</p>
<p>Vous échangez Google contre votre opérateur télécom. Qui connaît votre numéro de téléphone, votre adresse, et tout votre trafic réseau.</p>
<p>Cliquez sur Rejeter.</p>
</blockquote>
<p>J&#39;ai évidemment été jeter un coup d&#39;œil à Utiq et en effet c&#39;est bien la daube infâme pour la vie privée qui est décrite… </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-têtes calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[`human.json` ou comment créer un réseau de contenu certifié humain !]]></title>
      <guid isPermaLink="false">2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain</guid>
      <description><![CDATA[<p>J&#39;ai évoqué ce protocole dans ma dernière revue de presse et j&#39;ai pris le temps de mettre ça en plac…</p>
]]></description>
      <link>https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/index.html</link>
      <category><![CDATA[Internet]]></category>
      <category><![CDATA[Blog]]></category>
      <pubDate>Tue, 12 May 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>J&#39;ai évoqué ce protocole dans ma dernière <a href="/2026/04/08/revue-de-presse-avril/">revue de presse</a> et j&#39;ai pris le temps de mettre ça en place sur mon blog ! </p>
<h2 id="article-humanjson--kezako-"><code>human.json</code> ? Kézako ?<a href="#article-humanjson--kezako-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>À l&#39;heure de l&#39;IA c&#39;est parfois difficile de dire si on peut croire ou pas le contenu qu&#39;on lit en ligne. L&#39;idée de ce protocole est donc d&#39;identifier, via un graphe de confiance, quel site est rédigé par un humain ou non. On peut rédiger un contenu parfaitement vrai avec de l&#39;IA, on peut aussi s&#39;aider de l&#39;IA pour rédiger proprement du contenu, mais on sait aussi que beaucoup de contenu en ligne venant de l&#39;IA sont à peine relus / vérifié, qu&#39;on retrouve énormément de désinformation venant de l&#39;IA (directement dû à de l&#39;hallucination de LLM ou parce que les utilisateurs ont orientés le LLM pour qu&#39;il dise des trucs faux).</p>
<p>La proposition est plutôt simple : </p>
<ul>
<li>quand on est utilisateur, on installe une extension pour <a href="https://addons.mozilla.org/fr/firefox/addon/human-json-verifier/">Firefox</a> ou <a href="https://chromewebstore.google.com/detail/humanjson-verifier/haemonkhjllbfbilegdanbcdaednphko">Chrome</a>, puis on va se rendre sur un site qu&#39;on sait implémenter le protocole, puis on va l&#39;indiquer comme &quot;trusted&quot;, pour indiquer à l&#39;extension qu&#39;on a confiance, que ce site est fait par un humain et donc s&#39;il indique que d&#39;autres sites sont fiables on peut faire confiance ;</li>
<li>quand on est créateur de contenu en ligne, on peut ajouter une ligne dans son code HTML et un fichier <code>human.json</code> pour indiquer quels autres sites sont fiables ;</li>
</ul>
<p>Ensuite on peut vivre sa vie normalement en regardant ce que nous dit l&#39;extension.</p>
<h2 id="article-cote-extensions">Côté extensions<a href="#article-cote-extensions" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Une fois installé (et épinglé à la barre d&#39;outil), on verra une petite bulle de couleur apparaitre :</p>
<figure>
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/not-yet-trusted.png" alt="Exemple de l&#39;extension sur mon site avant de l&#39;avoir indiqué comme &quot;Trusted&quot;" is="img-zoom"/>
<figcaption>Exemple de l&#39;extension sur mon site avant de l&#39;avoir indiqué comme &quot;Trusted&quot;</figcaption>
</figure>
<p>La bulle peut avoir plusieurs couleurs, je cite directement la documentation (et la page de l&#39;extension qui reprend la même chose) :</p>
<blockquote>
<p>The color will vary depending on how many hops are needed to reach them from someone you trust: green for 0-1 hops (you trust them or someone who vouches for them), yellow for 2 hops, orange for 3+ hops.</p>
<ul>
<li>🟢 Green — 0–1 hops (seed site, or directly vouched by a seed)</li>
<li>🟡 Yellow — 2 hops</li>
<li>🟠 Orange — 3+ hops</li>
<li>⚪ Gray — not in your trust graph</li>
<li>🔵 Blue (+) — site has human.json but you haven&#39;t trusted it yet</li>
</ul>
</blockquote>
<p>Il manque la bulle grise qui indique qu&#39;il n&#39;y a aucun <code>human.json</code> d&#39;indiquer et donc l&#39;extension ne peut pas donner d&#39;information.</p>
<p>J&#39;ai ensuite &quot;Trusted&quot; mon propre site et on voit que je peux maintenant retirer ma confiance :</p>
<figure>
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/trusted.png" alt="Vue de l&#39;extension une fois qu&#39;on a &quot;trusted&quot; un site" is="img-zoom"/>
<figcaption>Vue de l&#39;extension une fois qu&#39;on a &quot;trusted&quot; un site</figcaption>
</figure>
<p>En ajoutant quelques liens (dont le créateur du protocole <code>human.json</code> Beto Dealmeida avec le domaine <a href="https://robida.net/">https://robida.net/</a>) et en laissant un peu de temps à l&#39;extension pour sauter de site en site pour trouver de <code>human.json</code>, je trouve d&#39;autres sites dans l&#39;onglet &quot;Manage&quot; :</p>
<figure>
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/manage-tab.png" alt="Vue de l&#39;onglet &quot;Manage&quot; avec des sites indiqués comme &quot;2 hops&quot;" is="img-zoom"/>
<figcaption>Vue de l&#39;onglet &quot;Manage&quot; avec des sites indiqués comme &quot;2 hops&quot;</figcaption>
</figure>
<p>On voit dans cette liste les sites qui ont été &quot;trusted&quot; par <a href="https://robida.net">https://robida.net</a> et un site &quot;trusted&quot; par <a href="https://blog.genma.fr">https://blog.genma.fr</a> (à qui j&#39;ai parlé de ce protocole il y a quelques jours quand je l&#39;ai rencontré pour la première fois à Devoxx France après plus de 10 ans à suivre son blog !).</p>
<p>Si je vais sur le site de l&#39;ami <a href="https://sieg.fr">Siegfried</a>, je vais voir ça :</p>
<figure>
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/sieg-fr-trusted.png" alt="Site https://sieg.fr qui est &quot;trusted&quot; par mon propre site" is="img-zoom"/>
<figcaption>Site <a href="https://sieg.fr">https://sieg.fr</a> qui est &quot;trusted&quot; par mon propre site</figcaption>
</figure>
<p>Si je vais sur le site de <a href="https://blog.genma.fr">Genma</a>, je vois que lui-même fait confiance au site <a href="https://www.opensource-experts.com/">https://www.opensource-experts.com/</a> et en me rendant sur <a href="https://www.opensource-experts.com/">https://www.opensource-experts.com/</a> je vois que là la bulle est jaune, car on est à 2 sauts d&#39;une seed (site directement &quot;trusted&quot;) : </p>
<figure id="image-gallery-site-httpsbloggenmafr-qui-luimeme-trusted-httpswwwopensourceexpertscom" class="marked-image-gallery" is="gallery-zoom">
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/genma-trusted.png" alt="Site https://blog.genma.fr qui lui-même &quot;trusted&quot; https://www.opensource-experts.com"/>
<img src="https://anthonypena.fr/2026/05/12/humanjson-ou-comment-creer-un-reseau-de-contenu-certifie-humain/img/open-source-expert-2hop-trusted.png" alt="Site https://blog.genma.fr qui lui-même &quot;trusted&quot; https://www.opensource-experts.com"/>
<figcaption>Site <a href="https://blog.genma.fr">https://blog.genma.fr</a> qui lui-même &quot;trusted&quot; <a href="https://www.opensource-experts.com">https://www.opensource-experts.com</a></figcaption>
</figure>
<h2 id="article-cote-site">Côté site<a href="#article-cote-site" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Pour mettre en place le protocole sur son site c&#39;est très facile.</p>
<p>La première étape c&#39;est créé un fichier json (la documentation indique de créer un fichier ̀<code>human.json</code> mais en réalité, on le nomme comme on veut) qui va ressembler à ça :</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;version&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;0.1.1&quot;</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://anthonypena.fr&quot;</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;vouches&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
        <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://genma.fr&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-04-24&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
        <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://press.k49.fr.nf&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-04-24&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
        <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://robida.net&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-04-28&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
        <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://sieg.fr&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-04-24&quot;</span> <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>La clé <code>version</code> indique la version du protocole qu&#39;on supporte (le système est encore très jeune comme je disais, donc on est encore en phase d&#39;essai), pour permettre à la web extension (ou un autre crawler) de savoir à quoi s&#39;attendre comme contenu, en particulier s&#39;il y a des breaking changes.</p>
<p>La clé <code>url</code> le site sur lequel on va déposer le fichier, pour indiquer que notre site est géré par un humain. Ça peut sembler étonnant mais pas tant que ça : imaginons qu&#39;il n&#39;y ait pas cette clé, et qu&#39;on découvre un <code>human.json</code> sur un site &quot;<a href="https://blog-plateform.com/blog-of-john/">https://blog-plateform.com/blog-of-john/</a>&quot;, quel ensemble de page doit être &quot;trusted&quot; ? &quot;<a href="https://blog-plateform.com/blog-of-john/">https://blog-plateform.com/blog-of-john/</a>&quot; ça parait logique mais est-ce qu&#39;on peut croire &quot;<a href="https://blog-plateform.com/">https://blog-plateform.com/</a>&quot; ? Pas forcément. À l&#39;inverse sur mon propre blog, peu importe la page, je veux indiquer que tout &quot;<a href="https://anthonypena.fr">https://anthonypena.fr</a>&quot; est géré par un humain.</p>
<p>Ensuite on va retrouver une clé <code>vouches</code> (qui est optionnelle, vous n&#39;êtes donc pas obligé d&#39;indiquer des marques de confiance) qui va contenir des marques de confiance. Dans mon exemple, une ligne est une marque de confiance. Pour chaque marque on va indiquer à quelle date on a indiqué notre confiance (j&#39;imagine pour donner un indice de confiance pour un éventuel domaine qui aurait changé de propriétaire ou de site qui aurait changé de fonctionnement).</p>
<p>Ensuite on va indiquer sur nos pages que notre <code>human.json</code> existe et sur quelle URL y accéder :</p>
<pre><code class="hljs language-HTML"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;fr&quot;</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    ...
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;human-json&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;/human.json&quot;</span> /&gt;</span>
    ...
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  ...
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><div aria-hidden="true" class="language-tag">HTML</div>
</code></pre><p>Note: il faut que ce fichier soit accessible avec les headers <code>Content-Type: application/json</code> (pour que les crawlers puissent s&#39;assurer qu&#39;ils reçoivent bien un JSON) et <code>Access-Control-Allow-Origin: *</code> (pour ne pas avoir d&#39;erreur de CORS).</p>
<p>Ensuite il suffit d&#39;alimenter le fichier <code>human.json</code> en fonction des gens qu&#39;on connait !</p>
<h2 id="article-critique-du-modele">Critique du modèle<a href="#article-critique-du-modele" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je trouve le modèle plutôt intéressant, mais il n&#39;est pas sans questionnement à date :</p>
<ul>
<li>le niveau de saut est un peu sévère : on considère comme moins de confiance un site qui est à 2 sauts, personnellement j&#39;aurais commencé à réduire la confiance au 3ème saut, dans mon exemple, je fais confiance à Genma, donc je peux aussi lui faire confiance pour avoir choisi uniquement des sites de confiance à mon avis ;</li>
<li>l&#39;extension est pour l&#39;instant uniquement en anglais (même si j&#39;ai ouvert la <a href="https://codeberg.org/robida/human.json/issues/56">discussion pour une traduction française</a>) ;</li>
<li>ça ne fonctionne pas sur les domaines en localhost, ce n&#39;est pas super grave, mais c&#39;est dommage de devoir attendre d&#39;avoir mis en ligne pour tester alors que le site fonctionne en local ;</li>
<li>il n&#39;y a pas de seed initiale : je comprends pourquoi (c&#39;est un système de confiance, mais on ne peut pas facilement faire confiance à un site parce que l&#39;extension indique qu&#39;on peut le faire par défaut), mais pour moi ça peut être un frein à l&#39;adoption ;</li>
<li>le protocole est encore très jeune, donc le réseau de confiance est encore tout petit, mais il faut commencer quelque part donc on verra dans le futur si ça se diffuse ou pas ;</li>
</ul>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Quand bien même le protocole est jeune et génère des questionnements sur le dépôt Codeberg, je pense que c&#39;est une très bonne initiative et j&#39;espère que le graphe de confiance va grossir !</p>
<p>Je vous encourage à mettre en place votre <code>human.json</code> si vous avez votre propre site ! Si on se connait et que vous n&#39;êtes pas dans ma liste, n&#39;hésitez pas à me contacter, c&#39;est que je ne dois pas être abonné à votre flux RSS !</p>
<p>Sources :</p>
<ul>
<li><a href="https://codeberg.org/robida/human.json">Dépôt Codeberg human.json</a></li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/human-json-verifier/">Extension Firefox</a></li>
<li><a href="https://chromewebstore.google.com/detail/humanjson-verifier/haemonkhjllbfbilegdanbcdaednphko">Extension Chrome</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A warm and poetic scene inspired by Studio Ghibli, featuring an ancient parchment map spread on a light wooden table. The map shows a cluster of floating islands (each representing a website) connected by glowing bridges of different colors: green bridges (0-1 trust hops) made of carved wood with maple leaf patterns, yellow bridges (2 hops) made of golden braided ropes, and orange bridges (3+ hops) made of thin, translucent glowing threads. </p>
<p>A wooden sailboat with a maple leaf-patterned sail floats on a blue river with golden reflections, symbolizing a data stream. A phoenix with golden and red feathers, wearing round glasses, stands at the helm, holding an ancient compass whose needle points toward a central island (the seed/trusted site). </p>
<p>On this central island, a red panda (anthropomorphic, wearing a light blue t-shirt and jeans, with curly hair tied in a low bun, a short dense beard, and black-framed glasses) sits on a rock, observing the map with a steaming cup of tea beside him. Around the panda, 8-10 red, orange, and yellow maple leaves float gently in the air. </p>
<p>In the background, a starry sky with stars subtly forming HTML tag symbols or binary code patterns. The table is surrounded by ancient books (leather-bound, with unreadable titles) and a holographic screen (with a carved wooden frame) displaying an interactive map of the islands, with faint animated lines of code. </p>
<p>An axolotl (anthropomorphic, wearing a loose sweater) on a nearby island is fishing with a bamboo fishing rod. A stylized cat (anthropomorphic, in loose clothing) sits on a bridge, reading a futuristic journal (a mix of paper and touchscreen). </p>
<p>The scene is bathed in a soft, warm golden light (like a cozy autumn afternoon), with reflections on the wood and parchment. The dominant colors are beiges, pale blues, warm oranges, golds, and touches of moss green. The bridges emit a soft, pulsing glow, as if alive. The panda’s tea cup releases steam that briefly forms binary code patterns before dissolving into the air. </p>
<p>The red panda is positioned in the bottom right corner, occupying about 1/3 of the height, slightly turned in a 3/4 back view. The map and boat are centered, with a depth of field guiding the eye toward the central island. The maple leaves are scattered around the panda, some resting on the table, others floating near him. </p>
<p>The art style is soft, with detailed textures: grained wood, slightly worn fabric, natural folds in the parchment, and frothy reflections in the river water. The overall atmosphere is peaceful, immersive, and dreamlike, blending technology and nature harmoniously.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Mai 2026]]></title>
      <guid isPermaLink="false">2026/05/05/revue-de-presse-mai</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/05/05/revue-de-presse-mai/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Tue, 05 May 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h2 id="article-ng-baguette-conf-2026httpswwwhelloassocomassociationsangularnexusevenementsngbaguetteconf2026"><a href="https://www.helloasso.com/associations/angular-nexus/evenements/ng-baguette-conf-2026">NG Baguette Conf 2026</a><a href="#article-ng-baguette-conf-2026httpswwwhelloassocomassociationsangularnexusevenementsngbaguetteconf2026" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je continue (avec toute l&#39;équipe) à travailler sur <a href="https://ngbaguette.angulardevs.fr/fr/">NG Baguette Conf 2026</a> et je profite de cette revue de presse pour vous dire qu&#39;on a lancé un code promo pour le dernier mois, avec le code &quot;LASTMONTH&quot; vous aurez -15% sur votre billet.</p>
<p>Au passage j&#39;ai travaillé sur le badge que les participants, et je l&#39;ai fait via du HTML/CSS avec les éléments de print qui sont prévues dans HTML/CSS, et comme j&#39;hésite depuis bien 2 ans à faire un article sur le sujet, j&#39;évoque le truc et si certains me font savoir que ça les intéresse j&#39;en parlerai !</p>
<h3 id="article-featcore-introduce-service-decorator-by-crisbeto--pull-request-68195--angularangular--githubhttpsgithubcomangularangularpull68195"><a href="https://github.com/angular/angular/pull/68195">feat(core): introduce @Service decorator by crisbeto · Pull Request #68195 · angular/angular · GitHub</a><a href="#article-featcore-introduce-service-decorator-by-crisbeto--pull-request-68195--angularangular--githubhttpsgithubcomangularangularpull68195" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Angular #Frontend #TypeScript</p>
<p>Je cite directement le contenu de la description de la pull request :</p>
<blockquote>
<p>These changes introduce the new @Service decorator which is a more ergonomic alternative to @Injectable. The reason we&#39;re adding a new decorator is that @Injectable has been around since the beginning of Angular and it has a lot of baggage that adds unnecessary overhead for users that generally want to define a singleton service, available in their entire app. The key differences between @Service and @Injectable are:</p>
<ol>
<li>@Service is providedIn: &#39;root&#39; by default. You can opt into providing the service yourself by setting autoProvided: false on it.</li>
<li>@Service doesn&#39;t allow constructor-based injection, only the inject function.</li>
<li>@Service doesn&#39;t support the complex type signature of @Injectable (useClass, useValue etc.). Instead it supports a single factory function.</li>
</ol>
<p>Example:</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-keyword">import</span> {<span class="hljs-title class_">Service</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/core&#x27;</span>;
<span class="hljs-keyword">import</span> {<span class="hljs-title class_">HttpClient</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/common/http&#x27;</span>;
<span class="hljs-keyword">import</span> {<span class="hljs-title class_">AuthService</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./auth&#x27;</span>;

<span class="hljs-meta">@Service</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PostService</span> {
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> httpClient = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">HttpClient</span>);
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> authService = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">AuthService</span>);

 <span class="hljs-title function_">getUserPosts</span>(<span class="hljs-params"></span>) {
   <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">httpClient</span>.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;/api/posts/&#x27;</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">authService</span>.<span class="hljs-property">userId</span>);
 }
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre></blockquote>
<p>Simplification qui ne va pas changer fondamentalement Angular mais va rendre plus explicite et plus clair pour les nouveaux développeurs Angular tout en donnant plus d&#39;intention. Personnellement j&#39;aime beaucoup ce changement. </p>
<p>En plus ça va obliger les collègues à utiliser <code>inject()</code> 😂 </p>
<h3 id="article-features-everyone-should-steal-from-npmx--andrew-nesbitthttpsnesbittio20260416featureseveryoneshouldstealfromnpmxhtml"><a href="https://nesbitt.io/2026/04/16/features-everyone-should-steal-from-npmx.html">Features everyone should steal from npmx | Andrew Nesbitt</a><a href="#article-features-everyone-should-steal-from-npmx--andrew-nesbitthttpsnesbittio20260416featureseveryoneshouldstealfromnpmxhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#NPM #Frontend</p>
<p>L&#39;article évoque la stratégie de npmx.dev pour combler les manques de npmjs.com : refaire un frontend qui ne casse aucune URL (sauf le domaine) pour minimiser l&#39;effort de basculer un lien de npmjs.com en npmx.dev avec toutes les features qu&#39;énormément de gens demandent depuis plus de 5 ans mais qui n&#39;ont jamais été implémenté et qui s&#39;entasse dans le backlog depuis le rachat de npm par Github. </p>
<p>Résultat : beaucoup de gens ont migrés au quotidien sur npmx.dev (j&#39;en fais partie) et ça a poussé npmjs.com à commencer à ajouter des choses (le light/dark le mois dernier). Est-ce que ça ira plus loin ? Peut-être. En attendant : on a déjà un super outil, rien n&#39;a changé dans nos habitudes au sens propre </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-ai-agents-can-now-cost-more-than-the-humans-they-were-supposed-to-replace--startup-fortunehttpsstartupfortunecomaiagentscannowcostmorethanthehumanstheyweresupposedtoreplace"><a href="https://startupfortune.com/ai-agents-can-now-cost-more-than-the-humans-they-were-supposed-to-replace/">AI agents can now cost more than the humans they were supposed to replace – Startup Fortune</a><a href="#article-ai-agents-can-now-cost-more-than-the-humans-they-were-supposed-to-replace--startup-fortunehttpsstartupfortunecomaiagentscannowcostmorethanthehumanstheyweresupposedtoreplace" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA</p>
<p>En résumé : si vous remplacez du travail humain qui était globalement du retravaillé de texte (genre du support client / utilisateur de premier niveau qui va reformuler la doc ou RTFM) c&#39;est hyper efficace financièrement, même si ça peut questionner sur la relation humaine. Par contre pour remplacer un flux de travail complexe, voir assez complexe pour demander un contrôle humain, coûte aussi cher voir plus cher que le faire uniquement par un humain.</p>
<p>Et c&#39;est logique : l&#39;IA (en tout cas en l&#39;état actuel des choses) ne peut pas raisonner, donc ne peut pas remplacer un raisonnement humain, et donc il faut à peu près autant d&#39;humain qu&#39;avant mais en plus payer l&#39;IA. Si le gain en temps est très bon ça peut être intéressant (mais ça se discute pour plein de raison : charge mentale sur les humains en question, humain qui ne voit plus toute la tâche et n&#39;est plus aussi pertinent, augmentation de la fatigue humaine et donc augmentation des erreurs, etc.). Si le gain de temps ne permet pas de dégager plus de business c&#39;est une perte sèche </p>
<p>Dans le même temps : on fait ce constat alors qu&#39;on ne paie pas le vrai prix de l&#39;IA, environ 1/100eme du prix, alors imaginez demain quand il faudra payer le prix fort pour l&#39;IA et que les humains ne sauront plus travailler sans ladite IA à cause de la réorientation de capacité cognitive ? 😇 </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-bruteforce-de-cartes-bancaireshttpskorbeninfocartebancairebruteforcehtml"><a href="https://korben.info/carte-bancaire-brute-force.html">Bruteforce de cartes bancaires</a><a href="#article-bruteforce-de-cartes-bancaireshttpskorbeninfocartebancairebruteforcehtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Paiement #Sécurité #Carte-bancaire #Banque</p>
<p>Un chercheur en sécurité se rend compte que c&#39;est hyper facile de bruteforce un numéro de carte bancaire (quand on a le ticket de carte où il manque juste une partie des chiffres) en environ une nuit </p>
<p>Comment ça marche sa technique ? Facile ! On tente toutes les combinaisons en tapant les formulaires de paiement de différents sites marchants jusqu&#39;à ce que ça passe. Certains sites marchants vont carrément jusqu&#39;à indiquer que la carte est expirée, qu&#39;il y a une erreur de 3 chiffres ou que c&#39;est juste le CVV qui est faux… Des infos qui aident encore plus le bruteforce… </p>
<p>Et une fois les numéros obtenus, il suffit de passer par un site qui ne demande pas le 3DS et c&#39;est bon on peut vider le compte 🥶 (et pas besoin de chercher loin pour un site sans 3DS, Amazon n&#39;a pas de 3DS la plupart du temps) </p>
<p>En résumé : si quelqu&#39;un a le script et trouve un ticket de carte, en une nuit il peut récupérer le numéro complet et vider votre compte. Et le plus &quot;drôle&quot;? C&#39;est les sites sans 3DS qui auront servi à vider votre compte qui seront considérés comme responsable 😅 </p>
<p>Je crois que je vais arrêter complètement de prendre des tickets de cartes moi… </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-git-fixup-is-magic-and-magit-is-toohttpsarialdomartinigithubiogitfixup"><a href="https://arialdomartini.github.io/git-fixup">Git fixup is magic (and Magit is too)</a><a href="#article-git-fixup-is-magic-and-magit-is-toohttpsarialdomartinigithubiogitfixup" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Git</p>
<blockquote>
<p>Add this alias to your <code>.gitconfig</code>:</p>
<pre><code>[alias]
  fixup = &quot;!f() { TARGET=$(git rev-parse $1); git commit --fixup=$TARGET ${@:2} &amp;&amp; GIT_SEQUENCE_EDITOR=true git rebase -i --autostash --autosquash $TARGET^; }; f&quot;
</code></pre><p>Then, use it as follows:</p>
<ul>
<li>Make a change.</li>
<li>Stage files with git add .</li>
<li>Fix up the desider commit (git fixup <SHA-1>).</li>
<li>Profit.</li>
</ul>
</blockquote>
<p>Alias sympa pour git qui me fait découvrir qu&#39;on peut faire un commit qui fait directement un fixup d&#39;un autre sans passer par un rebase explicite dans un second temps 😮 </p>
<h3 id="article-podman-avec-des-quadlets--gitops-avec-materiahttpsunetassedecafeblogpodlet"><a href="https://une-tasse-de.cafe/blog/podlet/">Podman avec des Quadlets + GitOps avec Materia</a><a href="#article-podman-avec-des-quadlets--gitops-avec-materiahttpsunetassedecafeblogpodlet" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Docker #GitOps #OS #Git #SystemD #DevOps</p>
<p>Franchement super intéressant ça ! </p>
<p>Docker ça veut généralement dire qu&#39;on est en root, avec un daemon qui tourne, et on se coupe de l&#39;OS pour la partie gestion. Mais Docker c&#39;est pas fou pour orchestrer des conteneurs (qui sont des processus comme les autres au fond).</p>
<p>Podman c&#39;est une alternative à Docker. Quadlets vient remplacer Docker Compose mais pas en faisant la même chose : il vient juste donner la petite couche qui manque pour facilement gérer nos services conteneurisés via SystemD (je sais, je sais, beaucoup n&#39;aiment pas, je m&#39;en fiche c&#39;est pas le sujet du jour, et SystemD ça marche quand même bien et globalement partout). Plus besoin de daemon vu que c&#39;est SystemD qui gère tout.</p>
<p>Et du coup on récupère tout le système de timer, d&#39;ordonancement, d&#39;orchestration, de log, etc. de SystemD ! 😮 </p>
<p>L&#39;auteur propose aussi de passer par Materia pour faire du GitOps : on décrit dans un repo git nos services, materia se charge de mettre à jour nos définitions de services sur notre serveur ! </p>
<p>Je serais vraiment curieux de voir la consommation RAM et CPU ! </p>
<h3 id="article-oui-votre-assureur-axa-pourrait-bloquer-vos-remboursements-sur-ordre-de-washingtonhttpswwwclubiccomdossier608725axamshinternationalcesentreprisesfrancaisesquimangentdanslamaindetrumphtml"><a href="https://www.clubic.com/dossier-608725-axa-msh-international-ces-entreprises-francaises-qui-mangent-dans-la-main-de-trump.html">Oui, votre assureur Axa pourrait bloquer vos remboursements sur ordre de Washington</a><a href="#article-oui-votre-assureur-axa-pourrait-bloquer-vos-remboursements-sur-ordre-de-washingtonhttpswwwclubiccomdossier608725axamshinternationalcesentreprisesfrancaisesquimangentdanslamaindetrumphtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Europe #Politique #USA #Tech</p>
<p>Nicolas Guillou, magistrat français à la Cour pénale internationale (CPI), décrit pourquoi il n&#39;a plus de remboursement de sa mutuelle Axa depuis qu&#39;il a été ajouté sur la liste OFAC (qui ne contient globalement que des terroristes ou coupable de crime contre le droit humain) pour avoir signé un mandat d&#39;arrêt contre Benyamin Nétanyahou. Axa n&#39;a aucune contrainte légale à appliquer ici des sanctions liées à la liste OFAC quand Guillou va la pharmacie de son quartier ou chez son médecin, mais dans le doute de représaille américaine, ils choisissent volontairement de ne plus rendre le service pour lequel Guillou paie. </p>
<p>Du fait que les entreprises choisissent majoritairement des boîtes américaines pour héberger services et données entraînent une dépendance aux USA, quand bien même la localisation physique est en Europe. Du fait que des entreprises aient une part non négligeable de leur business aux USA entraînent une dépendance aux USA. </p>
<p>Là où je ne suis pas d&#39;accord : on a le choix de travailler ou pas avec des acteurs américains, et s&#39;il manque une offre sur un service, on a des acteurs en Europe pour la construire avec eux plutôt que payer pour l&#39;amélioration de la version américaine dudit service. </p>
<p>Là on cite Axa mais c&#39;est vrai pour toutes les boîtes qui ont une dépendance avec les USA. Et pour moi toutes ces boîtes sont en risques à cause de ça. </p>
<p>La technologie c&#39;est politique. Le business c&#39;est politique. Tout est politique. Et si on veut garder une certaine latitude de liberté, il faut choisir avec qui on bosse. </p>
<h3 id="article-lemergence-dun-librofascisme--denis-szalkowskihttpswwwdsfcnetosslemergencedunlibrofascisme"><a href="https://www.dsfc.net/oss/l-emergence-d-un-librofascisme/">L’émergence d’un librofascisme — Denis Szalkowski</a><a href="#article-lemergence-dun-librofascisme--denis-szalkowskihttpswwwdsfcnetosslemergencedunlibrofascisme" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#DINUM #Open-source #Open-Source #Souveraineté #France #Linux #KDE #OS</p>
<p>Je ne connais pas l&#39;auteur personnellement mais ça fait une grosse dizaine d&#39;années que je le lis et donc je commence à connaître le personnage public : un en titinet troll, avec des astuces techniques qui viennent de l&#39;expérience, des raisonnements qui tiennent la route mais souvent des conclusions avec lesquels je suis rarement d&#39;accord, accompagné de position assez tranché et qui se basent parfois sur du doigt mouillé. Mais lire des avis divergeant est plutôt saint à mon sens pour questionner sa propre réflexion. </p>
<p>Je cite le premier paragraphe :</p>
<blockquote>
<p>J’ai toujours été dans une démarche d’éducation populaire en ce qui concerne Linux et le logiciel libre. Je n’ai jamais eu de chapelle, d’approche identitaire, contrairement à une grande majorité de libristes. Cette vision identitaire, je l’ai ressentie d’abord avec les debianœuds, puis avec des stagiaires ayant jeté leur dévolu sur Gentoo au milieu des années 2000. Debian n’était pas assez compliqué pour eux. Il leur fallait être des hommes, des vrais. En entendant parler de NixOS, là, je suis tombé des nues quand j’ai vu la complexité non feinte du gestionnaire de paquets. J’ai cru revenir 20 ans en arrière, voire plus.</p>
</blockquote>
<p>Je ne vais pas mentir, je fais partie des libristes qui défendent une vision &quot;identitaire&quot; du logiciel libre : je crois au libre pas par pragmatisme mais par conviction que c&#39;est par le logiciel libre qu&#39;on rendra les gens maîtres de leur usage, de là à parler d&#39; &quot;identité&quot; je ne sais pas par contre mais passons.</p>
<p>Vous vous en doutez je n&#39;ai pas non plus connu ses stagiaires qui ont préféré Gentoo à Debian début 2000, mais il y a sûrement de bonne raison de choisir Gentoo, et quand bien même c&#39;était pour sa complexité (je maîtrise peu Gentoo mais de mémoire c&#39;est une distribution avec un gestionnaire de paquet qui compile votre système, du Kernel aux outils graphiques) ils ont dû apprendre énormément de chose à l&#39;utiliser. </p>
<p>Parler d&#39;un retour 20 ans en arrière au sujet de NixOS est pour moi une très très grosse blague par contre 🤣 (mais je vous explique plus loin en quoi c&#39;est risible)</p>
<p>Je cite le paragraphe suivant :</p>
<blockquote>
<p>Je me suis restreint désormais à deux distributions Linux : Fedora et Debian Testing. Elles disposent toutes deux d’un installeur graphique offrant cette possibilité au plus grand nombre d’utiliser Linux. Une fois installées, leur gestionnaire de paquets s’interface très simplement avec Discover sous KDE. Un vrai bonheur pour l’utilisateur ou pour l’informaticien qui n’a pas envie de se casser la tête sur sa machine personnelle après sa journée de turbin !</p>
</blockquote>
<p>Monsieur Szalkowski nous expose qu&#39;il se limite à Fedora (au vu de ses publications et de son discours, on parle de la version de base, pas des variantes CoreOS ou Atomic) et Debian Testing. Et que c&#39;est beaucoup mieux du fait de l&#39;installateur graphique et Que ça demande beaucoup moins d&#39;effort à maintenir le soir après le travail quand on est un particulier. </p>
<p>Ok très bien mais ce n&#39;est pas vraiment la cible de Securix (distribution durçi) et Bureautix (distribution agent) <a href="https://www.clubic.com/dossier-609418-securix-et-bureautix-voici-a-quoi-ressemble-vraiment-le-linux-qui-va-remplacer-windows-en-france.html">les distributions Linux basés sur NixOS proposés par la DINUM</a>. La première vise à priori les ministères et personnels manipulant des données de niveau secret ou supérieur, la seconde le reste des agents de l&#39;Etat de la secrétaire de mairie aux ministres. Mais à aucun moment il n&#39;est prévu de leur demander d&#39;installer ou administrer leur machine individuellement.</p>
<p>NixOS c&#39;est quoi ? C&#39;est une distribution qui se base que le gestionnaire de paquet <code>nix</code> qui vise à rendre le plus atomique possible et le plus replicable possible les mises à jours et installations de paquet. L&#39;idée (en très grosse maille, y&#39;a beaucoup à en dire) c&#39;est que tout ce qui est installé le sera dans un volume read only, chaque paquet individuellement, puis <code>nix</code> va créer une sorte d&#39;image de votre nouveau système en jouant que des liens et des variables d&#39;environnements avant de basculer sur cette image, la précédente restant en présente sur la machine permettant de revenir sur une version précédente au besoin. Pour garantir la réplicabilité, <code>nix</code> impose de tout déclarer dans des fichiers de configuration plutôt que de multiplier les appels à lignes de commandes. </p>
<p>Pourquoi c&#39;est parfaitement adapté ici ? L&#39;équipe informatique d&#39;un ministère pourra déployer / maintenir / administrer tout le parc sous sa responsabilité simplement en poussant dans un dépôt git la nouvelle version de la configuration NixOS avant de la pousser sur les différents postes automatiquement, <code>nix</code> va garantir l&#39;application de la mise à jour. De plus si une erreur survient un retour arrière est garantie pour ne pas bloquer les agents.</p>
<p>C&#39;est complètement la logique DevOps qu&#39;on retrouve là. Celle qui est née à la suite du raz le bol de toute la filière de gérer en clic-clic ou en configuration individuelle chaque serveur dont on avait besoin. Vouloir gérer tout le parc des machines des agents de l&#39;Etat via une logique as-code et uniforme est purement pragmatique à mon sens : c&#39;est moins coûteux en temps, en effort et en argent. </p>
<p>Troisième paragraphe :</p>
<blockquote>
<p>A l’occasion de la publication de mes billets et vidéos sur tout le mal que je pensais du choix de NixOS fait par la DINUM, j’ai à nouveau pu me frotter à des rageux et des haters identitaires. Je les ai bananés des commentaires. De simples commentateurs vautrés dans un anonymat de pacotille qui, souvent, se déclarent contributeurs, incapables de partager par vidéo ou par blog interposés leurs compétences de manière didactique et d’agir dans une démarche d’éducation populaire ! Ce qu’ils recherchent, c’est la complexité. Ils veulent se rendre indispensables, recherchant la technique pour la technique. Leur jeunesse les prive de la mémoire et des raisons de l’émergence de la micro-informatique au milieu des années 80. Ce sont aujourd’hui les mêmes causes qui poussent les entreprises à adopter Azure ou AWS. Les collectivités, les entreprises ne veulent plus d’informaticiens qui se complaisent et se vautrent dans la complexité. Continuez ainsi, chères et chers amis, et vous finirez par perdre votre boulot, tant le discours que vous portez est antinomique avec les besoins des entreprises.</p>
</blockquote>
<p>Autant je condamne le harcèlement en ligne et les haters, autant je n&#39;ai pas vu les commentaires, donc je ne me permettrais pas de dire s&#39;il s&#39;agit bien de haters ou d&#39;un Denis qui prend mal qu&#39;on ne soit pas d&#39;accord avec lui avec un discours qui manque de recul 🤷‍♂️ (même si je suis enclain à le croire quand il parle de harcèlement)</p>
<p>En tout cas, je suis en désaccord total avec &quot;Ce qu’ils recherchent, c’est la complexité.&quot; (qui fait écho au premier paragraphe et ses stagiaires sous Gentoo comme si les équipes de la DINUM étaient constitués d&#39;étudiants de 20 piges). Comme expliqué juste avant : on est pour moi à un choix qui se justifie techniquement et qui comme le choix de partir vers un cloud comme Azure ou AWS implique une phase de migration coûteuse et un peu complexe (on va pas se mentir : migrer le parc de machine de Windows à NixOS ne va pas se faire d&#39;un claquement de doigts), pour gagner en fiabilité et simplicité dans un second temps. On peut critiquer les choix qui ont été faits, mais je vois un vrai pragmatisme ici. Quand bien même on est face à une distribution avec un installateur en ligne de commande (qu&#39;on ne verra de toutes façons sûrement jamais vu qu&#39;on passera par un outil d&#39;installation automatisé, comme on fait avec les postes Windows sur lesquels on déploie des images de l&#39;OS prêt à l&#39;emploi et pré-configuré). </p>
<p>Je saute le paragraphe 4 qui n&#39;apporte rien de plus qu&#39;une répétition du postulat : le choix du logiciel libre c&#39;est pour l&#39;argent et &quot;Les éléments de langage autour de cette distribution à l’approche qualifiée de déclarative et reproductible, s’apparentant fortement à du nudge, semblent avoir marqué les esprits. […] Jeunes gens, tâchez d’exprimer une pensée autonome.&quot; (encore une fois, la DINUM qui n&#39;est composé que d&#39;une armée d&#39;étudiants-stagiaire sans expérience) </p>
<p>Ensuite sur le paragaphe 5 :</p>
<blockquote>
<p>Sur Fedora, j’ai pu lire de bien curieux commentaires frisant avec un syllogisme de bas étage. Fedora, c’est Red Hat. Red Hat, c’est IBM. IBM, c’est les États-Unis. Et donc Fedora ne peut pas s’inscrire dans le choix d’une distribution souveraine. Transposons. NixOS est hollandaise. La Hollande fait partie de l’OTAN. L’OTAN est dirigé par les États-Unis. Donc NixOS ne peut pas être une distribution souveraine. Avouez que les deux raisonnements sont tout autant stupides l’un que l’autre. Dois-je encore consommer de la sauce hollandaise si je veux rester souverain dans ma cuisine ? J’y réfléchis très sérieusement. ;+)</p>
</blockquote>
<p>Je passe la blague sur la cuisine en fin de paragraphe qui est hors propos (c&#39;est pas mon humour mais chacun son humour c&#39;est pas le sujer et je n&#39;ai pas de critique / réponse ici). Par contre je suis ici d&#39;accord avec Denis : que Fedora soit supportée par une entreprise américaine n&#39;est pas un sujet. C&#39;est une distribution open source, quand bien même on viendrait à être coupé des USA, un fork de Fedora verrait le jour en Europe et il suffirait de migrer. Particulièrement vrai si au lieu de NixOS c&#39;est Fedora Silverblue (ou une autre variante Atomic) de Fedora qui avait été choisie : rpm-ostree et flatpak comme socle au lieu de yum/dnf pour obtenir des garanties d&#39;atomicité et reproductibilité du même genre que NixOS mais avec une approche différente techniquement parlant. Mais à priori les équipes de Fedora aussi possèdent une armée d&#39;étudiant-stagiaire qui cherchent la complexité 🤷‍♂️</p>
<p>Le dernier paragraphe :</p>
<blockquote>
<p>Ni les Russes, ni les Chinois, ni les Brésiliens ne se sont embarrassés de savoir si Fedora – la distribution de Monsieur et Madame Torvalds – ou Debian étaient deux représentants du soft power américain, au même titre que pouvaient l’être Maryline Monroe et Elvis Presley. A quel titre, ces populations « indigènes » des contrées lointaines auraient-elles fait le choix de la confidentialité pour se priver du travail de centaines, de milliers d’ingénieurs, d’universitaires et de quelques geeks en sandalettes, en s’agrégeant aux projets… américains ? Sous quels brevets sont fabriqués nos processeurs ? Le choix de NixOS est, selon moi, purement identitaire et donc idéologique. Et je ne vois pas bien ce que l’idéologie a à voir avec le logiciel libre. J’y sens, pour ma part, à tort ou à raison, le relent de l’émergence d’un librofascisme auquel nous devons opposer de toutes nos forces les pratiques d’éducation populaire et de mise à disposition de Linux et des logiciels libres au plus grand nombre.</p>
</blockquote>
<p>L&#39;origine de la distribution n&#39;est pas un sujet comme j&#39;ai dit (quoi que, j&#39;aurais peut-être à y redire si ça venait d&#39;une boîte comme Palantir ou de la CIA, ou autre organisme d&#39;espionage / surveillance mais passons), que Fedora soit la distribution préférée de Linus Torvald (le créateur de Linux) non plus. Au passage Linus utilise un vieux fork patché d&#39;une version allégé d&#39;Emacs, donc on devrait peut-être l&#39;immiter aveuglément ? 🤔 (non, Linus dit lui-même qu&#39;il fait ça purement par habitude pas par pragmatisme et de pas faire comme lui) </p>
<p>Je ne vais pas me répéter : arguer l&#39;idéologie ici c&#39;est au mieux de l&#39;ignorance au pire d&#39;une volonté de désinformation ici. </p>
<p>Je ne pensais pas forcément parler de Securix ou Bureautix, en tout cas pas avant de voir émerger le plan de déploiement (perso c&#39;est plutôt ça qui m&#39;intéresse face au choix de la distribution). Ça ne va pas m&#39;empêcher de continuer à lire les billets de monsieur Denis Szalkowski, car j&#39;y vois un intérêt technique. Par contre ça me conforte dans mon idée qu&#39;on serait rarement d&#39;accord au quotidien que ce soit au travail ou en termes de vision, et c&#39;est pas bien grave, on a chacun notre vie, notre vécu et nos convictions, tout ce qu&#39;on se doit c&#39;est du respect à mon avis. </p>
<h3 id="article-odf-est-lavenir-ooxml-le-passe--linuxfrorghttpslinuxfrorgnewsodfestlavenirooxmllepasse"><a href="https://linuxfr.org/news/odf-est-l-avenir-ooxml-le-passe">ODF est l’avenir, OOXML le passé - LinuxFr.org</a><a href="#article-odf-est-lavenir-ooxml-le-passe--linuxfrorghttpslinuxfrorgnewsodfestlavenirooxmllepasse" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Microsoft</p>
<p>Je cite un bout sur OOXML :</p>
<blockquote>
<p>Le format OOXML, ou Office Open XML, n’a pas été conçu dans un souci d’interopérabilité, mais pour répondre à un objectif très précis : encoder les formats binaires de Microsoft Office en XML de manière à permettre à Microsoft de prétendre respecter la norme sans pour autant renoncer à son emprise sur les utilisateurs par le biais d’un verrouillage technologique.</p>
<p>Cette genèse n’est pas de l’histoire ancienne, mais remonte à la période comprise entre 2006 ‒ par pure coïncidence, l’année où le format ODF a été approuvé par l’ISO ‒ et 2008, année de l’événement grotesque connu sous le nom de « Ballot Resolution Meeting » (réunion de résolution des votes), qui a conduit à l’approbation d’OOXML par l’ISO et qui est consignée dans toutes les versions de la spécification.</p>
<p>OOXML Transitional, la variante que presque tous les documents Microsoft Office utilisent en pratique, et la seule disponible aujourd’hui, est explicitement définie comme une couche de compatibilité avec les anciens formats binaires (les, désormais oubliés, DOC, XLS et PPT, qui n’étaient rien d’autre que l’enregistrement de la mémoire de travail sur le disque), et contient des milliers d’éléments non documentés, d’exceptions spécifiques au format et de références à des systèmes Microsoft hérités qu’aucun tiers ne peut reproduire intégralement.</p>
<p>La spécification elle-même reconnaît que les fichiers Transitional peuvent contenir des éléments dont le comportement est « hérité » et dont l’affichage correct nécessite une connaissance des systèmes propriétaires de Microsoft. En bref, pour implémenter correctement OOXML Transitional, il faut décoder trente ans d’histoire de Microsoft Office, ce que personne, à l’exception de Microsoft, ne peut faire, et que personne ne pourra jamais faire.</p>
<p>En ce sens, choisir OOXML n’est pas un pari mais un choix rétrograde, parce que le format n’est ouvert qu’en apparence ‒ mais il suffit de très peu, d’un peu de bonne volonté, pour se rendre compte qu’il est complètement fermé ‒ et a été conçu pour être un mécanisme de verrouillage.</p>
</blockquote>
<p>Je crois que tout est dit ! Je savais que OOXML (docx, xlsx, pptx, etc.) c&#39;était de la camelote, mais je savais pas quel point… Clairement faut arrêter d&#39;utiliser ces machins… Et il me semble que même la suite MS Office peut utiliser les formats ODF donc pourquoi on continue de s&#39;infliger des saletés pareilles ? Certains aiment vraiment tendre le bâton pour se faire battre 😬 </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Un VPN ça ne sert à rien]]></title>
      <guid isPermaLink="false">2026/04/28/un-vpn-ca-ne-sert-a-rien</guid>
      <description><![CDATA[<p>On voit beaucoup d&#39;influenceur vous vendre des VPNs depuis des années pour &quot;votre sécurité&quot; ou pour …</p>
]]></description>
      <link>https://anthonypena.fr/2026/04/28/un-vpn-ca-ne-sert-a-rien/index.html</link>
      <category><![CDATA[Internet]]></category>
      <category><![CDATA[Sécurité]]></category>
      <category><![CDATA[Avis]]></category>
      <pubDate>Tue, 28 Apr 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>On voit beaucoup d&#39;influenceur vous vendre des VPNs depuis des années pour &quot;votre sécurité&quot; ou pour tricher sur votre géo-localisation pour payer des trucs moins chers. En vrai, c&#39;est pas forcément toujours le bon plan voir même pas souhaitable, je vous explique.</p>
<blockquote>
<p>Note : je vais dans cet article dans une direction qui va à l&#39;opposé de ce que la plupart des gens vous diront, mais je sais que je ne suis pas le seul à avoir ce point de vue. Par exemple on retrouve une vidéo de <a href="%5Bhttps://youtu.be/ckZGQ5cLIfs">MiCode</a> qui parle aussi du sujet.</p>
</blockquote>
<h2 id="article-vpn--kezako-">VPN ? Kézako ?<a href="#article-vpn--kezako-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>On parle partout de VPN avec plein de promesse, mais concrètement c&#39;est quoi ?</p>
<p>Si on reste assez haut niveau : VPN = Virtual Private Network ou Réseau Privé Virtuel. Donc l&#39;idée c&#39;est de simuler le fait d&#39;avoir plusieurs machines dans le même réseau privé (comprendre = comme si vous étiez chez vous / à votre entreprise, avec toutes les machines branchées sur le même routeur), pour garantir un certain niveau de confidentialité.</p>
<p>Et techniquement, ça fonctionne comment ? C&#39;est assez simple en fait : une brique logicielle prend chaque paquet réseau qui devrait sortir de votre machine (par exemple : votre laptop alors que vous êtes dans un hôtel), chiffre ce paquet, l&#39;envoie à une autre machine ailleurs sur Internet (par exemple : votre Freebox qui est chez vous (oui les Freebox fournissent un VPN gratuitement)) et cette machine va ensuite déchiffrer le paquet réseau, l&#39;envoyer elle sur Internet (en changeant ce qu&#39;il faut dans le paquet pour faire comme si c&#39;était cette machine qui voulait envoyer le paquet réseau), puis une fois la réponse reçue, chiffre la réponse pour l&#39;envoyer à votre laptop qui va déchiffrer lui aussi.</p>
<p>Donc en gros : vous masquez votre activité en ligne (en partie en tout cas) à n&#39;importe qui entre vous (dans l&#39;exemple au-dessus : votre laptop) et votre serveur VPN (dans l&#39;exemple au-dessus : votre Freebox), mais à partir de votre serveur VPN vous êtes à nouveau sur Internet. </p>
<p>J&#39;imagine que vous vous dites &quot;Mais NordVPN / CyberGhost VPN / Proton VPN ! C&#39;est pas comme ça que ça marche ! ça change ma géo-localisation et protège ma connexion !&quot;. Alors oui mais non. Si on prend NordVPN (pour les autres c&#39;est pareil) : votre laptop va chiffrer les requêtes vers Internet pour les envoyer à un serveur NordVPN, on peut imaginer que vous ayez choisi NordVPN Belgique parce que vous êtes fan de F1 (comment ça j&#39;ai vu trop de pub pour des VPN ?) donc un serveur en Belgique va être choisi, ensuite ce serveur va lire tout ce que vous lui envoyez pour ajuster le contenu avant de l&#39;envoyer sur Internet (sans vraie protection en plus que si vous aviez fait la même chose depuis votre laptop du coup), puis il vous renverra la réponse qu&#39;on lui aura donnée, faisant croire que vous vous connectez depuis la Belgique de facto.</p>
<h2 id="article-pouvezvous-faire-confiance-a-votre-serveur-vpn-">Pouvez-vous faire confiance à votre serveur VPN ?<a href="#article-pouvezvous-faire-confiance-a-votre-serveur-vpn-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ce qu&#39;il faut bien comprendre c&#39;est qu&#39;utiliser un VPN veut dire déléguer sa connexion à une autre machine. Si vous êtes le propriétaire de la machine (au sens = elle est chez vous) vous pouvez à priori lui faire confiance (sauf si vous n&#39;avez aucune confiance en votre FAI (Fournisseur d&#39;Accès Internet)). Si c&#39;est le serveur de votre entreprise, pour votre machine professionnelle à priori c&#39;est plutôt sécurisé (pour du pro en tout cas, ça dépend de beaucoup d&#39;autres paramètres). </p>
<p>Si c&#39;est un serveur commercial, c&#39;est un autre sujet à mon sens : vous n&#39;avez comme garantie que les promesses que l&#39;entreprise vous fait, et donc vous faites confiance à la machine de quelqu&#39;un d&#39;autre pour être plus fiable que votre connexion. Vous faites aussi confiance à l&#39;entreprise de ne pas stocker vos données, vous leur faites confiance sur le fait qu&#39;ils n&#39;ont pas de mécanique pour analyser votre trafic, vous leur faites aussi confiance sur le fait qu&#39;ils font uniquement office de VPN et qu&#39;ils ne font pas plus sur le réseau sans vous le dire.</p>
<p>Le but d&#39;utiliser un VPN c&#39;est d&#39;ajouter un niveau de confidentialité sur votre connexion, donc c&#39;est à vous de voir si la dite couche est plus fiable que votre connexion. Si vous êtes chez vous j&#39;aurais tendance à dire qu&#39;utiliser un VPN pour la sécurité est une erreur. Si vous êtes dans un hôtel ou un fast food avec un grand M jaune, ça peut se discuter car vous serez sur des réseaux publics avec un très faible contrôle sur les utilisateurs connectés, mais à voir.</p>
<h2 id="article-estce-que-tout-passe-par-le-vpn-">Est-ce que tout passe par le VPN ?<a href="#article-estce-que-tout-passe-par-le-vpn-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Imaginons que vous êtes dans un cas où le VPN est bien utile. Il faut s&#39;assurer qu&#39;on fait bien passer l&#39;intégralité de son trafic par le VPN.</p>
<p>Par exemple si vos appels HTTP passent par le VPN mais que vos requêtes DNS (résolution des noms de domaines) passent sur le réseau classique, on peut savoir tous les sites que vous allez consulter. Il arrive aussi que votre configuration fasse qu&#39;en cas de rupture de session VPN, vous arriviez sur un fallback sans VPN et parfois silencieusement…</p>
<p>En fait ça dépend énormément de ce que vous cherchez dans le VPN : si c&#39;est la sécurité des données, la partie DNS n&#39;est pas très importante car ça ne donnera aucune information de données, par contre si vous cherchez l&#39;anonymat / pseudo-anonymat, vous voulez que 100% de votre trafic passe par le VPN.</p>
<h2 id="article-et-la-securite-sans-vpn-ca-existe-">Et la sécurité sans VPN ça existe ?<a href="#article-et-la-securite-sans-vpn-ca-existe-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Déjà qu&#39;on soit clair : on a disposition énormément de solution de sécurité sans avoir besoin de passer par du VPN.</p>
<p>La première brique pour moi à ne pas oublier c&#39;est le HTTPS, le S étant important. En effet le S de HTTPS indique aujourd&#39;hui qu&#39;on va utiliser du chiffrement TLS pour les échanges. Clairement ce n&#39;est pas parfait, il est toujours possible de faire du Man In The Middle en ciblant quelqu&#39;un, on sait que si on capture un paquet TLS, il est possible de le déchiffrer en cassant la clé avec une grosse infrastructure ou beeeeeaaaaauuuucoup de temps, mais soyons honnêtes : on est pas si intéressant que ça individuellement pour que quelqu&#39;un prenne le temps de faire ça spécialement pour nous.</p>
<p>Si vraiment vous voulez augmenter votre anonymat en ligne, vous pouvez passer par le réseau Tor. Le plus simple c&#39;est d&#39;utiliser <a href="https://www.torproject.org/download/">Tor Browser</a>, une version de Firefox modifiée pour passer par le réseau Tor au maximum et accéder à Internet en faisant passer sa connexion chiffrée par plusieurs nœuds intermédiaires avant de rejoindre Internet de sorte que l&#39;origine de la requête soit presque intraçable (presque parce qu&#39;il y a des cas où on peut désanonymiser le trafic Tor). C&#39;est gratuit, ça fonctionne bien, vous ne choisissez pas explicitement la localisation du nœud de sortie (donc la localisation qui sera affichée pour le serveur), c&#39;est un choix au hasard parmi les nœuds du réseau, mais ça fonctionne très bien !</p>
<h2 id="article-le-vpn-en-entreprise-est-un-antipattern-a-mon-avis">Le VPN en entreprise est un anti-pattern à mon avis…<a href="#article-le-vpn-en-entreprise-est-un-antipattern-a-mon-avis" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ça fait 10 ans que je travaille en entreprise. Ça fait 10 ans que je constate la même chose : on sécurise généralement très bien l&#39;entrée du réseau privé de l&#39;entreprise mais une fois qu&#39;on est dans le réseau interne il n&#39;y a presque plus de protection…</p>
<p>On voit parfois du HTTPS en interne mais plus d&#39;authentification &quot;parce qu&#39;on est dans le réseau interne&quot;. Parfois même le HTTPS n&#39;est pas là en interne… Parfois on voit du filtrage IP sur les plages d&#39;IP interne pour ouvrir les vannes sans plus de restriction…</p>
<p>Du coup il se passe quoi si quelqu&#39;un infiltre votre réseau interne ? C&#39;est simple : il a le champ libre pour faire ce qu&#39;il veut… Et accéder au réseau interne, ça va de physiquement se brancher sur une prise Ethernet dans les bureaux ou la wifi, à obtenir le mot de passe VPN d&#39;un utilisateur et se connecter à distance.</p>
<p>Mon avis est très clair : Zero Trusted Network / Aucun Réseau de Confiance. Partez du principe que vous ne pouvez avoir confiance en aucun réseau, que chaque connexion doit être sécurisé, contrôlé et traçable, peu importe la source.</p>
<blockquote>
<p>Note : il y a même des avantages métiers à fonctionner en tout authentifié si c&#39;est bien fait : vous pouvez savoir qui sont vos utilisateurs / consommateurs et donc créer des communications au besoin.</p>
</blockquote>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ici je ne vais même pas abordé les contraintes légales et/ou contractuels autour de l&#39;utilisation des VPNs (typiquement : en théorie vous n&#39;avez pas le droit d&#39;utiliser un VPN pour vous relocaliser et payer moins cher un service / accéder à un contenu géo-bloqué).</p>
<p>En tout cas je voulais parler du sujet depuis assez longtemps, j&#39;ai posé mon avis, vous n&#39;êtes pas obligé de le partager. Par contre si vous avez un avis différent avec des arguments, je suis complètement ouvert et intéressé pour échanger sur le sujet, et pourquoi pas même mettre à jour cet article !</p>
<p>Sources :</p>
<ul>
<li><a href="https://youtu.be/ckZGQ5cLIfs">NordVPN vous ment. (non sponsorisé)</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A cozy wooden desk bathed in soft golden afternoon light, featuring futuristic technical magazines and a holographic screen with a wooden frame displaying animated lines of code. In the bottom right corner, a red panda is curled up on a cushion, gazing at a semi-transparent tunnel extending from the screen outward. The tunnel is a blend of circuit board patterns and tree branches, symbolizing the duality of technology and nature. The scene is filled with 8-10 minimalist red, orange, and yellow maple leaves floating gently around, creating a warm, autumnal atmosphere. The art style is inspired by Studio Ghibli, with soft lines, detailed textures, and a poetic, dreamy ambiance.&quot;</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Reprendre le contrôle de vos dépendances NPM]]></title>
      <guid isPermaLink="false">2026/04/22/reprendre-le-controle-de-vos-dependances-npm</guid>
      <description><![CDATA[<p>Je vois souvent des gens ne pas maitriser l&#39;usage de NPM au quotidien. Des choses basiques, mais imp…</p>
]]></description>
      <link>https://anthonypena.fr/2026/04/22/reprendre-le-controle-de-vos-dependances-npm/index.html</link>
      <category><![CDATA[Frontend]]></category>
      <category><![CDATA[Backend]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[TypeScript]]></category>
      <pubDate>Wed, 22 Apr 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Je vois souvent des gens ne pas maitriser l&#39;usage de NPM au quotidien. Des choses basiques, mais importantes, surtout quand il s&#39;agit de se débarrasser d&#39;une faille de sécurité dans une dépendance transitive. Je ne suis pas expert NPM, mais après quasi 10 ans à l&#39;utiliser au quotidien, j&#39;ai appris quelques trucs qui servent bien, et j&#39;en apprends encore !</p>
<h2 id="article-cest-quoi-une-dependance-">C&#39;est quoi une dépendance ?<a href="#article-cest-quoi-une-dependance-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>En général, on répondra &quot;tout ce qui est listé dans le <code>package.json</code>&quot;. Et ce n&#39;est pas faux en soi. Mais c&#39;est incomplet en théorie.</p>
<p>Déjà si vous faites du Node, vous avez au strict minimum deux dépendances : Node et <code>npm</code> (ou peut-être <code>yarn</code> ou <code>pnpm</code>, mais au fond vous avez quand même <code>npm</code> sur votre machine quoi qu&#39;il arrive, et je ne vais pas couvrir les spécificités de <code>yarn</code> (que je ne maitrise pas assez) et <code>pnpm</code> (qui est trop intéressant pour juste faire un paragraphe dessus)). Sans ces deux outils, vous ne pouvez pas travailler au sens compiler / exécuter votre application. Donc vous dépendez de ces deux outils. Je ne vais pas rentrer plus dans le détail mais juste : pensez à mettre à jour votre version Node régulièrement, particulièrement avec le changement de <a href="/2026/04/08/revue-de-presse-avril/#article-evolving-the-nodejs-release-schedulehttpsnodejsorgenblogannouncementsevolvingthenodejsreleaseschedule">cycle de release</a>.</p>
<p>L&#39;autre aspect qui manque c&#39;est la notion de dépendance transitive. On qualifie de dépendance transitive une dépendance d&#39;une de nos dépendances. Prenons un exemple simple : vous avez un projet SolidJS avec Vite, vous installez donc <code>vite-plugin-solid</code>. Vous avez donc dans votre <code>package.json</code> <code>solid-js</code>, <code>vite</code> et <code>vite-plugin-solid</code> qui sont vos dépendances directes, mais <code>vite-plugin-solid</code> dépend de <code>@babel/core</code>, <code>babel-preset-solid</code>, <code>solid-js</code>, <code>solid-refresh</code>, <code>vite</code> et <code>vitefu</code>, et si vous creusez encore vous verrez que <code>babel-preset-solid</code> dépend de <code>@babel/core</code>, <code>babel-plugin-jsx-dom-expressions</code> et <code>solid-js</code>, et on pourrait creuser un peu toutes les dépendances comme ça. Chaque dépendance pouvant dépendre d&#39;une version différente d&#39;une même dépendance (vous pouvez dépendance de <code>solid-js@1.9.12</code>, <code>babel-preset-solid</code> dépendre de <code>solid-js@1.9.11</code>, et <code>babel-preset-solid</code> dépendre de <code>solid-js@1.9.10</code>), ce ne serait pas forcément très stable / recommandé mais c&#39;est possible du point de vue de NPM.</p>
<p>Vous avez donc des dépendances que vous maitrisez et d&#39;autres que vous ne maitrisez pas directement. À priori.</p>
<h2 id="article-visualise-vos-dependances">Visualisé vos dépendances<a href="#article-visualise-vos-dependances" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Commençons par notre <code>package.json</code> :</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
  ...
  <span class="hljs-attr">&quot;dependencies&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;solid-js&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^1.9.5&quot;</span>
  <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;devDependencies&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;typescript&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;~5.8.3&quot;</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;vite&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^6.3.5&quot;</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;vite-plugin-solid&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^2.11.6&quot;</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>On voit donc 4 dépendances ici.</p>
<p>Maintenant, installons nos dépendances (<code>npm ci</code> si vous avez un <code>package-lock.json</code>, <code>npm i</code> sinon, j&#39;y reviendrais plus tard).</p>
<pre><code>❯ npm ci # si vous n&#x27;avez pas encore de package-lock.json, utilisez npm i ou npm install

added 73 packages in 1m

13 packages are looking for funding
  run `npm fund` for details
</code></pre><p>Et là NPM nous dit avoir installé 73 packages. On est donc bien loin des 4 qu&#39;on voyait plus haut…</p>
<p>Ensuite on va utiliser <code>npm ls</code>.</p>
<pre><code>npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
├── solid-js@1.9.12
├── typescript@5.8.3
├── vite-plugin-solid@2.11.12
└── vite@6.4.2
</code></pre><p>C&#39;est logique, on retrouve les dépendances de notre <code>package.json</code>. Allons regarder plus en profondeur :</p>
<pre><code>❯ npm ls --depth 1

npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
├─┬ solid-js@1.9.12
│ ├── csstype@3.2.3
│ ├── seroval-plugins@1.5.2
│ └── seroval@1.5.2
├── typescript@5.8.3
├─┬ vite-plugin-solid@2.11.12
│ ├── @babel/core@7.29.0
│ ├── UNMET OPTIONAL DEPENDENCY @testing-library/jest-dom@^5.16.6 || ^5.17.0 || ^6.*
│ ├── @types/babel__core@7.20.5
│ ├── babel-preset-solid@1.9.12
│ ├── merge-anything@5.1.7
│ ├── solid-js@1.9.12 deduped
│ ├── solid-refresh@0.6.3
│ ├── vite@6.4.2 deduped
│ └── vitefu@1.1.3
└─┬ vite@6.4.2
  ├── UNMET OPTIONAL DEPENDENCY @types/node@^18.0.0 || ^20.0.0 || &gt;=22.0.0
  ├── esbuild@0.25.12
  ├── fdir@6.5.0
  ├── UNMET OPTIONAL DEPENDENCY fsevents@~2.3.3
  ├── UNMET OPTIONAL DEPENDENCY jiti@&gt;=1.21.0
  ├── UNMET OPTIONAL DEPENDENCY less@*
  ├── UNMET OPTIONAL DEPENDENCY lightningcss@^1.21.0
  ├── picomatch@4.0.4
  ├── postcss@8.5.9
  ├── rollup@4.60.1
  ├── UNMET OPTIONAL DEPENDENCY sass-embedded@*
  ├── UNMET OPTIONAL DEPENDENCY sass@*
  ├── UNMET OPTIONAL DEPENDENCY stylus@*
  ├── UNMET OPTIONAL DEPENDENCY sugarss@*
  ├── UNMET OPTIONAL DEPENDENCY terser@^5.16.0
  ├── tinyglobby@0.2.16
  ├── UNMET OPTIONAL DEPENDENCY tsx@^4.8.1
  └── UNMET OPTIONAL DEPENDENCY yaml@^2.4.2
</code></pre><p>Le fonctionnement de vite étant d&#39;essayer de s&#39;auto-configurer au maximum, on retrouve beaucoup de dépendances optionnelles. Épurons ces dépendances qui ne sont pas installées pour rendre l&#39;arbre plus lisible</p>
<pre><code>❯ npm ls --depth 1 | grep -v &#x27;UNMET OPTIONAL DEPENDENCY&#x27;
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
├─┬ solid-js@1.9.12
│ ├── csstype@3.2.3
│ ├── seroval-plugins@1.5.2
│ └── seroval@1.5.2
├── typescript@5.8.3
├─┬ vite-plugin-solid@2.11.12
│ ├── @babel/core@7.29.0
│ ├── @types/babel__core@7.20.5
│ ├── babel-preset-solid@1.9.12
│ ├── merge-anything@5.1.7
│ ├── solid-js@1.9.12 deduped
│ ├── solid-refresh@0.6.3
│ ├── vite@6.4.2 deduped
│ └── vitefu@1.1.3
└─┬ vite@6.4.2
  ├── esbuild@0.25.12
  ├── fdir@6.5.0
  ├── picomatch@4.0.4
  ├── postcss@8.5.9
  ├── rollup@4.60.1
  ├── tinyglobby@0.2.16
</code></pre><blockquote>
<p>Note : <code>grep</code> permet de filtrer pour ne garder que les lignes qui contiennent un certain motif, mais si on ajoute l&#39;option <code>-v</code>, on garde les lignes qui ne contiennent pas le motif.</p>
</blockquote>
<p>Rien qu&#39;en ajoutant un niveau de profondeur on est déjà à 20 dépendances, avec <code>solid-js@1.9.12</code> et <code>vite@6.4.2</code> qui taggé comme <code>deduped</code>, c&#39;est à dire identifiées comme déjà résolue et donc n&#39;ont plus besoin d&#39;être résolus (car le package est tiré plus haut dans l&#39;arbre et avec la même version ou une version compatible).</p>
<p>On peut continuer comme ça en augmentant la profondeur affichée. On peut afficher tout l&#39;arbre directement en passant <code>--all</code>. On peut aussi cibler un package précis.</p>
<pre><code>❯ npm ls solid-js                                       
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
├── solid-js@1.9.12
└─┬ vite-plugin-solid@2.11.12
  ├─┬ babel-preset-solid@1.9.12
  │ └── solid-js@1.9.12 deduped
  ├── solid-js@1.9.12 deduped
  └─┬ solid-refresh@0.6.3
    └── solid-js@1.9.12 deduped
</code></pre><p>Ici on voit où la dépendance <code>solid-js</code> est tirée dans l&#39;arbre, la version attendue, si elle est bien dédupliquée comme on s&#39;y attend (ici c&#39;est le cas).</p>
<p>En choisissant <code>solid-js</code> dans un projet SolidJS, on s&#39;attend à le voir. Si vous demande pour <code>esbuild</code> ?</p>
<pre><code>❯ npm ls esbuild 
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
└─┬ vite@6.4.2
  └── esbuild@0.25.12
</code></pre><p>Il n&#39;est pas dans notre <code>package.json</code> pourtant il fait bien partie de l&#39;arbre. Une faille sur <code>esbuild</code> peut donc nous impacter. Et certains me diront qu&#39;<code>esbuild</code> sert uniquement à la compilation donc ne part pas en production. Ce n&#39;est pas aussi simple. Déjà <code>esbuild</code> sera installé sur chaque runner de notre CI, donc à défaut d&#39;infecter nos utilisateurs, on peut impacter notre SI via notre CI ce qui n&#39;est déjà pas terrible. Ensuite on peut se retrouver dans un cas où la faille n&#39;est pas dans <code>esbuild</code> mais dans le code qu&#39;il produit, en effet les outils de compilation vont modifier nos sources et peuvent donc injecter du code non sûr et là ça peut retomber chez les utilisateurs.</p>
<h2 id="article-comment-quon-dit-ce-quon-veut-comme-version-">Comment qu&#39;on dit ce qu&#39;on veut comme version ?<a href="#article-comment-quon-dit-ce-quon-veut-comme-version-" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Déjà il faut comprendre ce qu&#39;on appelle le SemVer ou <strong>Sem</strong>antic <strong>Ver</strong>sioning.</p>
<p>Pour faire très simple : on va définir une version sur trois nombre <code>X.Y.Z</code>. On va appeler X la version majeure, Y la mineure et Z le patch. L&#39;idée va être de se dire qu&#39;une modification qui vient corriger va juste incrémenter le patch, ensuite une nouvelle fonctionnalité qui ne casse rien pour les utilisateurs actuels incrémente uniquement le mineur, et si on casse quelque chose on incrémente le majeur.</p>
<blockquote>
<p>Note : je vous laisse aller voir sur Internet pour tous les détails du SemVer, je n&#39;irai pas plus loin ici. Il reste pas mal de chose à dire : les versions alpha/beta/RC, les versions à quatre nombres, les versionnings alternatifs compatible ou non avec SemVer, etc.</p>
</blockquote>
<p>À partir de là, on se dit qu&#39;on veut parfois dire &quot;je veux strictement cette version&quot;, parfois &quot;je veux bien prendre un nouveau patch mais pas de changement mineur&quot; et de temps en temps &quot;je veux bien tout mettre à jour sauf la majeure&quot;.</p>
<p>Par défaut, si vous faite <code>npm install lodash</code> (pareil si vous faite <code>npm install lodash@latest</code>), NPM va ajouter à votre <code>package.json</code> dans <code>dependencies</code> <code>&quot;lodash&quot;: &quot;^4.18.1&quot;</code> (la dernière version sortie à date). Sauf que là vous avez peut-être mis un doigt dans un système que vous ne vouliez pas avec le <code>^</code> devant la version. En effet <code>^4.18.1</code> veut dire &quot;n&#39;importe quelle version 4.x.x qui est supérieur à 4.18.1&quot;. Donc si vous refaite un <code>npm i</code> dans quelques jours/semaines/mois vous aurez peut-être la version 4.18.1, peut-être une 4.18.2 ou peut-être une 4.45.0. Est-ce que vous vouliez prendre en compte tous ces changements simplement en installant vos dépendances ? Pas sûr (même si, je vous l&#39;accorde : avec <code>lodash</code> on peut normalement mettre à jour les yeux fermés).</p>
<p>Si vous voulez &quot;toujours&quot; tirer la version 4.18.1, il faut retirer le <code>^</code> et refaire un <code>npm i</code> (pour mettre à jour le <code>package-lock.json</code>) ou simplement faire directement <code>npm install lodash --save-exact</code> qui va ajouter au <code>package.json</code> <code>&quot;lodash&quot;: &quot;4.18.1&quot;</code>.</p>
<p>Si vous voulez bien les mises à jours, mais seulement de patch, vous pouvez indiquer <code>&quot;~4.18.1&quot;</code>.</p>
<p>Sauf que là ça ne concerne que les versions qu&#39;on tire directement via notre <code>package.json</code>. Si je veux forcer la version <code>0.27.7</code> d&#39;<code>esbuild</code> je ne peux pas fonctionner comme ça.</p>
<p>En effet si je fais <code>npm i esbuild@0.27.7 --save-exact</code> (la dernière version à date) puis que je regarde l&#39;arbre de dépendance :</p>
<pre><code>❯ npm ls esbuild      
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
├── esbuild@0.27.7
└─┬ vite@6.4.2
  └── esbuild@0.25.12
</code></pre><p>On voit bien que j&#39;ai version <code>0.27.7</code> à la racine de l&#39;arbre, mais sous <code>vite</code> j&#39;ai toujours la version <code>0.25.12</code>. Donc comment on fait ? Déjà on supprime <code>esbuild</code> qui est inutile à la racine du projet <code>npm uninstall esbuild</code>. Puis on va ajouter une section <code>overrides</code> à notre <code>package.json</code> pour forcer partout dans l&#39;arbre une certaine version d&#39;<code>esbuild</code> :</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
  ...  
  <span class="hljs-attr">&quot;overrides&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;esbuild&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;0.27.7&quot;</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>Là on fait <code>npm install</code> pour mettre à jour nos dépendances et on regarde notre arbre de dépendance :</p>
<pre><code>❯ npm ls esbuild
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
└─┬ vite@6.4.2
  └── esbuild@0.27.7 overridden
</code></pre><p>Là on voit bien que la version n&#39;est plus la même et c&#39;est indiqué qu&#39;elle est <code>overridden</code> montrant bien que ce n&#39;est pas la version que NPM aurait choisi normalement.</p>
<p>À Noter qu&#39;on peut aller assez loin avec cette mécanique, par exemple :</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
  ...  
  <span class="hljs-attr">&quot;overrides&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;esbuild&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^0.27.0&quot;</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;vite&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;esbuild&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^0.27.5&quot;</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>Permet d&#39;indiquer qu&#39;on veut surcharger la version d&#39;<code>esbuild</code> en autorisant n&#39;importe quelle version compatible avec <code>^0.27.0</code> partout dans l&#39;arbre de dépendance sauf dans le sous-arbre de <code>vite</code> où on va viser <code>~0.26.0</code> (en l’occurrence, la branche <code>0.26.x</code> ne contient que la version <code>0.26.0</code> donc NPM n&#39;a pas beaucoup de choix de version). Ici ça ne sert pas à grand-chose mais dans certains cas, ça peut être utile. // TODO</p>
<pre><code>❯ npm ls esbuild
npm-deps-override@0.0.0 /home/anthony_p/tmp/npm-deps-override
└─┬ vite@6.4.2
  └── esbuild@0.26.0
</code></pre><p>Ce n&#39;est pas une erreur de ma part, ici on ne voit plus l&#39;indication <code>overridden</code> alors que la version l&#39;est bien mais passons là-dessus. Par contre on voit bien que notre version est surchargée.</p>
<p>Et si maintenant on ajoute ça ?</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
    ...
    <span class="hljs-attr">&quot;overrides&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        ...
        <span class="hljs-attr">&quot;vite-plugin-solid&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
           <span class="hljs-attr">&quot;solid-js&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;1.9.4&quot;</span>
        <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>Normalement au moment de l&#39;installation vous aurez une erreur du type : </p>
<pre><code>❯ npm i         
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: solid-refresh@0.6.3
npm warn Found: solid-js@1.9.12
npm warn node_modules/solid-js
npm warn   solid-js@&quot;^1.9.5&quot; from the root project
npm warn
npm warn Could not resolve dependency:
npm warn peer overridden solid-js@&quot;1.9.4&quot; (was &quot;^1.3&quot;) from solid-refresh@0.6.3
npm warn node_modules/solid-refresh
npm warn   solid-refresh@&quot;^0.6.3&quot; from vite-plugin-solid@2.11.12
npm warn   node_modules/vite-plugin-solid
npm warn
npm warn Conflicting peer dependency: solid-js@1.9.4
npm warn node_modules/solid-js
npm warn   peer overridden solid-js@&quot;1.9.4&quot; (was &quot;^1.3&quot;) from solid-refresh@0.6.3
npm warn   node_modules/solid-refresh
npm warn     solid-refresh@&quot;^0.6.3&quot; from vite-plugin-solid@2.11.12
npm warn     node_modules/vite-plugin-solid
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: vite-plugin-solid@2.11.12
npm error Found: solid-js@1.9.12
npm error node_modules/solid-js
npm error   solid-js@&quot;^1.9.5&quot; from the root project
npm error
npm error Could not resolve dependency:
npm error peer overridden solid-js@&quot;1.9.4&quot; (was &quot;^1.7.2&quot;) from vite-plugin-solid@2.11.12
npm error node_modules/vite-plugin-solid
npm error   dev vite-plugin-solid@&quot;^2.11.6&quot; from the root project
npm error
npm error Conflicting peer dependency: solid-js@1.9.4
npm error node_modules/solid-js
npm error   peer overridden solid-js@&quot;1.9.4&quot; (was &quot;^1.7.2&quot;) from vite-plugin-solid@2.11.12
npm error   node_modules/vite-plugin-solid
npm error     dev vite-plugin-solid@&quot;^2.11.6&quot; from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /home/anthony_p/.npm/_logs/2026-04-15T05_25_31_667Z-eresolve-report.txt
npm error A complete log of this run can be found in: /home/anthony_p/.npm/_logs/2026-04-15T05_25_31_667Z-debug-0.log
</code></pre><p>Et là beaucoup vous diront &quot;passe --force et c&#39;est bon&quot; ou &quot;--legacy-peer-deps c&#39;est mieux !&quot;. Moi je vous dirais : à moins que vous soyez absolument sûr de vous ou que vous n&#39;ayez pas du tout le choix temporairement : ne le faites pas !</p>
<p>Dans mon exemple j&#39;ai indiqué à NPM que je voulais qu&#39;il tire une version &quot;1.9.4&quot; de <code>solid-js</code> pour <code>vite-plugin-solid</code> ce qui implique qu&#39;on casse le fonctionnement des peer dependancies (dépendance qu&#39;on attend qui soit tirée dans l&#39;arbre mais pas forcément par notre package). Passer <code>--force</code> ou <code>--legacy-peer-deps</code> ne va pas fonctionner ici de part le fonctionnement des peer dependancies (vous aurez la <code>1.9.12</code> qui sera prise partout dans l&#39;arbre quand même) mais passer <code>--force</code> ou <code>--legacy-peer-deps</code> va transformer les erreurs en warnings, masquant au passage (car personne ne lit les warnings) des futurs problèmes et donc vous rendant beaucoup plus difficile la montée de version de vos dépendances dans le futur…</p>
<p>Donc si vous arrivez dans le cas où NPM vous propose <code>--force</code> ou <code>--legacy-peer-deps</code> corriger la source du problème, mais n&#39;utilisez pas ces arguments !</p>
<h2 id="article-npm-i-npm-ci-npm-audit-et-packagelockjson"><code>npm i</code>, <code>npm ci</code>, <code>npm audit</code> et <code>package-lock.json</code><a href="#article-npm-i-npm-ci-npm-audit-et-packagelockjson" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je vois souvent des gens utiliser sans distinction <code>npm i</code> et <code>npm ci</code>. Les deux sont fondamentalement différents dans l&#39;usage :</p>
<ul>
<li><code>npm i</code> va lire votre <code>package.json</code> puis va interroger le registry NPM (par défaut <a href="https://npmjs.com/">https://npmjs.com/</a>) pour résoudre chaque dépendance (directe et transitive), voir s&#39;il y a une nouvelle version à tirer qui correspond au pattern qu&#39;on a indiqué, puis une opération de dédoublonnement va rentrer en œuvre, pour enfin créer votre dossier <code>node_modules</code> et créer (ou mettre à jour) le <code>package-lock.json</code> qui va être une image de votre dossier <code>node_modules</code> avec tout l&#39;arbre, les checksums pour valider que les packages n&#39;ont pas changé (et donc n&#39;ont pas été infectés depuis la dernière fois où vous les avez téléchargés) ;</li>
<li><code>npm ci</code> quant à lui va lire le <code>package-lock.json</code>, vérifier qu&#39;il est bien synchronisé avec le <code>package.json</code> (une section au début du <code>package-lock.json</code> reprend le contenu des <code>dependencies</code> et <code>devDependencies</code> du <code>package.json</code>), puis va télécharger en vérifiant les checksums les versions indiquées dans le <code>package-lock.json</code>, sans plus de traitement, pour créer le dossier <code>node_modules</code> ;</li>
</ul>
<p>Donc autrement dit : <code>npm i</code> est là pour modifier / mettre à jour vos dépendances, <code>npm ci</code> pour les installer. Si vous utilisez continuellement <code>npm i</code> vous allez continuellement mettre à jour vos dépendances (en plus de largement perdre du temps sur cette étape), alors qu&#39;avec <code>npm ci</code> vous allez installer les mêmes versions que toute l&#39;équipe et que votre CI donc vous êtes certain que vous n&#39;aurez pas d&#39;écart à l&#39;exécution. C&#39;est encore plus important si vous exécutez du Node.js côté serveur, parce qu&#39;avec des <code>npm i</code> vous n&#39;avez aucune garantie que l&#39;exécution se fera avec les mêmes versions de dépendances en production qu&#39;en local.</p>
<p>Et <code>npm audit</code> qu&#39;on voit régulièrement quand on fait des <code>npm i</code> ? C&#39;est une commande qui va inspecter vos dépendances et va vous indiquer si c&#39;est possible de mettre à jour des packages dans l&#39;arbre de dépendance pour corriger des failles de sécurité. <code>npm audit</code> vous donnera les infos, <code>npm audit fix</code> va appliquer tout ce qui est sans risque d&#39;un point de vue SemVer. Dans la plupart des cas, <code>npm audit fix</code> va essentiellement modifier le <code>package-lock.json</code> pour changer une version d&#39;une dépendance transitive, donc vous ne voyez rien côté <code>package.json</code>.</p>
<p>Donc votre <code>package-lock.json</code> de facto n&#39;est pas une simple image de votre <code>package.json</code> qui est généré et jetable sans questionnement. C&#39;est un fichier qui a une vraiment importance en termes de sécurité et de garantie de fonctionnement dans le temps.</p>
<p>Autant que possible, aujourd&#39;hui, évitez de supprimer le <code>package-lock.json</code>.</p>
<blockquote>
<p>Note : c&#39;est un peu opaque de prime abord mais si vous utilisez la fonctionnalité d&#39;installation des dépendances via IntelliJ (ou autre IDE de la suite de Jetbrains), il lancera la commande <code>npm install</code>, pas <code>npm ci</code>. J&#39;imagine qu&#39;ils ont fait ça pour éviter d&#39;avoir à tester si le package-lock.json est synchronisé avant de lancer la commande <code>npm ci</code> ou <code>npm i</code>, mais c&#39;est une erreur fondamentale de fonctionner comme ça…</p>
</blockquote>
<h2 id="article-renovate--dependabot">Renovate / Dependabot<a href="#article-renovate--dependabot" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Il existe des outils pour vous aider à maintenir vos dépendances à jour sans trop d&#39;effort, particulièrement si vous avez un bon pipeline qui s&#39;exécute sur vos MR et qui valide assez largement votre application !</p>
<p>Quelques astuces : </p>
<ul>
<li>Mettez toutes vos versions en mode exacte (ne pas mettre de <code>~</code> ou <code>^</code> avant la version) ;</li>
<li>Forcez-vous à mettre de l&#39;auto-merge sur les patchs (normalement c&#39;est censé être gratuit), sauf sur les dépendances internes à votre entreprise (j&#39;ai rarement vu une librairie interne qui suivait entièrement le SemVer et j&#39;ai toujours eu des soucis, donc dans le doute…) ;</li>
<li>définissez un rôle tournant dans votre équipe de mise à jour des dépendances (essentiellement : regarder si le pipeline passe sur les branches de Renovate / Dependabot et cliquer sur &quot;merge&quot;) ;</li>
</ul>
<blockquote>
<p>Note : si on vous bloque pour une quelconque raison l&#39;usage de Renovate / Dependabot, NPM fourni la commande <a href="https://docs.npmjs.com/cli/v11/commands/npm-outdated"><code>npm outdated</code></a> qui va vous indiquer toutes les mises à jours que vous pouvez faire. À défaut d&#39;un outil qui travail à votre place, l&#39;exécuter une fois par semaine vous permettra de rester plutôt à jour à moindre effort. Et si un jour vous trouvez <code>npm outdated</code> trop lent, vous pouvez regarder du côté de <a href="https://www.npmjs.com/package/taze"><code>taze</code></a> qui est plus rapide et permet de mettre à jour par lot les dépendances dans le <code>package.json</code>. </p>
</blockquote>
<h2 id="article-astuce--semver-calculator">Astuce : SemVer Calculator<a href="#article-astuce--semver-calculator" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Si vous avez dû mal à identifier quelles versions seront tirées pour un certain pattern, vous pouvez utiliser le <a href="https://semver.npmjs.com/">npm SemVer Calculator</a>. C&#39;est un outil en ligne fourni par NPM pour visualiser les versions compatibles avec un certain pattern.</p>
<figure>
<img src="https://anthonypena.fr/2026/04/22/reprendre-le-controle-de-vos-dependances-npm/img/semver-calculator.png" alt="SemVer Calculateur avec une démonstration sur une version de lodash" is="img-zoom"/>
<figcaption>SemVer Calculateur avec une démonstration sur une version de lodash</figcaption>
</figure>
<p>Par défaut c&#39;est <code>lodash</code> qui est pointé, mais vous pouvez cibler un autre package, vous pouvez tester n&#39;importe quel pattern de version. C&#39;est vraiment pratique pour valider un pattern très vite, et comprendre comment tout ça fonctionne par la pratique.</p>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Les dépendances avec NPM c&#39;est parfois un peu compliqué. Surtout parce qu&#39;en général on ne prend pas le temps de se projeter sur le comment ça fonctionne vraiment avant d&#39;avoir un problème et se battre avec. C&#39;est souvent un moment où on s&#39;est embourbé avec des mois de <code>--force</code> ou <code>--legacy-peer-deps</code>, où on a tout cassé et là on dit &quot;NPM c&#39;est de la m**de&quot;, alors que juste on s&#39;est loupé.</p>
<p>NPM fait partie de ses outils avec des défauts historiques mais qui ont tendances à nous laisser décider pas mal de choses et de facto demande de comprendre un minimum ce qu&#39;on fait pour que ça fonctionne dans le temps.</p>
<p>En tout cas, j&#39;espère que cet article vous aidera à mieux gérer vos dépendances NPM ! 🤓</p>
<p>Sources :</p>
<ul>
<li><a href="https://docs.npmjs.com/cli/v11/commands/npm-ls">npm ls</a></li>
<li><a href="https://docs.npmjs.com/cli/v11/commands/npm-install">npm install</a></li>
<li><a href="https://docs.npmjs.com/cli/v11/commands/npm-ci">npm ci</a></li>
<li><a href="https://docs.npmjs.com/cli/v11/commands/npm-audit">npm audit</a></li>
<li><a href="https://docs.npmjs.com/cli/v11/commands/npm-outdated">npm outdated</a></li>
<li><a href="https://semver.npmjs.com/">npm SemVer Calculator</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Un style graphique inspiré de l&#39;anime japonais Studio Ghibli, avec une ambiance chaleureuse, immersive, poétique et onirique. Une bibliothèque futuriste en bois sculpté, avec des escaliers en colimaçon, des échelles mobiles, et des étagères remplies de livres flottants. Chaque livre représente une version de package NPM (ex: <a href="mailto:%26#108;%26#x6f;%26#x64;%26#x61;%26#x73;%26#104;%26#64;%26#x34;%26#x2e;%26#49;%26#x38;%26#x2e;%26#x31;">&#108;&#x6f;&#x64;&#x61;&#x73;&#104;&#64;&#x34;&#x2e;&#49;&#x38;&#x2e;&#x31;</a>, <a href="mailto:%26#101;%26#115;%26#x62;%26#x75;%26#105;%26#x6c;%26#x64;%26#x40;%26#48;%26#x2e;%26#x32;%26#x37;%26#46;%26#x37;">&#101;&#115;&#x62;&#x75;&#105;&#x6c;&#x64;&#x40;&#48;&#x2e;&#x32;&#x37;&#46;&#x37;</a>) avec des titres lumineux et des couvertures colorées. Au centre, un grand hologramme central montre un arbre de dépendances NPM avec npm ls --all, avec des lignes lumineuses reliant les livres entre eux pour symboliser les relations entre les dépendances. En bas à droite, un panda roux anthropomorphe (style Ghibli, vêtements amples) est assis sur un tapis en tissu, un livre ouvert sur ses genoux (titre visible : &quot;SemVer pour les nuls&quot;), avec une tasse de thé fumant à côté. L&#39;arrière-plan est rempli de détails organiques : plantes grimpantes, feuilles d&#39;érable rouges/oranges/jaunes tombant doucement, et une lumière dorée tamisée évoquant un après-midi d&#39;automne. Les couleurs dominantes sont des tons doux de beige, bleu pâle, orange chaud, et des accents de vert et de doré pour les éléments technologiques et naturels. L&#39;image doit être détaillée, immersive, avec des textures riches et une atmosphère à la fois cosy et magique, mêlant technologie et nature de manière harmonieuse.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Avril 2026]]></title>
      <guid isPermaLink="false">2026/04/08/revue-de-presse-avril</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/04/08/revue-de-presse-avril/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Wed, 08 Apr 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-announcing-npmx-a-fast-modern-browser-for-the-npm-registryhttpsnpmxdevblogalpharelease"><a href="https://npmx.dev/blog/alpha-release">Announcing npmx: a fast, modern browser for the npm registry</a><a href="#article-announcing-npmx-a-fast-modern-browser-for-the-npm-registryhttpsnpmxdevblogalpharelease" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#NPM #Node.JS #Frontend</p>
<p>Annonce officielle de npmx.dev, qui est pour l&#39;instant un frontend alternatif à npmjs.com. Je dis pour l&#39;instant, car l&#39;article parle de frustration autour du CLI npm aussi donc peut-être qu&#39;ils tenteront quelque chose aussi. </p>
<p>Personnellement ça fait quelques semaines que j&#39;utilise npmx.dev en remplacement de npmjs.com au quotidien (sauf pour la partie privée de gestion de package) car :</p>
<ul>
<li>même url pour atteindre la description d&#39;un package (<a href="https://npmjs.com/package/@anthonypena/fp">https://npmjs.com/package/@anthonypena/fp</a> =&gt; <a href="https://npmx.dev/package/@anthonypena/fp">https://npmx.dev/package/@anthonypena/fp</a>) donc peu d&#39;effort là-dessus ;</li>
<li>thème light-dark automatique ;</li>
<li>Navigation dans le code propre ;</li>
<li>meilleure vision des versions ;</li>
<li>meilleure vision des dépendances ;</li>
<li>je trouve ça plus rapide (aucune métrique, juste un ressenti) ;</li>
</ul>
<p>Ce n&#39;est évidemment pas parfait (parfois des pages que je dois refresh pour que ça fonctionne, etc) mais ça me facilite la vie, donc je recommande. Surtout que ça n&#39;a aucune incidence sur vos projets ! </p>
<h3 id="article-absorbing-unknown-into-the-type-realmhttpswwwsolbergisunknowntotyped"><a href="https://www.solberg.is/unknown-to-typed">Absorbing unknown Into the Type Realm</a><a href="#article-absorbing-unknown-into-the-type-realmhttpswwwsolbergisunknowntotyped" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#TypeScript #Frontend</p>
<p>L&#39;intro donne une bonne idée du problème </p>
<blockquote>
<p>Every as in your TypeScript is a tiny lie. Sometimes a necessary one, but a lie nonetheless — you&#39;re telling the compiler &quot;trust me&quot; about data it can&#39;t verify. The question is: when can you avoid it?</p>
</blockquote>
<p>La conclusion résume assez bien l&#39;article :</p>
<blockquote>
<p>When unknown data arrives at your boundary:</p>
<ol>
<li><strong>Can you validate it?</strong> Use zod (or any schema library). This is the best option for JSON from APIs, databases, localStorage, URL params.
<strong>2. Can you narrow it?</strong> Write a type guard or assertion function. Best for discriminated unions, string literals, set membership, preconditions.</li>
<li><strong>Is it a generic boundary?</strong> One as in the utility, validation at the call site.</li>
<li><strong>Is it structural plumbing?</strong> (Proxies, generated code) Inline disable, move on.</li>
</ol>
<p>The goal isn&#39;t zero as — it&#39;s zero unexamined as. Every cast should be a conscious decision, not a reflex.</p>
</blockquote>
<p>Faut vraiment que j&#39;utilise plus Zod de mon côté ! Et je découvre better-result c&#39;est intéressant ! </p>
<h3 id="article-humanjsonhttpscodebergorgrobidahumanjson"><a href="https://codeberg.org/robida/human.json">human.json</a><a href="#article-humanjsonhttpscodebergorgrobidahumanjson" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Web #Frontend</p>
<p>L&#39;idée c&#39;est que chaque humain qui publie en ligne peut ajouter un fichier <code>human.json</code> qui a cette forme :</p>
<pre><code class="hljs language-JSON"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;version&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;0.1.1&quot;</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://example.com/~alice&quot;</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;vouches&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://bob.example.com&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-01-15&quot;</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://example.com/~charlie&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;vouched_at&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2025-11-02&quot;</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><div aria-hidden="true" class="language-tag">JSON</div>
</code></pre><p>Qui permet d&#39;indiquer qu&#39;on affirme être un humain qui écrit un site et qu&#39;on atteste que d&#39;autres sites sont rédigés par des humains. Si quelqu&#39;un d&#39;autres attestent qu&#39;on est un humain on a donc une chaîne de confiance qui se crée brique par brique. </p>
<p>Pour suivre cette chaîne de confiance :</p>
<ul>
<li>on doit indiquer dans nos pages web <code>&lt;link rel=&quot;human-json&quot; href=&quot;/path/to/human.json&quot;&gt;</code> ;</li>
<li>on peut utiliser l&#39;extension dédiée pour suivre cette chaîne de confiance avoir une indication dans son navigateur de la confiance ;</li>
</ul>
<p>J&#39;aime bien l&#39;idée même si c&#39;est purement basé sur la confiance. </p>
<h2 id="article-backend">Backend<a href="#article-backend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-evolving-the-nodejs-release-schedulehttpsnodejsorgenblogannouncementsevolvingthenodejsreleaseschedule"><a href="https://nodejs.org/en/blog/announcements/evolving-the-nodejs-release-schedule">Evolving the Node.js Release Schedule</a><a href="#article-evolving-the-nodejs-release-schedulehttpsnodejsorgenblogannouncementsevolvingthenodejsreleaseschedule" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#NodeJS #Node.JS #Backend</p>
<p>Changement historique et majeure pour l&#39;écosystème Node.js : le cycle de release va radicalement changer pour le mieux ! </p>
<p>On passe d&#39;un modèle où 2 versions majeures sortaient chaque année mais une seule considérée comme stable (exemple en 2025 : la 24 sortie en mai était stable, la 25 sortie en octobre ne l&#39;était pas) à un modèle où on aura une seule version chaque année, à date à peu près fixe (avril) et où toutes les versions deviendront stables. </p>
<figure>
<img src="https://nodejs.org/static/images/blog/announcements/2026-new-release-schedule.svg?dpl=dpl_XdcK2vFXvVGQwjrEhLjF22zubcNx" alt="Timeline de sortie des versions à partir de maintenant" is="img-zoom"/>
<figcaption>Timeline de sortie des versions à partir de maintenant</figcaption>
</figure>
<p>La version 26 est la dernière à suivre l&#39;ancien modèle (sur une LTS donc pour permettre aux utilisateurs de prendre en compte le changement en douceur), la 27 la première version à suivre le nouveau modèle.</p>
<p>Pour la version 27 :</p>
<ul>
<li>en octobre 2026, sortie en &quot;Alpha&quot; : phase de test préparation à la release ;</li>
<li>en avril 2027, sortie de la release en &quot;Current&quot; : la version sort comme les versions actuelles, on peut encore voir des mineurs et patchs mais c&#39;est pour améliorer / corriger en fonction des retours sans casser de fonctionnalité ;</li>
<li>en octobre 2027, passage en LTS (pour 30 mois) : on s&#39;assure que la version reçoit les patchs de sécurité pour garantir que les utilisateurs en productions sont tranquilles ;</li>
</ul>
<blockquote>
<p>Point utile à noter : les versions seront alignées sur l&#39;année de release, la version 27 en 2027, la version 28 en 2028, etc. </p>
</blockquote>
<p>Il va falloir prendre le pli de mettre à jour Node.js chaque année, et tester les versions Current, même Alpha si possible, pour pouvoir remonter les problèmes au plus tôt </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-how-to-kill-the-code-reviewhttpswwwlatentspacepreviewsdead"><a href="https://www.latent.space/p/reviews-dead">How to Kill the Code Review</a><a href="#article-how-to-kill-the-code-reviewhttpswwwlatentspacepreviewsdead" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA</p>
<p>Je cite le sous-titre qui résume bien l&#39;idée :</p>
<blockquote>
<p>Human-written code died in 2025. Code reviews will die in 2026.</p>
</blockquote>
<p>L&#39;article nous explique qu&#39;on tend à tuer la code review, car si on utilise un agent pour coder le produit et un autre agent pour coder les tests du produit tous les deux à partir des specs, on peut ne review que les specs, ce qu&#39;on fait déjà en tant que développeur agentique. Que de toutes façons le volume de code généré entraîne un goulet d&#39;étranglement sur la délivrabilité, du fait qu&#39;en tant qu&#39;humain on est lent à relire du code, que souvent ça incombe aux techs leads et que ça les épuise. </p>
<p>Qu&#39;il faut viser :</p>
<blockquote>
<p>The future is ship fast, observe everything, revert faster.</p>
</blockquote>
<p>Premier point : l&#39;auteur de l&#39;article est le fondateur d&#39;Aviator, qui se décrit comme &quot;multiplayer AI coding platform&quot;. Donc je cite aussi un vieil adage :</p>
<blockquote>
<p>Pendant la ruée vers l’or, ce n’est pas les chercheurs d’or qui se sont le plus enrichis, mais les vendeurs de pelles et de pioches…</p>
</blockquote>
<p>Ce que nous dit ce monsieur : ne faites plus rien vous-même, utilisez une IA pour coder le produit, une autre IA pour tester le produit, et déployer le tout avec des briques construites avec des IAs. Donc en gros &quot;donnez-moi de l&#39;argent&quot;. </p>
<p>Ensuite on nous rabâche qu&#39;avec l&#39;IA on peut aller, plus vite, plus loin, avec une meilleure qualité. Mais du coup : comme on s&#39;assure que toute l&#39;équipe comprend ce qu&#39;elle fait ? La première raison d&#39;être de la code review ce n&#39;est pas de garantir qu&#39;aucun bug n&#39;arrivera, mais de partager la connaissance dans l&#39;équipe sur comment fonctionne le produit et éviter des mauvaises pratiques. Si on enlève la code review, seul le dev qui a défini la fonctionnalité saura comment elle fonctionne (et encore vu le mouvement actuel qui dit qu&#39;on devrait ne même plus regarder le code et faire confiance aux specs…), et personne n&#39;aura regardé s&#39;il a suivi les bonnes pratique sur la définition de ses specs, les conventions, etc. Donc on va avoir plusieurs devs en roue libre qui partent chacun dans leur direction peu importe qu&#39;ils bossent sur un seul produit. Réjouissant futur à mon avis… </p>
<h3 id="article-openai-to-nearly-double-workforce-to-8000-by-end2026-ft-reports--reuterscomhttpswwwreuterscombusinessopenainearlydoubleworkforce8000byend2026ftreports20260321"><a href="https://www.reuters.com/business/openai-nearly-double-workforce-8000-by-end-2026-ft-reports-2026-03-21/">OpenAI to nearly double workforce to 8,000 by end-2026, FT reports — reuters.com</a><a href="#article-openai-to-nearly-double-workforce-to-8000-by-end2026-ft-reports--reuterscomhttpswwwreuterscombusinessopenainearlydoubleworkforce8000byend2026ftreports20260321" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #OpenAI #ChatGPT #LLM #Dev</p>
<blockquote>
<p>Artificial intelligence start-up OpenAI plans to nearly ​double its workforce to 8,000 ‌from 4,500 by the end of 2026, the Financial Times reported on Saturday, ​citing two people with knowledge of ​the matter.</p>
</blockquote>
<blockquote>
<p>OpenAI to nearly double workforce to 8,000 by end-2026, FT reports said. </p>
</blockquote>
<blockquote>
<p>The ChatGPT-maker is ​also ramping up recruitment of specialists focused on &quot;technical ambassadorship,&quot; ‌aimed ⁠at helping businesses make better use of its tools, the report added.</p>
</blockquote>
<p>Si je résume la position d&#39;OpenAI &quot;vous n&#39;avez plus besoin de dev vu notre IA fait tout mais nous on a toujours besoin de dev vu que notre IA ne fait pas tout.&quot; </p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-proton-mail-a-aide-le-fbi-a-demasquer-un-manifestant-anonyme-affilie-au-mouvement-decentralise-de-protestation--stop-cop-city-httpsdroitdeveloppezcomactu380880protonmailaaidelefbiademasquerunmanifestantanonymeaffilieaumouvementdecentralisedeprotestationstopcopcitysuscitantdenouveaudesquestionssursesgarantiesenmatieredesecurite"><a href="https://droit.developpez.com/actu/380880/Proton-Mail-a-aide-le-FBI-a-demasquer-un-manifestant-anonyme-affilie-au-mouvement-decentralise-de-protestation-Stop-Cop-City-suscitant-de-nouveau-des-questions-sur-ses-garanties-en-matiere-de-securite/">Proton Mail a aidé le FBI à démasquer un manifestant anonyme affilié au mouvement décentralisé de protestation « Stop Cop City »,</a><a href="#article-proton-mail-a-aide-le-fbi-a-demasquer-un-manifestant-anonyme-affilie-au-mouvement-decentralise-de-protestation--stop-cop-city-httpsdroitdeveloppezcomactu380880protonmailaaidelefbiademasquerunmanifestantanonymeaffilieaumouvementdecentralisedeprotestationstopcopcitysuscitantdenouveaudesquestionssursesgarantiesenmatieredesecurite" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Communication #Vie-privée #Sécurité</p>
<p>Si on regarde dans le détail, on est obligé d&#39;admettre que quand bien même Proton tente de minimiser les données qu&#39;ils possèdent sur leurs utilisateurs, ils ont aussi des contraintes légales pour certaines données (comme les coordonnées de paiement). Proton garanti la sécurité des communications pas l&#39;anonymat des utilisateurs. </p>
<p>Il faut aussi rappeler que si Proton ne se conformait pas un minimum aux requêtes judiciaires de l&#39;État Suisse, ce serait eux qui seraient sur le banc des accusés et donc leur mission serait remise en cause 😅 </p>
<h3 id="article-android-developer-verification-balancing-openness-and-choice-with-safetyhttpsandroiddevelopersgoogleblogcom202603androiddeveloperverificationhtmlm1"><a href="https://android-developers.googleblog.com/2026/03/android-developer-verification.html?m%3D1">Android developer verification: Balancing openness and choice with safety</a><a href="#article-android-developer-verification-balancing-openness-and-choice-with-safetyhttpsandroiddevelopersgoogleblogcom202603androiddeveloperverificationhtmlm1" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Android #Google #Sécurité</p>
<p>Je cite la démarche :</p>
<blockquote>
<p>How the advanced flow works for users</p>
<ul>
<li>Enable developer mode in system settings: Activating this is simple. This prevents accidental triggers or &quot;one-tap&quot; bypasses often used in high-pressure scams.</li>
<li>Confirm you aren&#39;t being coached: There is a quick check to make sure that no one is talking you into turning off your security. While power users know how to vet apps, scammers often pressure victims into disabling protections.</li>
<li>Restart your phone and reauthenticate: This cuts off any remote access or active phone calls a scammer might be using to watch what you’re doing.</li>
<li>Come back after the protective waiting period and verify: There is a one-time, one-day wait and then you can confirm that this is really you who’s making this change with our biometric authentication (fingerprint or face unlock) or device PIN. Scammers rely on manufactured urgency, so this breaks their spell and gives you time to think.</li>
<li>Install apps: Once you confirm you understand the risks, you’re all set to install apps from unverified developers, with the option of enabling for 7 days or indefinitely. For safety, you’ll still see a warning that the app is from an unverified developer, but you can just tap “Install Anyway.”</li>
</ul>
</blockquote>
<p>Ça peut sembler facile et pas si bloquant mais pensez à un truc simple : j&#39;utilise des apps au quotidien que j&#39;installe via <a href="https://f-droid.org/">f-droid</a>, certaines pas du tout présentes sur le Play Store, donc le jour où je vais changer de téléphone, je devrais faire la manip au-dessus, attendre 24h, et là je pourrais commencer à utiliser mon téléphone (que j&#39;ai payé, qui m&#39;appartient, dont je suis censé disposer librement sans condition, sans avoir à demander de permission) normalement. Pas pour des limitations techniques, parce que Google aura décidé que c&#39;est mieux pour mon bien. </p>
<p>Franchement tout jusqu&#39;au dernier point, je peux comprendre, ça peut sûrement éviter des arnaques de personnes en illectronisme. Le dernier point est 100% abusif à mon sens. </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-a-website-to-destroy-all-websiteshttpshenrycodeswritingawebsitetodestroyallwebsites"><a href="https://henry.codes/writing/a-website-to-destroy-all-websites/">A website to destroy all websites.</a><a href="#article-a-website-to-destroy-all-websiteshttpshenrycodeswritingawebsitetodestroyallwebsites" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Web #Internet</p>
<p>Cet article est une ode à un retour à un Internet plus humain. Les parallèles sont intéressants, et franchement je suis d&#39;accord avec l&#39;auteur, pour retrouver un Internet plus humain, il suffit qu&#39;on lâche les gros acteurs pour revenir à la base : publier nos propres sites, simple, imparfait mais humain. </p>
<p>Article qui vaut la peine d&#39;être lu à mon sens (et je voulais vraiment le lire depuis la revue de presse de l&#39;ami <a href="https://ehret.me/2026/02/nflm-developer/?ref%3Drss">Siegfried</a> de février… ). Sous certains aspects il me fait d&#39;ailleurs penser au discours d&#39;Edward Snowden dans <em>Mémoire Vives</em>, sa découverte d&#39;Internet, tout ce qu&#39;il a appris et tout le temps passé à échanger avec des inconnus (mais pas si inconnu à force d&#39;échange à travers un écran). </p>
<h3 id="article-two-years-of-emacs-solo-35-modules-zero-external-packages-and-a-full-refactorhttpswwwrahuljuliatocompostsemacssolotwoyears"><a href="https://www.rahuljuliato.com/posts/emacs-solo-two-years">Two Years of Emacs Solo: 35 Modules, Zero External Packages, and a Full Refactor</a><a href="#article-two-years-of-emacs-solo-35-modules-zero-external-packages-and-a-full-refactorhttpswwwrahuljuliatocompostsemacssolotwoyears" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Emacs</p>
<p>Je suis depuis longtemps aussi attiré que repoussé par Emacs. Je fais un peu de vim au quotidien (surtout via git d&#39;ailleurs). Mais Emacs est pour moi beaucoup plus puissant et permet beaucoup plus de chose. </p>
<p>J&#39;ai toujours pensé que pour avoir un environnement développement proche d&#39;un IDE (ou même d&#39;un éditeur de texte ++ comme VSCode) il fallait empiler des packages à foison, ce qui m&#39;a toujours embêté. Pourquoi ? C&#39;est compliqué à maintenir et c&#39;est lent (là où ce qui m&#39;intéresse dans vim ou Emacs c&#39;est la légèreté, la simplicité et la vitesse) </p>
<p>Ici c&#39;est l&#39;auteur de &quot;emacs-solo&quot;, une configuration d&#39;Emacs sans aucune dépendance, super modulaire, sans package à télécharger, juste quelques fichiers lisp à copier. Et franchement ça a l&#39;air de vraiment bien marcher ! Ça donne envie de tester ! </p>
<h3 id="article-wifi-trop-faible--sortez-votre-ancien-smartphone-android-du-tiroir-et-transformezle-en-repeteurhttpswwwlesnumeriquescomtelephoneportablewifitropfaiblesortezvotreanciensmartphoneandroiddutiroirettransformezleenrepeteurn253258html"><a href="https://www.lesnumeriques.com/telephone-portable/wifi-trop-faible-sortez-votre-ancien-smartphone-android-du-tiroir-et-transformez-le-en-repeteur-n253258.html">WiFi trop faible ? Sortez votre ancien smartphone Android du tiroir et transformez-le en répéteur</a><a href="#article-wifi-trop-faible--sortez-votre-ancien-smartphone-android-du-tiroir-et-transformezle-en-repeteurhttpswwwlesnumeriquescomtelephoneportablewifitropfaiblesortezvotreanciensmartphoneandroiddutiroirettransformezleenrepeteurn253258html" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Wifi #Android #Smartphone</p>
<p>J&#39;avoue, j&#39;avais jamais pensé à utiliser un ancien smartphone comme ça 😅 </p>
<p>Mais : </p>
<ul>
<li>il faut un smartphone pas trop ancien pour supporter d&#39;être à la fois à émettre un réseau wifi et de connecter à un autre (il faut qu&#39;il soit dual band) ;</li>
<li>s&#39;il est trop peu perf ça va être lent à cause de lui pas à cause de la portée wifi ;</li>
<li>je pense que ça consomme plus d&#39;électricité qu&#39;un répéteur / routeur wifi (j&#39;ai pas mesuré, donc c&#39;est du pif) ; </li>
<li>ce sera sûrement moins stable (sur des sessions un peu longues de partage de connexion, je trouve que je perds en stabilité parce que mon téléphone chauffe un peu, et j&#39;ai toujours constaté ça) ;</li>
</ul>
<p>Mais, ça veut pas dire que ça vaut pas le coup de tenter, même en tant que solution temporaire, surtout si on a un smartphone dans un tiroir qui dort : ça ne vous coûtera pas grand-chose de tester. Et au pire si c&#39;est moins stable. Il sera toujours temps d&#39;investir dans un répéteur wifi plus tard ! </p>
<h3 id="article-datashield--la-blocklist-qui-vire-les-ips-pourrieshttpskorbeninfodatashieldipv4blocklisthtml"><a href="https://korben.info/data-shield-ipv4-blocklist.html">Data-Shield - La blocklist qui vire les IPs pourries</a><a href="#article-datashield--la-blocklist-qui-vire-les-ips-pourrieshttpskorbeninfodatashieldipv4blocklisthtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Réseau #Firewall #Open-Source</p>
<blockquote>
<p>Hé bien c&#39;est exactement ce que fait Data-Shield IPv4 Blocklist , un projet open source qui maintient une liste d&#39;environ 100 000 adresses IP identifiées comme malveillantes. Le principe est simple… on colle l&#39;URL RAW de la liste dans la config de son firewall (genre dans les alias d&#39;OPNsense ou les External Block Lists de Fortinet) et hop, tout ce beau monde est filtré au niveau périmétrique. La liste (un simple fichier texte avec une IP par ligne) est rafraîchie toutes les 6 heures avec une fenêtre de rétention de 15 jours, du coup les IPs qui ne sont plus actives finissent par sortir automatiquement.</p>
</blockquote>
<p>Franchement un super travail de maintenir une liste comme ça ! Il faudrait vraiment que je commence à utiliser une liste comme au niveau firewall 😅 </p>
<h3 id="article-la-france-rachete-a-atos-lentreprise-bull-fleuron-trop-longtemps-en-souffrance-des-supercalculateurshttpswwwclubiccomactualite607144lafranceracheteaatoslentreprisebullfleurontroplongtempsensouffrancedessupercalculateurshtml"><a href="https://www.clubic.com/actualite-607144-la-france-rachete-a-atos-l-entreprise-bull-fleuron-trop-longtemps-en-souffrance-des-supercalculateurs.html">La France rachète à Atos l&#39;entreprise Bull, fleuron trop longtemps en souffrance des supercalculateurs</a><a href="#article-la-france-rachete-a-atos-lentreprise-bull-fleuron-trop-longtemps-en-souffrance-des-supercalculateurshttpswwwclubiccomactualite607144lafranceracheteaatoslentreprisebullfleurontroplongtempsensouffrancedessupercalculateurshtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#France #Bull #Supercalculateur #Atos</p>
<blockquote>
<p>L&#39;État français a finalisé ce 31 mars 2026 le rachat de Bull, spécialiste du calcul haute performance et de l&#39;IA, pour une valeur pouvant atteindre 404 millions d&#39;euros. L&#39;acquisition d&#39;une entreprise historique.</p>
</blockquote>
<p>Je trouve ça assez faible sachant que l&#39;entreprise a généré &quot;un chiffre d&#39;affaires de 720 millions d&#39;euros en 2025.&quot;. Après c&#39;est peut-être une astuce financière pour protéger d&#39;entreprise. </p>
<p>J&#39;y apprends d&#39;autres choses intéressantes au passage :</p>
<blockquote>
<p>L&#39;usine d&#39;Angers est la seule en Europe capable de fabriquer des supercalculateurs, ces machines colossales qui traitent des milliards d&#39;opérations par seconde et qui sont devenues indispensables pour entraîner les grands modèles d&#39;intelligence artificielle, simuler des scénarios militaires ou faire avancer la recherche scientifique. Cerise sur le gâteau, elles sont reconnues pour leur sobriété énergétique, un critère de plus en plus décisif à l&#39;heure où faire tourner une IA coûte une énergie considérable.</p>
</blockquote>
<p>Une usine de super calculateur à Angers 😮 </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Créer une vue calendrier minimaliste avec du HTML et du CSS]]></title>
      <guid isPermaLink="false">2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css</guid>
      <description><![CDATA[<p>Si vous allez sur un profil Github (par exemple : le miens), vous verrez quelque chose qui ressemble…</p>
]]></description>
      <link>https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/index.html</link>
      <category><![CDATA[Frontend]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[CSS]]></category>
      <pubDate>Tue, 31 Mar 2026 05:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Si vous allez sur un profil Github (par exemple : <a href="https://github.com/kuroidoruido">le miens</a>), vous verrez quelque chose qui ressemble à ça :</p>
<figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/github-contributions.png" alt="Contributions Github" is="img-zoom"/>
<figcaption>Contributions Github</figcaption>
</figure>
<p>Pour plein de raisons j&#39;aime bien et pas trop cette vue. Et j&#39;avais envie d&#39;avoir quelque chose de similaire sur mon blog… Je vous explique !</p>
<p>Tout ce que je vous montre ici est disponible ici :</p>
<ul>
<li><a href="https://kuroidoruido.github.io/css-is-magic/minimalist-calendar-view/index.html">Démonstration interactive</a></li>
<li><a href="https://github.com/kuroidoruido/css-is-magic/blob/main/minimalist-calendar-view/">Code source de la démo</a></li>
</ul>
<h2 id="article-ce-que-jaime-et-aime-moins-dans-la-vue-contribution-de-github">Ce que j&#39;aime et aime moins dans la vue contribution de Github<a href="#article-ce-que-jaime-et-aime-moins-dans-la-vue-contribution-de-github" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ce qui fait la popularité de cette vue c&#39;est que ça permet à des gens de montrer qu&#39;ils travaillent plus que tout le monde… J&#39;aime pas trop ça… Ce que ça montre c&#39;est votre activité, en grande partie basé sur votre volume de commit, ce qui ne veut rien dire ni de votre activité réelle, ni de votre apport aux projets, ni rien en fait, juste vous savez faire des <code>git commit -m &quot;truc&quot; --allow-empty</code>…</p>
<p>Par contre j&#39;aime bien ce genre de graphique avec un côté prise de recul car ça permet d&#39;avoir une vue d&#39;ensemble d&#39;une période assez longue (sur ma capture d&#39;écran les 12 derniers mois, mais ça peut être aussi les 12 mois d&#39;une année), sans prendre trop de place et si on sait qu&#39;on ne triche pas sur l&#39;activité qu&#39;on a, de voir quand on a été moins bon, et peut-être prendre du recul là-dessus pour comprendre pourquoi, ensuite au choix faire en sorte de pouvoir être actif plus souvent parce que ça nous manquait à cette période, ou à l&#39;inverse réduire son activité pour être mieux (ça c&#39;est vous qui voyez).</p>
<p>Globalement, j&#39;aime vraiment la vue d&#39;ensemble que ça apporte qui donne une info en un coup d&#39;œil ! Et c&#39;est ça que j&#39;aimerai avoir sur mon blog !</p>
<p>J&#39;aimerai une vue très simple, beaucoup plus minimaliste que ce que fait Github, avec les couleurs du blog, sur chaque page archives (une page archive présente tous les articles d&#39;une année), pour naviguer visuellement dans l&#39;année.</p>
<h2 id="article-lets-go-html">Let&#39;s go HTML!<a href="#article-lets-go-html" class="anchor" aria-label="permalink">🔗</a></h2>
<p><a href="/2026/01/15/nouveau-blog-partie-1-html/">Mon blog est généré statiquement</a> donc je veux une solution purement HTML et CSS. Je passe sur la manière dont je mouline mon modèle interne pour générer le HTML, mais voici le résultat :</p>
<pre><code class="hljs language-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;overview&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-previous-year</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2025-12-29&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Monday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-previous-year</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2025-12-30&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Tuesday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-previous-year</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2025-12-31&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Wednesday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-01&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Thursday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-02&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Friday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-03&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Saturday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-04&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-comment">&lt;!-- Sunday --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-05&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-01-06&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;#2026/01/06/revue-de-presse-janvier&quot;</span> <span class="hljs-attr">title</span>=<span class="hljs-string">&quot;Revue de presse - Janvier 2026&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ...
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-03-17&quot;</span> <span class="hljs-attr">data-today</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;2026-03-18&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ...
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span><div aria-hidden="true" class="language-tag">HTML</div>
</code></pre><blockquote>
<p>Note : j&#39;ai ajouté les jours de la semaine sur la première semaine pour aider à comprendre.</p>
</blockquote>
<p>Je veux une grille donc j&#39;ai choisi de faire une liste non ordonnée (<code>&lt;ul&gt;</code>) ! What!? 🧐</p>
<p>Ça peut vous surprendre mais oui j&#39;ai choisi de faire une liste et pas un tableau. Pourquoi ? Un tableau c&#39;est beaucoup plus difficile à styliser graphiquement, et ça demande beaucoup plus d&#39;effort à produire en termes de HTML. Si j&#39;avais choisi de le faire sous la forme d&#39;un <code>&lt;table&gt;</code> j&#39;aurai dû penser le positionnement des dates dès la génération du HTML par exemple…</p>
<p>Vous noterez aussi que j&#39;ai mis un <code>aria-hidden=&quot;true&quot;</code> sur la liste. En effet j&#39;ai <em>choisi</em> d&#39;exclure cet élément des outils d&#39;accessibilité types lecteurs d&#39;écran. La première raison est que ça n&#39;aurait rien apporté : j&#39;aurais sur ma page une liste de date avec pour chaque s&#39;il y a un article, puis la liste directe des articles… Je dois aussi admettre que je n&#39;avais aucune idée de comment rendre tout ça accessible… Je n&#39;ai pas encore fait le travaille d&#39;auditer l&#39;accessibilité de mon blog avec des outils, je m&#39;en mordrais peut-être les doigts ce jour-là et si c&#39;est le cas j&#39;en reparlerais !</p>
<p>Dans cette liste on peut voir une série de <code>&lt;li&gt;</code> avec chacun un attribut <code>data-date=&quot;yyyy-MM-dd&quot;</code>, c&#39;est simple mais ça fonctionne et vous allez voir que ça va nous servir plus tard ! </p>
<p>On notera que les premiers ont l&#39;attribut <code>data-previous-year=&quot;true&quot;</code>, car comme le nom de l&#39;attribut l&#39;indique : il s&#39;agit des derniers jours de l&#39;année précédente. Pourquoi ? Parce que je veux mettre les jours en colonne par semaine, et que la première semaine de l&#39;année ne commence pas forcément un lundi (ou un dimanche), et que pourtant les derniers jours de l&#39;année sont considérés comme faisant partie de la semaine 1 de l&#39;année suivante (j&#39;imagine pour n&#39;avoir que des semaines complètes).</p>
<p>La date du jour est indiqué aussi avec un attribut spécifique <code>data-today=&quot;true&quot;</code>. Vous verrez que ça nous servira plus tard aussi !</p>
<blockquote>
<p>Note : vous pouvez noter aussi que tous mes attributs personnalisés (et donc non standards) sont préfixés avec <code>data-</code>, sans ça fonctionne mais ce n&#39;est pas du HTML valide, qui oblige à avoir un préfixe <code>data-</code>, l&#39;intérêt de ça c&#39;est aussi que jamais vous n&#39;aurez de conflit avec une éventuelle évolution de la spécification HTML.</p>
</blockquote>
<p>Les dates où j&#39;ai publié un article, dans l&#39;élément <code>&lt;li&gt;</code> on retrouve un lien qui n&#39;a pas de texte (car je n&#39;en ai pas besoin), mais qui a une ancre comme URL et un title. Le title pour commencer indique simplement le nom de l&#39;article, ce qui permet de l&#39;afficher au survol (comportement natif du navigateur). L&#39;ancre c&#39;est moins habituel quand on ne construit pas de site web (par opposition aux logiciels de gestions / web app) : au clic sur un lien ancre, l&#39;URL va changer pour faire apparaitre l&#39;ancre (sans chargement / navigation), et si l&#39;ancre correspond à un élément de la page (comprendre : si l&#39;ancre a la même valeur que l&#39;attribut <code>id</code> d&#39;un élément de la page), le navigateur va scroll jusqu&#39;à cet élément et l&#39;indiquer comme &quot;focus&quot;. On s&#39;en servira plus tard là aussi !</p>
<p>Et visuellement ça donne ça :</p>
<figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/initial-screen.png" alt="Vue de la page avec uniquement les puces de la liste visible" is="img-zoom"/>
<figcaption>Vue de la page avec uniquement les puces de la liste visible</figcaption>
</figure>
<p>Ça fait rêver hein ? Non ? 🤡</p>
<h2 id="article-note-sur-le-theme">Note sur le thème<a href="#article-note-sur-le-theme" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Quitte à faire les choses biens, je vais faire une vue qui fonctionne bien en thème clair et sombre. Et je veux faire les choses proprement, donc je vais utiliser des variables CSS.</p>
<p>Je vous donne les variables de thème que je vais utiliser :</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-pseudo">:root</span> {
  <span class="hljs-comment">/* ATOMS */</span>
  <span class="hljs-attr">--color--white</span>: <span class="hljs-number">#ffffff</span>;
  <span class="hljs-attr">--color--black</span>: <span class="hljs-number">#121212</span>;
  <span class="hljs-attr">--color--dark-gray</span>: <span class="hljs-number">#333333</span>;
  <span class="hljs-attr">--color--gray</span>: <span class="hljs-number">#6c757d</span>;
  <span class="hljs-attr">--color--light-gray</span>: <span class="hljs-number">#e0e0e0</span>;
  <span class="hljs-attr">--color--blue</span>: <span class="hljs-number">#007bff</span>;
  <span class="hljs-attr">--color--green</span>: <span class="hljs-number">#28a745</span>;
  <span class="hljs-attr">--size--quarter</span>: <span class="hljs-number">0.125rem</span>;
  <span class="hljs-attr">--size--half</span>: <span class="hljs-number">0.25rem</span>;
  <span class="hljs-attr">--size--1</span>: <span class="hljs-number">0.5rem</span>;
  <span class="hljs-attr">--size--2</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attr">--size--3</span>: <span class="hljs-number">1.5rem</span>;
  <span class="hljs-attr">--size--4</span>: <span class="hljs-number">2rem</span>;
  <span class="hljs-attr">--size--5</span>: <span class="hljs-number">4rem</span>;

  <span class="hljs-comment">/* MOLECULES */</span>
  <span class="hljs-attr">--color--bg</span>: <span class="hljs-built_in">light-dark</span>(<span class="hljs-built_in">var</span>(--color--white), <span class="hljs-built_in">var</span>(--color--black));
  <span class="hljs-attr">--color--text</span>: <span class="hljs-built_in">light-dark</span>(<span class="hljs-built_in">var</span>(--color--dark-gray), <span class="hljs-built_in">var</span>(--color--light-gray));
  <span class="hljs-attr">--color--primary</span>: <span class="hljs-built_in">var</span>(--color--blue);
  <span class="hljs-attr">--color--secondary</span>: <span class="hljs-built_in">var</span>(--color--gray);
  <span class="hljs-attr">--color--accent</span>: <span class="hljs-built_in">var</span>(--color--green);
  <span class="hljs-attr">--main-text--max-width</span>: <span class="hljs-number">100ch</span>;
  <span class="hljs-attr">--reponsive-main-text-max-width</span>: <span class="hljs-built_in">min</span>(
    <span class="hljs-number">100</span>dvw,
    <span class="hljs-built_in">min</span>(<span class="hljs-number">100vw</span>, <span class="hljs-built_in">var</span>(--main-text--max-width))
  );
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><p>Il n&#39;y a pas de magie, c&#39;est le thème de mon blog (avec quelques variables en moins dont je n&#39;aurai pas du tout besoin). Pour plus de détail sur comment tout ça fonctionne, je vous renvoie vers <a href="/2026/01/21/nouveau-blog-partie-2-css/">mon article sur le style de mon blog</a>.</p>
<p>J&#39;en profite aussi pour rappeler que pour avoir proprement deux thèmes sur votre site, il suffit d&#39;avoir <code>&lt;meta name=&quot;color-scheme&quot; content=&quot;light dark&quot;&gt;</code> dans le <code>&lt;head&gt;</code> de votre page.</p>
<h2 id="article-dune-liste-a-une-grille">D&#39;une liste à une grille<a href="#article-dune-liste-a-une-grille" class="anchor" aria-label="permalink">🔗</a></h2>
<p>L&#39;idée de base c&#39;est d&#39;aligner tous les éléments en colonne, sept par sept jusqu&#39;à les avoir tous mis. De cette façon, la première colonne représente la semaine 1 de l&#39;année, la seconde colonne la semaine 2 et ainsi de suite. Donc on veut une grille qui aura 7 lignes et entre 52 et 54 colonnes. Dans un premier temps : restons sur 53 semaines (le cas le plus courant).</p>
<p>Pour faire ça c&#39;est simple, on va utiliser un <code>display: grid</code> associé à <code>grid-template-columns: repeat(53, var(--overview--border-width))</code> pour avoir 53 colonnes, <code>grid-template-rows: repeat(7, var(--overview--border-width))</code> pour avoir 7 lignes et <code>grid-auto-flow: column</code> pour lui dire de remplir colonne par colonne (par défaut, le layout grid remplit ligne à ligne).</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-attr">--overview--day-width</span>: <span class="hljs-built_in">var</span>(--size--<span class="hljs-number">1</span>);

    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-attribute">display</span>: grid;
        <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">53</span>, <span class="hljs-built_in">var</span>(--overview--day-width));
        <span class="hljs-attribute">grid-template-rows</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">7</span>, <span class="hljs-built_in">var</span>(--overview--day-width));
        <span class="hljs-attribute">grid-auto-flow</span>: column;
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><p>Notre vue est tout de suite plus compacte !</p>
<figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-no-style.png" alt="Vue avec juste la définition de la grille" is="img-zoom"/>
<figcaption>Vue avec juste la définition de la grille</figcaption>
</figure>
<p>Je ne veux pas un point pour chaque jour, je veux des cercles, avec une bordure fine. Donc pour ça j&#39;ajoute un peu de style sur les <code>&lt;li&gt;</code> :</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-attr">--overview--month-border-color</span>: <span class="hljs-built_in">var</span>(--color--secondary);
    <span class="hljs-attr">--overview--day-width</span>: <span class="hljs-built_in">var</span>(--size--<span class="hljs-number">1</span>);
    <span class="hljs-attr">--overview--day-border-radius</span>: <span class="hljs-built_in">calc</span>(<span class="hljs-built_in">var</span>(--overview--day-width) / <span class="hljs-number">2</span>);

    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-selector-tag">li</span> {
            <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-built_in">var</span>(--overview--month-border-color);
            <span class="hljs-attribute">border-radius</span>: <span class="hljs-built_in">var</span>(--overview--day-border-radius);
            <span class="hljs-attribute">width</span>: <span class="hljs-built_in">var</span>(--overview--day-width);
            <span class="hljs-attribute">height</span>: <span class="hljs-built_in">var</span>(--overview--day-width);
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-with-dots.png" alt="Vue avec les jours en forme de cercle" is="img-zoom"/>
<figcaption>Vue avec les jours en forme de cercle</figcaption>
</figure>
<p>C&#39;est un peu mieux, mais il y a toujours les puces des différents <code>&lt;li&gt;</code> et on a aussi le padding-left natif des listes (c&#39;est ça qui permet à la fois de laisser de la place pour les puces et que les listes soient de base un peu indentée par rapport au reste du texte). Corrigeons ça ! Et au passage on va ajouter un peu d&#39;espace entre les cercles pour que ce ne soit plus tout tassé !</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-attr">--overview--padding</span>: <span class="hljs-built_in">var</span>(--size--half);

    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-attribute">list-style-type</span>: none;
        <span class="hljs-attribute">gap</span>: <span class="hljs-number">1px</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-built_in">var</span>(--overview--padding);
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-white.png" alt="Grille minimaliste sans aucune indication" is="img-zoom"/>
<figcaption>Grille minimaliste sans aucune indication</figcaption>
</figure>
<p>On a notre grille propre. Il ne reste plus qu&#39;à mettre en avant les éléments :</p>
<ul>
<li>masquer les jours de l&#39;année précédente en effaçant la bordure les <code>&lt;li&gt;</code> avec l&#39;attribut <code>data-previous-year</code> ;</li>
<li>ajouter un fond pour les <code>&lt;li&gt;</code> qui contiennent un élément <code>&lt;a&gt;</code> (pour mettre en évidence les jours avec un article) ;</li>
<li>ajouter une bordure colorée pour la date du jour (les <code>&lt;li&gt;</code> qui ont l&#39;attribut <code>data-today</code>) ;</li>
</ul>
<p>Pour faire tout ça on va utiliser des sélecteurs sur attribut (<code>li[data-today]</code> par exemple) et le pseudo-sélecteur <code>:has()</code> (<code>:has(a)</code> par exemple).</p>
<p>Je vais aussi en profiter pour faire en sorte que le lien ancre vers l&#39;article prenne toute la place dans le cercle, ça va permettre de cliquer n&#39;importe où dans le cercle pour accéder à l&#39;ancre.</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-attr">--overview--today-border-color</span>: <span class="hljs-built_in">var</span>(--color--accent);
    <span class="hljs-attr">--overview--with-article-color</span>: <span class="hljs-built_in">var</span>(--color--primary);

    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-selector-tag">li</span> {
            &amp;<span class="hljs-selector-attr">[data-previous-year]</span> {
                <span class="hljs-attribute">border</span>: none;
            }

            &amp;<span class="hljs-selector-attr">[data-today]</span> {
                <span class="hljs-attribute">border-color</span>: <span class="hljs-built_in">var</span>(--overview--today-border-color);
                <span class="hljs-attribute">border-width</span>: <span class="hljs-number">2px</span>;
            }

            &amp;<span class="hljs-selector-pseudo">:has</span>(<span class="hljs-selector-tag">a</span>) {
                <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">var</span>(--overview--with-article-color);
                <span class="hljs-selector-tag">a</span> {
                    <span class="hljs-attribute">display</span>: block;
                    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
                    <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
                }
            }
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-with-color.png" alt="Vue de la grille en mettant en évidence les éléments intéressants" is="img-zoom"/>
<figcaption>Vue de la grille en mettant en évidence les éléments intéressants</figcaption>
</figure>
<p>On peut encore faire mieux ! </p>
<p>Et si on colorait différemment la bordure des mois pair ? Sans ajouter quoi que ce soit au HTML évidemment ! On va utiliser un sélecteur d&#39;attribut qui se base sur sa valeur : <code>li[data-date*=&quot;-02-&quot;]</code> signifie &quot;tous les <code>&lt;li&gt;</code> qui ont l&#39;attribut <code>data-date</code> avec une valeur contenant (<code>*=</code>) la chaîne de caractère <code>-02-</code>&quot;, autrement dit pour nous &quot;tous les <code>&lt;li&gt;</code> de février. Et donc il suffit de faire pareil pour les autres mois. </p>
<p>On va aussi utiliser une fonctionnalité récente de CSS : les couleurs relatives. L&#39;idée c&#39;est de pouvoir prendre la valeur d&#39;une couleur et changer juste une partie des valeurs, dans mon cas je vais prendre la couleur <code>--overview--month-border-color</code> et réduire de 30% son opacité en passant le canal alpha à 0.7, ça permet que la couleur s&#39;adapte au thème automatiquement sans me casser la tête.</p>
<p>Au passage je renomme <code>--overview--month-border-color</code> en <code>--overview--odd-month-border-color</code> pour être plus logique.</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-attr">--overview--odd-month-border-color</span>: <span class="hljs-built_in">var</span>(--color--secondary);
    <span class="hljs-attr">--overview--even-month-border-color</span>: <span class="hljs-built_in">rgb</span>(from <span class="hljs-built_in">var</span>(--overview--odd-month-border-color) r g b / <span class="hljs-number">0.7</span>);

    <span class="hljs-selector-tag">ul</span> {

        <span class="hljs-selector-tag">li</span> {
            <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-built_in">var</span>(--overview--odd-month-border-color);

            &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-02-&quot;</span>]</span>, &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-04-&quot;</span>]</span>,
            &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-06-&quot;</span>]</span>, &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-08-&quot;</span>]</span>,
            &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-10-&quot;</span>]</span>, &amp;<span class="hljs-selector-attr">[data-date*=<span class="hljs-string">&quot;-12-&quot;</span>]</span> {
                <span class="hljs-attribute">border-color</span>: <span class="hljs-built_in">var</span>(--overview--even-month-border-color);
            }
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-with-months.png" alt="Avec les mois en évidence" is="img-zoom"/>
<figcaption>Avec les mois en évidence</figcaption>
</figure>
<p>Comme on connaît la date du jour, on pourrait aussi rendre moins visible les jours des dates dans le futur. Toujours sans rien ajouter au HTML évidemment. Facile avec le combinateur &quot;frère suivant&quot; (Subsequent-sibling Combinator en anglais) : <code>li[data-today] ~ li</code> va indiquer qu&#39;on veut sélectionner tous les <code>&lt;li&gt;</code> qui suivent un <code>&lt;li data-today&gt;</code>.</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-selector-tag">li</span><span class="hljs-selector-attr">[data-today]</span> ~ <span class="hljs-selector-tag">li</span> {
            <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.5</span>;
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/grid-futur-dates.png" alt="Vue avec les dates futures identifiées" is="img-zoom"/>
<figcaption>Vue avec les dates futures identifiées</figcaption>
</figure>
<p>Facile non ?</p>
<h2 id="article-52-a-54-semaines-par-an">52 à 54 semaines par an…<a href="#article-52-a-54-semaines-par-an" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Il manque un dernier truc : comment on gère le fait d&#39;avoir entre 52 et 54 semaines ? Et dans quels cas ça arrive ?</p>
<p>Je vous ai mis un article qui détaille tout ça dans les sources mais pour résumé : je suis français, je suis donc dans une zone qui fonctionne en ISO 8601, donc je vais me baser là-dessus (en Amérique du Nord ce serait différent par exemple).</p>
<p>Pour faire un résumé grossier : </p>
<ul>
<li>mathématiquement : une année c&#39;est 52 semaines (7 jours x 52 semaines = 364 jours) + 1 à 2 jours (2j si c&#39;est une année bissextile) ;</li>
<li>mais comme les années ne sont pas sur un nombre de jour divisible par 7, les jours de la première semaine de l&#39;année se décale d&#39;année en année et la dernière semaine de l&#39;année est souvent la même semaine que la première de l&#39;année suivante ;</li>
<li>la règle est simple : si le 1er janvier tombe entre le lundi et jeudi inclus, les derniers jours de l&#39;année N-1 et les premiers de l&#39;année N sont comptés comme la semaine 1, si le 1er janvier tombe entre le vendredi et le dimanche inclus, ces mêmes jours sont la dernière semaine de l&#39;année N-1 (donc semaine 53) ;</li>
<li>en cas d&#39;année bissextile où le 1er janvier est un dimanche (dernier jour de la semaine en ISO), alors le 31 décembre sera un lundi (premier jour de la semaine en ISO), on aura donc 54 semaines à afficher ;</li>
</ul>
<blockquote>
<p>Note : je vous laisse regarder plus en détail le site que j&#39;ai mis en source, mais il n&#39;y a qu&#39;en notation américaine qu&#39;on aura une semaine numérotée 54, pas en calendrier ISO.</p>
</blockquote>
<p>Bon et du coup, pour nous on fait comment ? On fait des calculs savants pour gérer ça ? 🤔</p>
<p>Plus simple : on se pose pour voir le problème autrement et on laisse CSS se débrouiller. 😇</p>
<p>Le cas 52 semaines à afficher n&#39;arrivera jamais à cause du nombre de jour dans l&#39;année, sur une année de 365 jours, les cas les plus extrêmes ce sera 52 semaines pleines et une journée toute seule soit au début (comme 2026, le 1er janvier est un dimanche, tout seul sur sa semaine) soit à la fin (comme en 2028, où le 1er janvier est un lundi, et le 31 décembre un lundi aussi). 53 semaines sera notre cas par défaut le plus courant. </p>
<p>Et de temps en temps, on aura une 54ème semaine qui va apparaitre. Quand on aura 366 jours dans l&#39;année uniquement, et dans le cas où le premier jour de l&#39;année et le dernier jours de l&#39;année sont seuls sur leur semaine. En d&#39;autres mots : on aura 366 jours affichés + 6 jours de l&#39;année précédente qui sont masqués mais sont là pour l&#39;alignement ; donc on aura 54 semaines si on a 372 <code>&lt;li&gt;</code> dans notre liste <code>&lt;ul&gt;</code>, et ça c&#39;est facile à gérer en CSS !</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#overview</span> {
    <span class="hljs-selector-tag">ul</span> {
        &amp;<span class="hljs-selector-pseudo">:has</span>(<span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:nth-child</span>(<span class="hljs-number">372</span>)) {
            <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">54</span>, <span class="hljs-built_in">var</span>(--overview--day-width));
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><h2 id="article-mettre-en-avant-lelement-selectionne">Mettre en avant l&#39;élément sélectionné<a href="#article-mettre-en-avant-lelement-selectionne" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je l&#39;expliquais un peu plus haut : quand on clique sur un de mes liens dans la vue calendrier, on va créer une ancre dans l&#39;URL :</p>
<figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/url-with-anchor.png" alt="Ancre vue dans la barre d&#39;URL" is="img-zoom"/>
<figcaption>Ancre vue dans la barre d&#39;URL</figcaption>
</figure>
<p>Eh bien en CSS l&#39;élément qui possède l&#39;id de même valeur pourra être sélectionné avec le pseudo-sélecteur <code>:target</code>.</p>
<p>Donc je peux faire une mise en avant toute simple avec :</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-id">#previous-posts</span> {
    <span class="hljs-selector-tag">ul</span> {
        <span class="hljs-selector-tag">li</span> {
            <span class="hljs-selector-tag">a</span> {
                &amp;<span class="hljs-selector-pseudo">:target</span> {
                    <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--color--primary)
                }
            }
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/31/creer-une-vue-calendrier-minimaliste-avec-du-html-et-du-css/img/target-focus.png" alt="Mise en avant de la cible de l&#39;ancre" is="img-zoom"/>
<figcaption>Mise en avant de la cible de l&#39;ancre</figcaption>
</figure>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>À la base quand j&#39;ai ajouté ça à mon blog, je ne pensais pas en faire un article : je me suis amusé à ajouter ça, puis j&#39;ai pris un pas de recul en me disant que y&#39;avait des trucs intéressants à montrer et expliquer ! Surtout à l&#39;heure des LLMs qui crachent du Tailwind les yeux fermés à longueur de temps alors qu&#39;on pourrait faire tellement plus simple en CSS… Mais bref !</p>
<p>On aurait pu faire des choses très différentes visuellement, même en se basant sur des mécaniques très similaires côté sélecteurs. Mais là on parle d&#39;une question de goût / choix. J&#39;ai choisi de faire quelque chose de très simple et minimaliste parce que c&#39;est ça que j&#39;avais envie de faire !</p>
<p>À noter que j&#39;ai une particularité sur le blog : je compte mes années de mars à février, donc j&#39;ai décalé mes archives pour caler à ce cycle. Maintenant : ça ne change rien à tout ce que j&#39;ai décrit dans cet article, simplement, ne comparez pas les jours exacts avec mon blog, vous allez vous arracher les cheveux !</p>
<p>Sources :</p>
<ul>
<li><a href="https://kuroidoruido.github.io/css-is-magic/minimalist-calendar-view/index.html">Démonstration interactive</a></li>
<li><a href="https://github.com/kuroidoruido/css-is-magic/blob/main/minimalist-calendar-view/">Code source de la démo</a></li>
<li><a href="https://sacreesblogueuses.com/combien-de-semaines-dans-une-annee-52-ou-53-selon-le-calendrier/">Combien de semaines dans une année : 52 ou 53 selon le calendrier</a></li>
<li><a href="https://www.w3schools.com/Css/css_combinators.asp">CSS Combinators (w3schools)</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Colors/Using_relative_colors">Using relative colors (mdn)</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A cozy wooden desk bathed in soft golden light, reminiscent of a late autumn afternoon. The centerpiece is a large wooden calendar, intricately carved with circular reliefs representing each day of the year. Some circles are illuminated in soft blue or green, symbolizing published articles. A red panda, sitting on a cushion in the bottom right corner (occupying less than 1/3 of the height), is gently painting one of the calendar circles with a fine brush. The red panda is slightly turned in a 3/4 back view, surrounded by a subtle halo of light and 8-10 floating maple leaves in shades of red, orange, and yellow. Around the calendar, faint holograms display snippets of CSS/HTML code and dates, blending seamlessly into the scene. The atmosphere is warm, poetic, and dreamlike, inspired by Studio Ghibli&#39;s style, with a harmonious mix of organic textures (wood, fabric) and subtle high-tech elements (holograms with wooden frames). The overall mood is immersive, cozy, and magical, evoking a sense of timeless creativity and reflection.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Créer un composant Tabs avec Angular]]></title>
      <guid isPermaLink="false">2026/03/24/creer-composants-tabs-avec-angular</guid>
      <description><![CDATA[<p>Récemment j&#39;ai eu besoin de créer un composant Tabs pour une vue avec des onglets. Ce n&#39;est pas très…</p>
]]></description>
      <link>https://anthonypena.fr/2026/03/24/creer-composants-tabs-avec-angular/index.html</link>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Frontend]]></category>
      <pubDate>Tue, 24 Mar 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Récemment j&#39;ai eu besoin de créer un composant Tabs pour une vue avec des onglets. Ce n&#39;est pas très compliqué, mais il y a quelques trucs intéressants à faire pour avoir des éléments très simples à manipuler en tant que consommateur du composant, avec peu d&#39;effort de maintenance ensuite.</p>
<blockquote>
<p>Note : pour cet article j&#39;ai créé un projet Angular en version 21 et j&#39;ai décidé de suivre la nouvelle convention de nommage des fichiers (sans les suffixes <code>.component</code>, <code>.service</code>, etc.), vous êtes évidemment libre de suivre l&#39;ancienne convention.</p>
</blockquote>
<p>Tout le code montré ici est disponible dans un projet prêt à lancer ici : <a href="https://github.com/kuroidoruido/ng-tabs-sample">https://github.com/kuroidoruido/ng-tabs-sample</a></p>
<h2 id="article-le-style">Le style<a href="#article-le-style" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je ne vais pas m&#39;attarder sur la partie style. Pas que ça n&#39;ait aucun intérêt, mais il y a pléthore d&#39;exemples et finalement ce n&#39;est pas très intéressant à détailler ici à mon sens. Je vais donc faire un style assez minimaliste (et un peu incomplet) mais suffisant pour que ça fonctionne !</p>
<p>Le HTML :</p>
<pre><code class="hljs language-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-group&quot;</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-headers&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-header&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-tab</span>=<span class="hljs-string">&quot;tab-1&quot;</span>&gt;</span>Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-header active&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-tab</span>=<span class="hljs-string">&quot;tab-2&quot;</span>&gt;</span>Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-header&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-tab</span>=<span class="hljs-string">&quot;tab-3&quot;</span>&gt;</span>Tab 3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-content&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;tab-1&quot;</span>&gt;</span>
    ...
  <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-content active&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;tab-2&quot;</span>&gt;</span>
    ...
  <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;tab-content&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;tab-3&quot;</span>&gt;</span>
    ...
  <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span><div aria-hidden="true" class="language-tag">HTML</div>
</code></pre><p>Le style qui va avec :</p>
<pre><code class="hljs language-CSS"><span class="hljs-selector-tag">section</span><span class="hljs-selector-class">.tab-group</span> {
    <span class="hljs-attr">--color--gray</span>: <span class="hljs-number">#ccc</span>;
    <span class="hljs-attr">--color--gray-dark</span>: <span class="hljs-number">#999</span>;

    <span class="hljs-attr">--border--color</span>: <span class="hljs-built_in">var</span>(--color--gray);
    <span class="hljs-attr">--border--width</span>: <span class="hljs-number">1px</span>;
    <span class="hljs-selector-tag">nav</span><span class="hljs-selector-class">.tab-headers</span> {
        <span class="hljs-selector-tag">ul</span> {
            <span class="hljs-attribute">display</span>: flex;
            <span class="hljs-attribute">list-style</span>: none;
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">border-bottom</span>: <span class="hljs-built_in">var</span>(--border--width) solid <span class="hljs-built_in">var</span>(--border--color);
        }
        <span class="hljs-selector-class">.tab-header</span> {
            <span class="hljs-attribute">border</span>: <span class="hljs-built_in">var</span>(--border--width) solid <span class="hljs-built_in">var</span>(--border--color);
            <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-number">0.5rem</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>;
            <span class="hljs-attribute">border-bottom-color</span>: white;
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-built_in">calc</span>(-<span class="hljs-number">1</span> * <span class="hljs-built_in">var</span>(--border--width));
            
            <span class="hljs-selector-tag">button</span> {
                <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-number">1.5rem</span>;
                <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
                <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
                <span class="hljs-attribute">background</span>: none;
                <span class="hljs-attribute">border</span>: none;
                <span class="hljs-attribute">cursor</span>: pointer;
            }
            
            &amp;<span class="hljs-selector-pseudo">:hover</span> {
                <span class="hljs-attribute">border-color</span>: <span class="hljs-built_in">var</span>(--color--gray-dark);
            }

            &amp;<span class="hljs-selector-pseudo">:not</span>(<span class="hljs-selector-class">.active</span>) {
                <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">var</span>(--border--color);
                <span class="hljs-attribute">border-bottom-color</span>: <span class="hljs-built_in">var</span>(--border--color);
                <span class="hljs-selector-tag">button</span> {
                    <span class="hljs-attribute">color</span>: black;
                }
            }
        }
    }
    
    <span class="hljs-selector-class">.tab-content</span> {
        <span class="hljs-attribute">display</span>: none;
        <span class="hljs-attribute">border</span>: <span class="hljs-built_in">var</span>(--border--width) solid <span class="hljs-built_in">var</span>(--border--color);
        <span class="hljs-attribute">border-top</span>: none;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0.5rem</span> <span class="hljs-number">0.5rem</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-number">1rem</span>;

        &amp; &gt; <span class="hljs-selector-pseudo">:first-child</span> {
            <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">0</span>;
        }
        &amp; &gt; <span class="hljs-selector-pseudo">:last-child</span> {
            <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0</span>;
            <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0</span>;
        }

        &amp;<span class="hljs-selector-class">.active</span> {
            <span class="hljs-attribute">display</span>: block;
        }
    }
}<div aria-hidden="true" class="language-tag">CSS</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/24/creer-composants-tabs-avec-angular/img/html-css-screenshot.png" alt="Vu avec seulement HTML et CSS" is="img-zoom"/>
<figcaption>Vu avec seulement HTML et CSS</figcaption>
</figure>
<p>Maintenant on passe à ce qui est intéressant !</p>
<h2 id="article-cote-utilisation">Côté utilisation<a href="#article-cote-utilisation" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai fait quelque chose d&#39;assez simple côté DOM, mais je n&#39;ai pas trop ce genre de code sur le tous les jours en mode composant : ça devient vite un énorme monolithe, avec la logique des onglets perdue au milieu de la logique métier, quand on a pas plusieurs occurrences du composant avec de la duplication… Et bonus : dans 2-3 ans, le style va évoluer et il va falloir repasser sur toutes les occurrences du composant pour changer, en prenant en compte les &quot;quelques petites améliorations/corrections&quot; locales à chaque occurrence…</p>
<p>Bref : si je travaille avec un framework, je n&#39;utilise pas directement le HTML, je vais cacher ça dans un composant avec un DSL propre qui s&#39;adapte bien à mon projet (pas forcément tous les projets). C&#39;est aussi vrai pour pas mal de briques du genre.</p>
<p>Voilà ce que je veux écrire :</p>
<pre><code class="hljs language-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">app-tab-group</span> <span class="hljs-attr">default</span>=<span class="hljs-string">&quot;tab-2&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">app-tab-headers</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">app-tab</span>=<span class="hljs-string">&quot;tab-1&quot;</span>&gt;</span>Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">app-tab</span>=<span class="hljs-string">&quot;tab-2&quot;</span>&gt;</span>Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">app-tab</span>=<span class="hljs-string">&quot;tab-3&quot;</span>&gt;</span>Tab 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">app-tab-content</span>=<span class="hljs-string">&quot;tab-1&quot;</span>&gt;</span>
        ...
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">app-tab-content</span>=<span class="hljs-string">&quot;tab-2&quot;</span>&gt;</span>
        ...
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">app-tab-content</span>=<span class="hljs-string">&quot;tab-3&quot;</span>&gt;</span>
        ...
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">app-tab-group</span>&gt;</span><div aria-hidden="true" class="language-tag">HTML</div>
</code></pre><p>Ce n&#39;est pas si différent que ça de la version HTML pure. Ça va me permettre de ne pas ajouter d&#39;élément dans le DOM en plus de ce qui est requis, car certains styles d&#39;entreprise utilisent des sélecteurs du type <code>.tab-group &gt; .tab-headers</code> (pour cibler le <code>.tab-headers</code> qui est l&#39;enfant direct de <code>.tab-group</code>), donc vous ne pouvez pas intercaler d&#39;éléments.</p>
<p>On reste un peu proche du DOM d&#39;origine avec les <code>&lt;li&gt;</code> et <code>&lt;section&gt;</code> qui sont toujours là, mais on s&#39;est débarrassé de toutes les classes et on va pouvoir gérer facilement un peu tout proprement chacun de son côté !</p>
<h2 id="article-construisons-les-composants">Construisons les composants<a href="#article-construisons-les-composants" class="anchor" aria-label="permalink">🔗</a></h2>
<p>La première étape c&#39;est de construire les différents composants :</p>
<ul>
<li><code>&lt;app-tab-group&gt;</code> : qui sera notre composant parent ;</li>
<li><code>[app-tab-headers]</code> : qui va contenir nos titres d&#39;onglet ;</li>
<li><code>[app-tab]</code> : qui va gérer chaque titre d&#39;onglet individuellement ;</li>
<li><code>[app-tab-content]</code> : qui va gérer le contenu de chaque onglet ;</li>
</ul>
<p>Les rôles sont bien divisés. Chaque composant a un rôle bien défini et on va pouvoir faire des petits composants !</p>
<p>Personnellement ce genre de brique réutilisable plutôt générique, je les place dans un dossier <code>shared/components</code> (ou quelque chose de similaire en fonction des conventions de l&#39;équipe / du projet), avec un fichier <code>index.ts</code> pour directement pouvoir importer un peu partout nos différentes briques. L&#39;intérêt du <code>index.ts</code> ici c&#39;est qu&#39;on va pouvoir assez facilement refactorer / déplacer nos composants / fichiers sans forcément avoir des changements d&#39;import partout dans l&#39;application (ça évite donc du bruit dans les relectures de code).</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/index.ts</span>
<span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./tab-group&#x27;</span>
<span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./tab-headers&#x27;</span>
<span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./tab&#x27;</span>
<span class="hljs-keyword">export</span> * <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./tab-content&#x27;</span>;<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Pour le composant <code>app-tab-group</code> c&#39;est simplement un composant conteneur qui ne fait rien (pour l&#39;instant en tout cas) :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab-group.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span>, input } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;app-tab-group&quot;</span>,
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
    &lt;section class=&quot;tab-group&quot;&gt;
        &lt;ng-content /&gt;
    &lt;/section&gt;`</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabGroup</span> {
    <span class="hljs-keyword">default</span> = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;();
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>On voit le paramètre <code>default</code> qui est défini mais on ne s&#39;en sert pas pour l&#39;instant.</p>
<p>Les composants <code>app-tab-headers</code> et <code>app-tab</code> sont assez similaires à part que leur sélecteur se base sur un attribut et pas un élément, et qu&#39;on va retrouver l&#39;utilisation de <code>host</code> pour définir des attributs sur l&#39;élément qui va porter l&#39;attribut : </p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab-headers.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;[app-tab-headers]&quot;</span>,
    <span class="hljs-attr">host</span>: {
        <span class="hljs-string">&quot;[class.tab-headers]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
    },
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
    &lt;nav class=&quot;tab-headers&quot;&gt;
        &lt;ul&gt;
            &lt;ng-content /&gt;
        &lt;/ul&gt;
    &lt;/nav&gt;`</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabHeaders</span> {}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span>, input } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;[app-tab]&quot;</span>,
    <span class="hljs-attr">host</span>: {
        <span class="hljs-string">&quot;[class.tab-header]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
        <span class="hljs-string">&quot;[attr.data-tab]&quot;</span>: <span class="hljs-string">&quot;tab()&quot;</span>,
    },
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
    &lt;button [attr.data-tab]=&quot;tab()&quot;&gt;
        &lt;ng-content /&gt;
    &lt;/button&gt;
    `</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Tab</span> {
    tab = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;({ <span class="hljs-attr">alias</span>: <span class="hljs-string">&quot;app-tab&quot;</span> });
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><blockquote>
<p>Note : on aurait pu se passer de l&#39;alias sur l&#39;input <code>tab</code> mais je trouve ça plus simple d&#39;écrire <code>&lt;li app-tab=&quot;tab-1&quot;&gt;Tab 1&lt;/li&gt;</code> que d&#39;écrire <code>&lt;li app-tab tab=&quot;tab-1&quot;&gt;Tab 1&lt;/li&gt;</code>.</p>
</blockquote>
<p>On retrouve ensuite <code>app-tab-content</code> qui est assez simple avec rien d&#39;original par rapport aux autres composants : </p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab-content.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Component</span>, input } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;[app-tab-content]&quot;</span>,
    <span class="hljs-attr">host</span>: {
        <span class="hljs-string">&quot;[class.tab-content]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
        <span class="hljs-string">&quot;[class.active]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
        <span class="hljs-string">&quot;[attr.id]&quot;</span>: <span class="hljs-string">&quot;tab()&quot;</span>,
    },
    <span class="hljs-attr">template</span>: <span class="hljs-string">&quot;&lt;ng-content /&gt;&quot;</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabContent</span> {
    tab = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;({ <span class="hljs-attr">alias</span>: <span class="hljs-string">&quot;app-tab-content&quot;</span> });
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>En l&#39;état ça ne fonctionne évidemment pas, et on voit à la fois tout le contenu et tous les onglets en version inactive.</p>
<figure>
<img src="https://anthonypena.fr/2026/03/24/creer-composants-tabs-avec-angular/img/static-angular-screenshot.png" alt="Version non finie mais en composant Angular" is="img-zoom"/>
<figcaption>Version non finie mais en composant Angular</figcaption>
</figure>
<h2 id="article-creer-un-etat-partage-entre-tout-le-monde">Créer un état partagé entre tout le monde<a href="#article-creer-un-etat-partage-entre-tout-le-monde" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Maintenant on se pose et on réfléchit : on a besoin qu&#39;à chaque clic sur un onglet, on indique aux contenus qu&#39;ils doivent se masquer / s&#39;afficher. Donc il faut que les composants <code>app-tab</code> puissent communiquer avec les composants <code>app-tab-content</code>.</p>
<p>L&#39;option de base serait d&#39;avoir un service global qui gère tous les onglets et tous les groupes d&#39;onglets, garde un identifiant pour chaque, se débrouille pour tout track, et nettoyer quand y&#39;a besoin, etc. Mais non : ça parait simple mais en fait c&#39;est plein de complexités…</p>
<p>On pourrait se dire que quelque chose comme <a href="https://ngrx.io/">NgRx</a> ou un <a href="https://ngrx.io/guide/signals/signal-store">signal store</a> pourrait être une bonne solution, mais le premier pose une grande partie des mêmes problèmes que le service global, le second n&#39;apportera pas grand-chose de plus…</p>
<p>Alors on fait comment ? On va utiliser un service qu&#39;on provide nous-même avec un scope restreint à notre groupe d&#39;onglet : à la création de <code>&lt;app-tab-group&gt;</code>, on veut une nouvelle instance de notre service, et que cette instance soit partagée uniquement avec les composants enfants. C&#39;est facile, et vraiment : c&#39;est pas compliqué !</p>
<p>Commençons par créer notre service :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab-state.ts</span>
<span class="hljs-keyword">import</span> { computed, <span class="hljs-title class_">Injectable</span>, <span class="hljs-title class_">Signal</span>, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@angular/core&quot;</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabState</span> {
    <span class="hljs-keyword">private</span> _defaultTab = signal&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">private</span> _activeTab = signal&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);

    <span class="hljs-keyword">public</span> <span class="hljs-title function_">setActiveTab</span>(<span class="hljs-params"><span class="hljs-attr">tabId</span>: <span class="hljs-built_in">string</span></span>) {
        <span class="hljs-variable language_">this</span>.<span class="hljs-property">_activeTab</span>.<span class="hljs-title function_">set</span>(tabId ?? <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_defaultTab</span>());
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title function_">setDefaultTab</span>(<span class="hljs-params"><span class="hljs-attr">tabId</span>: <span class="hljs-built_in">string</span></span>) {
        <span class="hljs-variable language_">this</span>.<span class="hljs-property">_defaultTab</span>.<span class="hljs-title function_">set</span>(tabId);

        <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_activeTab</span>() == <span class="hljs-literal">null</span>) {
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">_activeTab</span>.<span class="hljs-title function_">set</span>(tabId);
        }
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title function_">isActive</span>(<span class="hljs-attr">tabId</span>: <span class="hljs-title class_">Signal</span>&lt;<span class="hljs-built_in">string</span>&gt;): <span class="hljs-title class_">Signal</span>&lt;<span class="hljs-built_in">boolean</span>&gt; {
        <span class="hljs-keyword">return</span> <span class="hljs-title function_">computed</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_activeTab</span>() === <span class="hljs-title function_">tabId</span>());
    }
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Ici mon service <code>TabState</code> va porter l&#39;état d&#39;un seul groupe d&#39;onglet, donc on a besoin que de deux choses : garder en mémoire l&#39;onglet par défaut et garder en mémoire l&#39;onglet actif. Le reste c&#39;est des méthodes utilitaires pour s&#39;assurer qu&#39;on garde bien encapsulé les signaux.</p>
<p>Vous noterez que contrairement à ce qu&#39;on fait habituellement : je **n&#39;**ai <strong>pas</strong> mis de <code>{ providedIn: &#39;root&#39; }</code> dans l&#39;annotation <code>@Injectable()</code>. Avoir un <code>{ providedIn: &#39;root&#39; }</code> entrainerait que le service serait global, or ce n&#39;est pas ce qu&#39;on veut, on peut nous-mêmes indiquer le <code>provide</code>.</p>
<p>C&#39;est là que la magie opère :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab-group.ts</span>

<span class="hljs-meta">@Component</span>({
    ...
    <span class="hljs-attr">providers</span>: [<span class="hljs-title class_">TabState</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabGroup</span> {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> tabState = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">TabState</span>);

    <span class="hljs-keyword">default</span> = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;();

    <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) {
        <span class="hljs-title function_">effect</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">tabState</span>.<span class="hljs-title function_">setDefaultTab</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">default</span>()));
    }
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><p>Ici on va ajouter notre service comme <code>provider</code>, ce qui va lier une instance du service <code>TabState</code> à chaque instance de <code>TabGroup</code>. Ensuite on peut l&#39;injecter comme n&#39;importe quel autre service. On en profite pour définir notre onglet par défaut via un <code>effect</code> dans le constructor.</p>
<p>Ensuite on peut rendre dynamique nos autres composants :</p>
<pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab.ts</span>
<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;[app-tab]&quot;</span>,
    <span class="hljs-attr">host</span>: {
        <span class="hljs-string">&quot;[class.tab-header]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
        <span class="hljs-string">&quot;[class.active]&quot;</span>: <span class="hljs-string">&quot;isActive()&quot;</span>,
        <span class="hljs-string">&quot;[attr.data-tab]&quot;</span>: <span class="hljs-string">&quot;tab()&quot;</span>,
    },
    <span class="hljs-attr">template</span>: <span class="hljs-string">`
    &lt;button [attr.data-tab]=&quot;tab()&quot; (click)=&quot;tabState.setActiveTab(tab())&quot;&gt;
        &lt;ng-content /&gt;
    &lt;/button&gt;
    `</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Tab</span> {
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> tabState = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">TabState</span>);
    
    tab = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;({ <span class="hljs-attr">alias</span>: <span class="hljs-string">&quot;app-tab&quot;</span> });
    
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> isActive = <span class="hljs-variable language_">this</span>.<span class="hljs-property">tabState</span>.<span class="hljs-title function_">isActive</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">tab</span>);
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><pre><code class="hljs language-TypeScript"><span class="hljs-comment">// src/app/shared/components/tabs/tab.ts</span>
<span class="hljs-meta">@Component</span>({
    <span class="hljs-attr">selector</span>: <span class="hljs-string">&quot;[app-tab-content]&quot;</span>,
    <span class="hljs-attr">host</span>: {
        <span class="hljs-string">&quot;[class.tab-content]&quot;</span>: <span class="hljs-string">&quot;true&quot;</span>,
        <span class="hljs-string">&quot;[class.active]&quot;</span>: <span class="hljs-string">&quot;isActive()&quot;</span>,
        <span class="hljs-string">&quot;[attr.id]&quot;</span>: <span class="hljs-string">&quot;tab()&quot;</span>,
    },
    <span class="hljs-attr">template</span>: <span class="hljs-string">&quot;&lt;ng-content /&gt;&quot;</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TabContent</span> {
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> tabState = <span class="hljs-title function_">inject</span>(<span class="hljs-title class_">TabState</span>);
    
    tab = input.<span class="hljs-property">required</span>&lt;<span class="hljs-built_in">string</span>&gt;({ <span class="hljs-attr">alias</span>: <span class="hljs-string">&quot;app-tab-content&quot;</span> });
    
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">readonly</span> isActive = <span class="hljs-variable language_">this</span>.<span class="hljs-property">tabState</span>.<span class="hljs-title function_">isActive</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">tab</span>);
}<div aria-hidden="true" class="language-tag">TypeScript</div>
</code></pre><figure>
<img src="https://anthonypena.fr/2026/03/24/creer-composants-tabs-avec-angular/img/demo.gif" alt="Démonstration des onglets fonctionnels" is="img-zoom"/>
<figcaption>Démonstration des onglets fonctionnels</figcaption>
</figure>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Faire des briques dans ce genre implique souvent la création d&#39;une grosse usine compliqué à cause de la méconnaissance du framework. C&#39;est finalement assez facile d&#39;avoir un état partagé à un groupe de composant (encore plus depuis les standalone component !), assez peu verbeux quand on travaille en Single File Component et avec des signaux comme je l&#39;ai fait.</p>
<p>Si finalement le code n&#39;est pas très compliqué, je trouve que c&#39;est le genre de mécanique qui peut se transposer facilement à des briques plus complexes !</p>
<p>Sources :</p>
<ul>
<li><a href="https://github.com/kuroidoruido/ng-tabs-sample">Projet démo</a></li>
</ul>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Studio Ghibli-inspired magical workshop: a wooden desk with old grimoires and floating holographic screens showing a modern Angular Tabs component with &quot;Sortilèges&quot;, &quot;Ingrédients&quot;, and &quot;Recettes&quot; tabs. An axolotl in a lab coat watches nearby, surrounded by golden light and maple leaves. Warm, dreamy autumn lighting, soft textures, 8K, detailed.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[2025 c'est fini, en route pour 2026 !]]></title>
      <guid isPermaLink="false">2026/03/11/2025-cest-fini-en-route-pour-2026</guid>
      <description><![CDATA[<p>Nouvelle année, nouveau bilan ! Cette année est encore une année un peu mouvementée !</p>
]]></description>
      <link>https://anthonypena.fr/2026/03/11/2025-cest-fini-en-route-pour-2026/index.html</link>
      <category><![CDATA[Edito]]></category>
      <category><![CDATA[Blog]]></category>
      <pubDate>Wed, 11 Mar 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Nouvelle année, nouveau bilan ! Cette année est encore une année un peu mouvementée !</p>
<p>Si vous découvrez mon blog ou mes bilans annuels, je les fais en mars, car je suis né fin février, ce qui fait que je fais mes bilans en année &quot;Anthony&quot; (vous pouvez vous dire aussi que c&#39;est en <a href="https://fr.wikipedia.org/wiki/Calendrier_romain#Les_mois">calendrier romain pompilien</a> aussi si vous trouvez ça trop égocentrique). Tout ça pour dire que ça me semble finalement plus logique de faire mon bilan annuel en suivant mes années de vie que début janvier.</p>
<nav data-serie="bilan-annuel">
<h2>Série d'article</h2>
<ul>
<li><a href="https://anthonypena.fr/2022/03/08/2021-cest-fini-en-route-pour-2022/index.html">2021 c'est fini, en route pour 2022 !</a></li>
<li><a href="https://anthonypena.fr/2023/03/07/2022-cest-fini-en-route-pour-2023/index.html">2022 c'est fini, en route pour 2023 !</a></li>
<li><a href="https://anthonypena.fr/2024/03/12/2023-cest-fini-en-route-pour-2024/index.html">2023 c'est fini, en route pour 2024 !</a></li>
<li><a href="https://anthonypena.fr/2025/03/11/2024-cest-fini-en-route-pour-2025/index.html">2024 c'est fini, en route pour 2025 !</a></li>
<li><a href="https://anthonypena.fr/2026/03/11/2025-cest-fini-en-route-pour-2026/index.html">2025 c'est fini, en route pour 2026 !</a></li>
</ul>
</nav>
<h2 id="article-cote-mission">Côté mission<a href="#article-cote-mission" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ça fait maintenant plus d&#39;un an que je travaille sur cette mission (commencé en novembre 2024). Je suis bien sur cette mission, l&#39;équipe est bien, le projet est intéressant. Comme partout tout n&#39;est pas parfait, mais j&#39;y trouve un certain équilibre. J&#39;ai aussi depuis quelque temps une position plus transverse : on a dû doubler le nombre de personne pour encaisser le volume de travail en avançant la date de livraison et fini par prendre un peu de hauteur en prenant des sujets plus long court et plus complexe.</p>
<p>Dans un sens j&#39;ai aussi pu évoluer sur l&#39;aspect mentoring et je me questionne sur l&#39;éventualité d&#39;en faire plus (et même hors de cette mission).</p>
<p>Je ne sais pas comment tout ça va évoluer, mais on verra : en tout cas je vois dans la roadmap des sujets que j&#39;ai envie de mener !</p>
<h2 id="article-cote-sfeir">Côté SFEIR<a href="#article-cote-sfeir" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai soufflé la semaine dernière ma 7ème bougie. Je me répète, mais j&#39;aurai jamais cru resté aussi longtemps.</p>
<p>Toujours Staff Engineer, j&#39;ai quand même eu un focus plutôt sur des sujets groupes plutôt qu&#39;agence cette année à mon sens. J&#39;ai en effet essentiellement travaillé sur l&#39;outillage des formations et l&#39;expérience formateur.</p>
<p>J&#39;ai encore fait pas mal de chose cette année, même hors de la casquette Staff Engineer, mais je commence à laisser mes casquettes à d&#39;autres pour laisser d&#39;autres grandir à leur tour. On verra de quoi 2026 sera fait !</p>
<h2 id="article-cote-langage-et-projets-perso">Côté langage et projets perso<a href="#article-cote-langage-et-projets-perso" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Est-ce que j&#39;ai fait ce qui était prévu ? Non. Est-ce que c&#39;est grave ? Non plus !</p>
<p>J&#39;ai enfin sorti le blog de Ghost ! J&#39;en ai fait une série d&#39;article pour tout expliqué.</p>
<p>J&#39;ai aussi continué à travailler sur <a href="https://anthonypena-easy-wiremock.deno.dev">Easy Wiremock</a> (qui est un frontend à Wiremock pour pouvoir visualiser différents éléments). J&#39;ai ajouté des petites fonctionnalités qui m&#39;aident au quotidien (qui aident aussi les membres de mon équipe), ça fonctionne bien, donc c&#39;est un succès à mon sens !</p>
<p>Je pensais retravailler mon fork de <a href="https://github.com/kuroidoruido/canis-dirus/">Canis Dirus</a> (et repousser à Siegfried ces contributions) et finalement je n&#39;ai jamais pris le temps de le faire… J&#39;ai toujours des idées, mais je vais peut-être changer de fonctionnement pour pouvoir aller plus loin (et faire aussi beaucoup plus que &quot;juste&quot; pousser sur Mastodon ma veille en continu). Si ça abouti j&#39;en reparlerai, car je pense que ça pourrait intéresser des gens !</p>
<h2 id="article-conferences--talks">Conférences / Talks<a href="#article-conferences--talks" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Année encore plutôt calme côté conférences et meetups :</p>
<ul>
<li>J&#39;ai rejoué mon talk <a href="https://kuroidoruido.github.io/talks/2025/06-05_devquest-2025_adieu-rxjs/index.html">Adieu RxJS ! Vive les Signals ! Oh wait…</a> en juin à DevQuest à Niort ;</li>
<li>J&#39;ai joué un talk en interne de Sfeir Nantes sur <a href="https://kuroidoruido.github.io/talks/2025/07-09_sfeir-share_post-linkedin-parfait/index.html">Comment faire le post LinkedIn parfait ?</a> ;</li>
</ul>
<p>Par contre j&#39;ai toujours été impliqué à d&#39;autres niveaux :</p>
<ul>
<li>J&#39;ai continué à travailler sur <a href="https://angulardevs.fr">Angular Devs France</a> même s&#39;il faut avouer qu&#39;on s&#39;est beaucoup concentré sur <a href="https://2025-ngbaguette.angulardevs.fr/fr/">NG Baguette Conf 2025</a> et qu&#39;on est toujours pas mal occupé sur <a href="https://ngbaguette.angulardevs.fr">NG Baguette Conf 2026</a> (dont la billetterie est ouverte en ce moment !) ;</li>
<li>J&#39;ai continué jusqu&#39;à l&#39;été les apéros du <a href="https://naoned.computer-club.fr/">Naoned Computer Club</a> mais je n&#39;ai pas réussi à reprendre après l&#39;été et j&#39;ai finalement annoncé côté association Computer Club que j&#39;arrêtais ;</li>
<li>J&#39;ai été à nouveau bénévole pour Devfest Nantes ;</li>
</ul>
<h2 id="article-le-blog">Le blog<a href="#article-le-blog" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Bilan de l&#39;année : 41 articles publiés depuis mon dernier bilan (cet article inclus) ! Ceci incluant 12 revues de presses, j&#39;ai donc écrit 29 articles à proprement parler.</p>
<p>C&#39;est 15 de plus que ce que je comptais pour 2024. Clairement une de mes plus grosses années ! Et j&#39;en suis très content !</p>
<p>J&#39;aime toujours écrire, j&#39;aime toujours partager, j&#39;ai envie de partager beaucoup de choses (pas que via mon blog / en mode texte), ça me fait toujours du bien à moi, donc je ne compte pas m&#39;arrêter là !</p>
<p>Je sais que le blog en lui-même m&#39;a demandé pas mal de travail pour la migration, je sais aussi que j&#39;ai encore du chemin à parcourir pour aller au bout du blog tel que je l&#39;imaginais. En tout cas je suis toujours content de voir que des gens me lisent !</p>
<p>N&#39;hésitez pas à me contacter en privé ou m&#39;interpeler si on se croise en personne ou commenter mes publications sur les réseaux sociaux. Je vous répondrais, et ça pourrait créer de la discussion ou des idées d&#39;articles !</p>
<h2 id="article-mon-bujo-et-moi">Mon BuJo et moi<a href="#article-mon-bujo-et-moi" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai encore beaucoup utilisé mon BuJo cette année, et je confirme ce que je disais l&#39;année dernière : les carnets de La Boutique de Margaux sont parfaits ! Donc j&#39;ai à nouveau pris un carnet de cette boutique, et j&#39;ai choisi <a href="https://laboutiquedemargaux.fr/collections/lorganise/products/bullet-journal-lorganise-cerise-carnet-a5">l&#39;Organisé &quot;Cerise&quot;</a> qui est un carnet rouge, avec un embossage représentant deux cerises. </p>
<p>J&#39;ai pas changé du tout ma formule BuJo minimaliste que j&#39;avais tenté l&#39;année dernière : elle me convient ! </p>
<p>J&#39;ai par contre changé de crayon. Je suis passé d&#39;un Kaco Green avec 3 couleurs (noir, rouge et bleue) + 1 porte mine (en gros comme un stylo 4 couleurs mais avec un couleur qui est un porte-mine, pas trouvé de lien) au combo d&#39;un stylo plume <a href="https://www.lamy.com/fr-fr/p/lamy-safari-stylo-plume/49729340014939">Lamy Safari Umbra F (Fine)</a> et d&#39;un critérium <a href="https://www.staedtler.com/fr/fr/produits/crayons-et-accessoires/porte-mine-fins/mars-micro-775-porte-mines-m775/">Staedtler Mars Micro 775 7mm</a>. Je ne pensais sincèrement pas retourné sur un stylo plume un jour, mais celui-ci m&#39;a tenté et est extrêmement agréable à manipuler et l&#39;écriture est super fluide ! J&#39;en suis très content. Si je ne devais citer qu&#39;un bémol : j&#39;aurai dû choisir la plume EF (Extra-Fine), car je trouve le trait légèrement trop épais à mon goût. Si un jour je dois le changer je tenterai peut-être le Lamy AL-star qui est globalement le même stylo que le Safari est en aluminium (juste un peu peur au côté désagréable du froid de l&#39;aluminium quand on commence à écrire). Mais passons sur mes histoires de stylos ! (quand bien même j&#39;adore la papeterie et je pourrais en parler encore pas mal 😅)</p>
<p>Sinon j&#39;utilise toujours un &quot;BuJo numérique&quot; à base d&#39;Obsidian pour ma mission, et ça correspond toujours à mon besoin !</p>
<h2 id="article-cote-lecture">Côté lecture<a href="#article-cote-lecture" class="anchor" aria-label="permalink">🔗</a></h2>
<p>J&#39;ai commencé à noter tout ce que je lis (pour l&#39;instant dans une checklist dans mon Trello en attendant mieux). Et je peux vous dire que je lis beaucoup, plus que je pensais ! 😅 Après je me dis que c&#39;est peut-être aussi un effet de mesure : comme je mesure je lis encore plus pour la métrique !</p>
<p>Pour vous donner des chiffres, entre le 1er novembre 2025 et le 28 février 2026 (j&#39;ai décidé de noter à partir de novembre, donc j&#39;arrête ce bloc au 28 février comme le reste), j&#39;ai lu 73 livres. Alors y&#39;a de tout : 2 magazines (Linux Magazine), 2 comics (dont un recueil des 15 premiers tomes de Spawn), 1 recueil de nouvelle, 1 essai économique, 6 romans, 24 bandes dessinées, 35 mangas et 2 manhuas (BD chinoise).</p>
<p>En tout cas je lis ! Et ça me fait du bien ! J&#39;ai aussi commencé à lire des livres qui me paraissent différent de ce que j&#39;ai déjà lu. J&#39;ai aussi commencé à lire de littérature japonaise, même si clairement j&#39;y connais pas grand-chose donc je teste un peu au hasard pour l&#39;instant. J&#39;ai commencé à regarder la littérature asiatique au sens large mais pour l&#39;instant j&#39;ai surtout accroché à des œuvres japonaises 🤷</p>
<p>Quelques recommandations de mon année (pas forcément d&#39;ordre précis) :</p>
<ul>
<li><em>Le recueil de l’angoisse</em> de Maël Sargel : auteur indépendant que j&#39;ai rencontré dans un salon du livre, j&#39;ai vraiment aimé ce recueil quand bien même je ne l&#39;ai pas forcément trouvé angoissant ;</li>
<li><em>Sang neuf</em> de Jean-Christophe Chauzy : bande dessiné d&#39;un auteur qui raconte son histoire face à la maladie, c&#39;est parfois un peu cru (moi ça me dérange pas du tout, mais ça peut déranger donc je préviens), mais c&#39;est vraiment touchant ;</li>
<li><em>La citadelle des vertiges</em> d&#39;Alain Grousset : roman que j&#39;avais lu adolescent et que j&#39;ai retrouvé par hasard dans une recyclerie, donc je me suis laissé aller à la nostalgie, et je ne regrette pas, c&#39;est un très bon livre qui se lit tout seul, même adolescent, tout en étant une bonne introduction à la science-fiction ;</li>
<li><em>La bibliothèque des rêves secrets</em> de Michiko Aoyama : très bon roman japonais, posé et relaxant, qui vous fera suivre des tranches de vie de personne croisant une bibliothécaire un peu particulière ;</li>
<li><em>Les milliardaires ne paient pas d&#39;impôts sur le revenu et nous allons y mettre fin</em> de Gabriel Zucman : pour dépasser ce qu&#39;on a peu entendre à droite ou à gauche et se poser sur ce qu&#39;il essaie d&#39;expliquer vraiment ;</li>
<li><em>Ikigami</em> de Motorō Mase (10 tomes) : dystopie où un pays proche du Japon aurait adopté après la Seconde Guerre Mondiale la &quot;Loi de prospérité nationale&quot; qui implique de tuer 1 personne sur 1000, âgée de 18 à 24 ans par injection d&#39;une capsule pendant la vaccination obligatoire à 6 ans, c&#39;est la 3ème fois que je lis cette histoire, c&#39;est bien écrit, on voit 20 points de vue différents autour de cette Loi et comment les gens gèrent leurs derniers instants, vraiment un très bon manga ;</li>
<li><em>The Walking Dead</em> de Robert Kirkman, Tony Moore et Charlie Adlard : le comics qui donnera par la suite la série TV, je ne suis pas intéressé par les zombies, les comics pas plus que ça non plus, mais la vache cette série est incroyable (et l&#39;histoire est assez différente de la série quand bien même on retrouve énormément de personnes) ;</li>
</ul>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Encore une année riche, encore une année où j&#39;ai pu faire des choses, mais aussi une année où j&#39;ai appris à fermer des portes. Que ce soit le Naoned Computer Club ou même les événements internes SFEIR, j&#39;ai fait des choix pour me préserver moi, et même si j&#39;ai pu réaliser des choses très sympas : je suis content que ce soit fini !</p>
<p>Pas forcément un laïus à faire dessus mais ça fait un an que j&#39;ai quitté Nantes et que je vis du côté de Cholet. Je continue de m&#39;approprier cette nouvelle vie, à commencer par le jardinage, mais ça fait du bien d&#39;avoir quitté le tumulte de la ville. Le seul truc qui me manque : il n&#39;y a pas de vraie bonne boutique vendant des mangas dans le choletait, j&#39;ai trouvé du mainstream, des rayonnages plus mal rangés les uns que les autres (ou avec des classements sans queue ni tête) mais pas de vrai rayon manga (pour être clair : il manque toujours 70-80% des titres que je suis…). Tant pis, Internet est mon ami pour corriger ce problème, et je ne parle pas d&#39;Amazon, il se trouve qu&#39;Otaku no Dera (la boutique que je fréquentais depuis 2010) vend aussi en livraison !</p>
<p>Sinon une nouvelle passion est rentrée dans ma vie : Magic The Gathering ! (Pas) Merci Myriam ! 😂 Bon en vrai, ça faisait pas mal de temps que j&#39;hésitais à mettre le nez dans un TCG (j&#39;ai joué pendant des années à Yu-Gi-Oh! avant de lâcher l&#39;affaire pour plein de raisons) et je me retrouve pas mal dans Magic, donc à voir dans le temps ! </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant</p>
<blockquote>
<p>A Ghibli-style illustration featuring a masculine character with a round face, full cheeks, a marked chin, curly hair tied in a low bun, dense short beard, and dark brown eyes slightly squinted, wearing black rectangular glasses and a silver chain necklace. He has a robust build with broad shoulders and wears a light blue t-shirt with two subtle, light-toned koi carp designs on the back. He stands in a 3/4 view on a Venetian bridge, left hand with a watch resting on the railing, gazing thoughtfully at the canal at dusk. The canal is lined with colorful houses, automated gondolas glide on the water, and bioluminescent jellyfish float gently. In the background, a warm, inviting bookstore glows softly. A red panda, curled up on a cushion in the lower right corner, watches the scene. The atmosphere is golden and dreamy, blending magic and subtle technology, with autumn leaves and a serene, reflective mood.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Mars 2026]]></title>
      <guid isPermaLink="false">2026/03/03/revue-de-presse-mars</guid>
      <description><![CDATA[]]></description>
      <link>https://anthonypena.fr/2026/03/03/revue-de-presse-mars/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Tue, 03 Mar 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-oathttpsoatinkcomponents"><a href="https://oat.ink/components/">Oat</a><a href="#article-oathttpsoatinkcomponents" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Frontend #CSS #JavaScript #Web</p>
<p>Encore une library de composant web super légère qui à l&#39;air plutôt complète ! </p>
<blockquote>
<p>Semantic, minimal, zero dependencies. ~8KB CSS and JS.</p>
</blockquote>
<p>Indépendant de tout framework, vous pouvez l&#39;utiliser partout dans vos frontend ! </p>
<h3 id="article-optimiser-les-perfs-et-la-securite-dun-site-hugo--julien-wittouckhttpscodekaio20260220optimiserlesperfsetlasc3a9curitc3a9dunsitehugo"><a href="https://codeka.io/2026/02/20/optimiser-les-perfs-et-la-s%C3%A9curit%C3%A9-dun-site-hugo/">Optimiser les perfs et la sécurité d&#39;un site Hugo - Julien Wittouck</a><a href="#article-optimiser-les-perfs-et-la-securite-dun-site-hugo--julien-wittouckhttpscodekaio20260220optimiserlesperfsetlasc3a9curitc3a9dunsitehugo" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Web #Frontend</p>
<p>Un REX sur quelques techniques pour optimiser le chargement / la sécurité d&#39;un site web </p>
<p>Pas surprise :</p>
<ul>
<li>utilisation de Lighthouse ;</li>
<li>changement de format d&#39;image pour du webp ; </li>
<li>resize des images pour avoir des images plus petites ;</li>
<li>utilisation de srcset pour laisser le navigateur choisir la taille optimale par rapport à l&#39;usage ;</li>
<li>ajout des bons headers de sécurité ;</li>
</ul>
<p>Faut que je me penche là-dessus sur mon site aussi ! </p>
<h3 id="article-optimisation-webperf--avif-et-precompression-pour-le-bloghttpsblogzwindlerfr20260219optimisationwebperfavifprecompression"><a href="https://blog.zwindler.fr/2026/02/19/optimisation-webperf-avif-precompression/">Optimisation webperf : AVIF et pré-compression pour le blog</a><a href="#article-optimisation-webperf--avif-et-precompression-pour-le-bloghttpsblogzwindlerfr20260219optimisationwebperfavifprecompression" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Frontend #Web #HTTP</p>
<p>Encore quelqu&#39;un qui revient de Touraine Tech et qui optimise son blog avec les conseils qui viennent d&#39;un talk ! </p>
<p>Ce coup-ci c&#39;est Denis, avec des résultats chiffrés ! </p>
<p>Franchement je suis pressé qu&#39;il y ait les replays en ligne pour voir le talk d&#39;Antoine Caron et Mathieu Mure <a href="https://touraine.tech/talk/cmgah8mo800fj1elbs7lmahsn?day%3D2">&quot;Au secours ! Mes images pourrissent mes perfs&quot;</a> !</p>
<h3 id="article-so-ive-been-thinking-about-static-site-generatorshttpswolfgirldevblog20260223soivebeenthinkingaboutstaticsitegenerators"><a href="https://wolfgirl.dev/blog/2026-02-23-so-ive-been-thinking-about-static-site-generators/">So I&#39;ve Been Thinking About Static Site Generators</a><a href="#article-so-ive-been-thinking-about-static-site-generatorshttpswolfgirldevblog20260223soivebeenthinkingaboutstaticsitegenerators" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Blog #Web #Frontend #Performance</p>
<p>Article assez détaillé sur comment avoir une génération statique d&#39;un site (SSG) type blog en cumulant 2 parties : la partie incrémentale / transformation du markdown dans un langage compilé comme Rust (car la logique est compilée très vite, de manière incrémentale, et ne bougera pas quand on aura besoin de générer le contenu) et la partie template dans un langage interprété comme JavaScript pour sa souplesse. </p>
<p>Les arguments sont intéressants je trouve. C&#39;est pas la voie que j&#39;ai prise par contre (mon blog est écrit entièrement avec un moteur maison en TypeScript exécuté avec Deno) par contre j&#39;ai des performances à date qui tiennent la route (1 à 3 secondes pour rebuilder mon blog). C&#39;est au-dessus de ce que l&#39;autrice souhaiterait (elle vise 300ms, si possible 100ms, même 20ms en but ultime), mais je trouve ça raisonnable (après dans 5 ans quand j&#39;aurai beaucoup plus de contenu j&#39;aurai peut-être un avis différent). </p>
<p>En tout cas je pense qu&#39;il y a de l&#39;inspiration à prendre !</p>
<h3 id="article-beulogue-v5httpsehretme202601beuloguev5"><a href="https://ehret.me/2026/01/beulogue-v5/">beulogue v5</a><a href="#article-beulogue-v5httpsehretme202601beuloguev5" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Astro #Blog #Frontend</p>
<p>J&#39;aime toujours autant voir comment les autres gèrent leur blog.</p>
<p>Ici Siegfried nous explique comment est construit la v5 de son blog, et ça tient surtout en un mot : Astro. </p>
<p>Je comprends complètement pourquoi, si vous avez lu <a href="https://anthonypena.fr/2026/01/15/nouveau-blog-partie-1-html/index.html">ma série d&#39;article que la réécriture de mon blog</a> vous savez que j&#39;ai failli le faire en Astro aussi mais finalement non. Ça reste un super framework ! </p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-containers-cloud-blockchain-ai--its-all-the-same-old-bs-says-veteran-red-hatterhttpswwwtheregistercom20260208waves_of_tech_bs"><a href="https://www.theregister.com/2026/02/08/waves_of_tech_bs/">Containers, cloud, blockchain, AI – it&#39;s all the same old BS, says veteran Red Hatter</a><a href="#article-containers-cloud-blockchain-ai--its-all-the-same-old-bs-says-veteran-red-hatterhttpswwwtheregistercom20260208waves_of_tech_bs" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#LLM #IA #Kubernetes #Cloud</p>
<p>Je cite directement car pas besoin de plus :</p>
<blockquote>
<p><strong>Containers</strong>: Sure, yes, they work, they are handy for testing. But they aren&#39;t a deployment method. You shouldn&#39;t need them. Anything that you can run in a container, you can just run on the bare metal, and if you&#39;re not competent enough to get – and keep – that working, then you probably aren&#39;t competent enough to deploy a container either.</p>
<p><strong>Kubernetes</strong>: If you don&#39;t need containers, then you don&#39;t need another vastly more complicated tool to deploy those containers. The chances are, you are not a vast multinational that must be able to withstand ten million potential new customers visiting your site all at once. It won&#39;t happen, so you won&#39;t lose any of that imaginary business.</p>
<p><strong>The cloud</strong>: Nebulous by name and by nature. Who thought it was smart to take all your company&#39;s important data and hand it to some internet rando – probably the lowest bidder – trusting them to store the crown jewels, keep them safe, and never ever peek at them. If that sounds reasonable to you, maybe you should try selling homeopathy.</p>
<p><strong>Anything &quot;as a service&quot; – it doesn&#39;t matter what</strong>: Infrastructure as a service – if you need servers, buy servers, or rent your own private servers. Nobody else will ever care as much about your servers as you will. Platform as a Service – now you don&#39;t even get servers, just OS instances. That&#39;s even worse. Software as a Service? Now you don&#39;t even know what the server is, or where it is, or what it&#39;s running; you don&#39;t get software, and you don&#39;t even know what data you have or how it&#39;s stored – you&#39;re paying for access to your own stuff.</p>
<p><strong>The blockchain, and anything built on the blockchain</strong>: the world&#39;s slowest and most-distributed database. Cryptocurrencies? Hashcash on the blockchain. NFTs – URL shorteners on the blockchain, only they&#39;re longer rather than shorter. Worthless. Web3? Get ripped off, as a service.</p>
<p>Which brings us round to <strong>&quot;generative AI&quot;</strong> or, as we prefer to term them, large language models, powered by the transformer algorithm. If The Financial Times can explain how it works to a banker in a couple of thousand words and a few minutes, it can&#39;t be that complicated or hard to understand, and it isn&#39;t. It&#39;s predictive text turned up to 11. It can&#39;t even count. As Daniel Stenberg, author of curl, caustically observed:</p>
<blockquote>
<p>The &quot;i&quot; in &quot;LLM&quot; stands for intelligence.</p>
</blockquote>
</blockquote>
<p>Si tout ça peut sembler &quot;l&#39;évolution logique&quot; pour certains, je trouve quand même qu&#39;on empile toujours plus de marketing et de bullshit… En ce moment c&#39;est l&#39;<strong>IA</strong> sans intelligence, demain ce sera autre chose 🤷‍♂️ </p>
<h3 id="article-waymo-exec-reveals-company-uses-operators-in-the-philippines-to-assist-autonomous-vehicleshttpssebsauvagenetlinksyqpe7w"><a href="https://sebsauvage.net/links/?yqpE7w">Waymo Exec Reveals Company Uses Operators in the Philippines to Assist Autonomous Vehicles</a><a href="#article-waymo-exec-reveals-company-uses-operators-in-the-philippines-to-assist-autonomous-vehicleshttpssebsauvagenetlinksyqpe7w" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Voiture-autonome #Voiture #Google</p>
<p>L&#39;IA de Waymo, une société de transport en voiture autonome appartenant à Google (pour être précis : au groupe Alphabet qui est la maison mère de Google), repose beaucoup sur l&#39;usage de philippins qui conduisent à distance les voitures &quot;autonomes piloté par IA&quot;… </p>
<p>Encore une entreprise IA qui ment sur son usage de l&#39;IA. Encore une IA qui repose sur des humains Sous-payés dans un pays pauvre. Les IA actuelles savent faire des choses, mais sont clairement très loin de ce qui est annoncé ! </p>
<h3 id="article-rtkhttpsgithubcomrtkairtk"><a href="https://github.com/rtk-ai/rtk">rtk</a><a href="#article-rtkhttpsgithubcomrtkairtk" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Agentic</p>
<blockquote>
<p>CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies </p>
</blockquote>
<p>Pas encore testé mais vu le prix que coûte l&#39;usage des IA comme Claude / Gemini, etc. réduire le volume de token en réduisant le bruit inutile des sorties des commandes courantes ça peut pas faire de mal ! </p>
<h3 id="article-jai-demande-a-claude-pourquoi-il-ne-recommande-jamais-vuejs--nicolas-bonnefoyhttpswwwlinkedincompostsnbonnefoy_jaidemand25c325a925c325a0claudepourquoiilnerecommandeshare7433139537821921280ror7utm_sourceshareutm_mediummember_androidrcmacoaabstacubdsnx13s7uh8twss8u8br5ts2ga"><a href="https://www.linkedin.com/posts/nbonnefoy_jai-demand%25C3%25A9-%25C3%25A0-claude-pourquoi-il-ne-recommande-share-7433139537821921280-roR7?utm_source%3Dshare%26utm_medium%3Dmember_android%26rcm%3DACoAABstAcUBDSnX1-3s7Uh8tWSS8u8BR5Ts2gA">J&#39;ai demandé à Claude pourquoi il ne recommande jamais Vue.js. — Nicolas Bonnefoy</a><a href="#article-jai-demande-a-claude-pourquoi-il-ne-recommande-jamais-vuejs--nicolas-bonnefoyhttpswwwlinkedincompostsnbonnefoy_jaidemand25c325a925c325a0claudepourquoiilnerecommandeshare7433139537821921280ror7utm_sourceshareutm_mediummember_androidrcmacoaabstacubdsnx13s7uh8twss8u8br5ts2ga" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Claude #LLM</p>
<blockquote>
<p>J&#39;ai demandé à Claude pourquoi il ne recommande jamais Vue.js.</p>
<p>Sa réponse, en substance : &quot;Je ne sais pas. Probablement parce que j&#39;ai vu plus de React dans mes données d&#39;entraînement.&quot;</p>
<p>Une étude d&#39;Amplifying vient de documenter le phénomène à grande échelle. Ils ont envoyé 2 430 prompts ouverts à Claude Code, du type &quot;j&#39;ai besoin d&#39;une base de données&quot; ou &quot;ajoute l&#39;authentification&quot;. Sans jamais nommer un outil.</p>
<p>Les résultats sont nets. GitHub Actions : 94%. Stripe : 91%. shadcn/ui : 90%. Vercel : 100% sur les projets JS.</p>
<p>Plus intéressant : les modèles les plus récents abandonnent des outils établis. Prisma passe de 79% à 0% entre Sonnet 4.5 et Opus 4.6. Celery de 100% à 0%. Au profit de Drizzle et des solutions natives FastAPI.</p>
<p>Le mécanisme est simple. Plus un outil est présent dans les données d&#39;entraînement, plus il est recommandé. Plus il est recommandé, plus il est adopté. Plus il est adopté, plus il apparaît dans les futures données d&#39;entraînement.</p>
<p>Ce n&#39;est pas un classement qualité. C&#39;est un classement de visibilité.</p>
<p>Quand je lui demande si c&#39;est justifié techniquement, Claude répond :</p>
<p>&quot;Pas vraiment. Vue 3 avec la Composition API, Nuxt 3, Pinia, VueUse : c&#39;est un écosystème mature, performant, avec une DX souvent supérieure pour certains profils de projets. La courbe d&#39;apprentissage est plus douce, l&#39;API est plus cohérente, et pour des équipes qui ne sont pas déjà dans l&#39;écosystème React, c&#39;est souvent un meilleur choix.</p>
<p>Le fait que je ne le propose pas par défaut est un bon exemple de ce que l&#39;étude appelle &#39;training data frequency vs actual quality&#39; : la fréquence dans mes données n&#39;est pas un signal de qualité, c&#39;est un signal de popularité. Et les deux ne sont pas la même chose.&quot;</p>
<p>Quand un founder me demande &quot;on part sur quelle stack ?&quot;, la vraie question n&#39;est plus seulement quel outil est le meilleur. C&#39;est : est-ce que ton CTO (ou ton agent IA) a évalué les alternatives, ou est-ce qu&#39;il suit le chemin par défaut ?</p>
<p>L&#39;étude complète : <a href="https://amplifying.ai/research/claude-code-picks/report">https://amplifying.ai/research/claude-code-picks/report</a> </p>
</blockquote>
<p>(j&#39;ai cité le post LinkedIn complet sans y toucher sauf pour le lien final qui pointe la source pas le lien LinkedIn)</p>
<p>Je ne suis pas du tout étonné de ce résultat ! J&#39;ajouterai même une sur utilisation de Tailwind CSS (c&#39;est d&#39;ailleurs cité dans l&#39;étude) car c&#39;est plus facile de laisser les LLMs faire du Tailwind CSS que de leur faire faire du CSS 🤷‍♂️ </p>
<p>Rappelez-vous d&#39;une chose super importante : quand vous utilisez des LLMs pour le code, c&#39;est VOUS qui devez faire les choix de technologie et d&#39;architecture, sauf si vous ne voulez pas maîtriser votre projet et aller dans le mur à un moment ! </p>
<h3 id="article-mcp-is-dead-long-live-the-clihttpsejholmesgithubio20260228mcpisdeadlonglivetheclihtml"><a href="https://ejholmes.github.io/2026/02/28/mcp-is-dead-long-live-the-cli.html">MCP is dead. Long live the CLI</a><a href="#article-mcp-is-dead-long-live-the-clihttpsejholmesgithubio20260228mcpisdeadlonglivetheclihtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #MCP</p>
<p>L&#39;article est intéressant parce qu&#39;on a vu émergé une alternative aux API REST sous la forme d&#39;une nouvelle forme d&#39;API alors qu&#39;on aurait simplement pu pousser massive à la création de CLI pour tous les tools qui n&#39;avait pas de CLI. </p>
<p>Et en effet j&#39;avais pas réalisé qu&#39;on consommait plus de token en MCP qu&#39;en CLI. En plus d&#39;avoir moins de capacité à l&#39;utiliser nous en tant qu&#39;humain 🙃 </p>
<h3 id="article-claude-code-vatil-nous-remplacer---olivier-poncethttpsyoutube4lh_ag57dxs"><a href="https://youtu.be/4Lh_AG57dXs">Claude code va-t-il nous remplacer ? — Olivier Poncet</a><a href="#article-claude-code-vatil-nous-remplacer---olivier-poncethttpsyoutube4lh_ag57dxs" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Claude #Dev</p>
<p><a href="https://youtu.be/4Lh_AG57dXs"><img src="https://anthonypena.fr/2026/03/03/revue-de-presse-mars/img/youtube-4Lh_AG57dXs.jpg" alt="https://youtu.be/4Lh_AG57dXs" title="Youtube video preview"/></a></p>
<p>Vidéo super intéressante sur un sujet d&#39;actualité : l&#39;IA et Claude Code.</p>
<p>Pour faire un résumé très grossier : non l&#39;IA ne va pas remplacer les devs, on va juste devoir passer plus de temps sur la définition des spécifications, de la documentation, etc. En fait tout ce qui est autour du code, tout ce qui est souvent négligé.</p>
<p>Les IAs (enfin plutôt les LLMs de code) ne remplaceront pas les humains, ils vont nous faire gagner du temps sur tout ce qui est répétitif et mécanique. On va pouvoir se concentrer sur ce qui est important.</p>
<p>Par contre, il faut partir du principe que l&#39;IA a tort par défaut, l&#39;IA doit être très largement cadrée pour pouvoir produire le même niveau de qualité de code que vous auriez fait sans IA.</p>
<p>Exemple cité par Olivier : un projet web qu&#39;il a réalisé en 3 jours, donc une grosse journée et demie à raffiner le besoin et les spécifications et une maquette interactive, avant de passer à l&#39;implémentation réelle. Le genre de projet que sur LinkedIn on verrait beaucoup annoncer avoir codé en 2-3h en vibe codant… L&#39;IA c&#39;est un outil, soyez en maître ou oui vous serez remplacé !</p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-attention-votre-imprimante-pourrait-bientot-ne-plus-fonctionner-a-cause-de-windows-11-httpswwwgenerationntcomactualiteswindows11microsoftimprimantepiloteobsolescence2070410"><a href="https://www.generation-nt.com/actualites/windows-11-microsoft-imprimante-pilote-obsolescence-2070410">Attention, votre imprimante pourrait bientôt ne plus fonctionner à cause de Windows 11 !</a><a href="#article-attention-votre-imprimante-pourrait-bientot-ne-plus-fonctionner-a-cause-de-windows-11-httpswwwgenerationntcomactualiteswindows11microsoftimprimantepiloteobsolescence2070410" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Windows #Microsoft #Hardware #Sécurité #Imprimante</p>
<p>Je cite :</p>
<blockquote>
<p>La raison invoquée par la firme de Redmond est encore une fois la même que pour Windows 11 : la sécurité. Les anciens pilotes d&#39;imprimantes, spécifiquement les versions V3 (héritée de Windows Vista) et V4 (Windows 8), sont considérés comme un véritable talon d&#39;Achille pour le système d&#39;exploitation.</p>
</blockquote>
<p>Mais du coup une imprimante parfaitement fonctionnelle devrait aller à la casse parce qu&#39;aussi bien les constructeurs et Microslop en a décidé ainsi ? Une solution proposée c&#39;est d&#39;utiliser un serveur d&#39;impression sous Linux (comprendre : une petite machine sous Linux, brancher à l&#39;imprimante et au réseau pour faire intermédiaire, parce que sous Linux, tant que ça marche côté hardware, ça marchera côté software)… </p>
<p>Y&#39;a un monde où on arrête d&#39;accepter que Microslop décide pour tout le monde comme ça ? Parce qu&#39;à un moment si les anciens pilotent ont des trous de sécurités la solution c&#39;est corriger les pilotes pas jeter les imprimantes… </p>
<p>Edit : je me suis fait avoir comme beaucoup de monde, y compris la rédaction de Génération NT, en fait Microsoft a annoncé l&#39;arrêt de la mise à jour des anciens index d&#39;imprimantes, qui ont été remplacés petit à petit depuis 2014 par un nouveau système. Pour plus de détail, je vous renvoie vers l&#39;article de <a href="https://www.minimachines.net/actu/vieille-imprimante-windows-11-139364">Pierre de Minimachines</a></p>
<h3 id="article-pres-dune-publicite-sur-trois-sur-meta-menerait-vers-une-arnaque-ou-un-malwarehttpswwwphonandroidcompresdunepublicitesurtroissurmetameneraitversunearnaqueouunmalwarehtml"><a href="https://www.phonandroid.com/pres-dune-publicite-sur-trois-sur-meta-menerait-vers-une-arnaque-ou-un-malware.html">Près d’une publicité sur trois sur Meta mènerait vers une arnaque ou un malware</a><a href="#article-pres-dune-publicite-sur-trois-sur-meta-menerait-vers-une-arnaque-ou-un-malwarehttpswwwphonandroidcompresdunepublicitesurtroissurmetameneraitversunearnaqueouunmalwarehtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité</p>
<blockquote>
<p>’après une enquête de Gen Digital relayée par TechRadar, 14,57 millions de publicités Meta ont été analysées sur une période de 23 jours dans l’Union européenne et au Royaume-Uni. Ces annonces représentaient 10,76 milliards d’impressions. Les chercheurs estiment que 4,51 millions d’entre elles étaient liées à des campagnes frauduleuses. Cela correspond à 30,99 % des publicités étudiées. Au total, ces annonces malveillantes ont généré plus de 304 millions d’impressions en moins d’un mois.</p>
</blockquote>
<p>Et on se demande pourquoi on est beaucoup dire qu&#39;un bloqueur de pub / anti-trackeur est nécessaire pour surfer en sécurité ! Mais après on entendra que les GAFAM font tout ce qu&#39;ils peuvent pour nous protéger… </p>
<h3 id="article-tpms--vos-pneus-balancent-votre-position-en-clair--korbenhttpskorbeninfotpmstrackingvoiturecapteurspneushtml"><a href="https://korben.info/tpms-tracking-voiture-capteurs-pneus.html">TPMS - Vos pneus balancent votre position en clair - Korben</a><a href="#article-tpms--vos-pneus-balancent-votre-position-en-clair--korbenhttpskorbeninfotpmstrackingvoiturecapteurspneushtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Vie-privée #Sécurité #Voiture</p>
<blockquote>
<p>En effet, une équipe d&#39;IMDEA Networks et d&#39;armasuisse (le labo de défense suisse, rien que ça) a posé 5 récepteurs SDR dans une ville pendant 10 semaines. Coût du matos, environ 100 dollars par capteur, qui est en gros un Raspberry Pi 4 avec un dongle RTL-SDR à 25 balles. Et grâce à cela, ils ont capté plus de 6 MILLIONS de messages, provenant de plus de 20 000 véhicules !</p>
</blockquote>
<p>À priori toutes les voitures construites à partir de 2014 ont forcément du TPMS en Europe, y&#39;a aucun chiffrement, aucune authentification, et y&#39;a un identifiant unique qui est diffusé à rythme régulier… Avec même pas 100€ on peut monter un sniffeur de TPMS pour fliquer tout le monde 🤦‍♂️ </p>
<p>On peut faire quoi de notre côté ? Rien. Y&#39;a aucune option pour couper ça ou le rendre plus sécurisé… </p>
<h3 id="article-cultivating-a-robust-and-efficient-quantumsafe-httpshttpssecuritygoogleblogcom202602cultivatingrobustandefficienthtmlm1"><a href="https://security.googleblog.com/2026/02/cultivating-robust-and-efficient.html?m%3D1">Cultivating a robust and efficient quantum-safe HTTPS</a><a href="#article-cultivating-a-robust-and-efficient-quantumsafe-httpshttpssecuritygoogleblogcom202602cultivatingrobustandefficienthtmlm1" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#HTTP #Web #Google #Cloudflare #Sécurité #TLS #Quantique</p>
<p>Google et Cloudflare au sein d&#39;un groupe de travail de l&#39;IETF sont en phase de test d&#39;un potentiel remplaçant de TLS pour HTTPS pour avoir un chiffrement qui résiste aux ordinateurs quantiques. </p>
<p>Ce serait un mode de fonctionnement très différents au niveau de la création des certificats et de leur validation mais à voir ce que ça donnera. </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-the-only-developer-productivity-metrics-that-matterhttpsgenehackblog202602theonlydeveloperproductivitymetricsthatmatter"><a href="https://genehack.blog/2026/02/the-only-developer-productivity-metrics-that-matter/">The only developer productivity metrics that matter</a><a href="#article-the-only-developer-productivity-metrics-that-matterhttpsgenehackblog202602theonlydeveloperproductivitymetricsthatmatter" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Métier-de-dev #Culture-d&#39;équipe #Collaboration #Dev</p>
<blockquote>
<p>So, here’s the deal, just in case you’ve forgotten or were never told: pretty much every single way management tries to measure software team productivity is bullshit. You’re not measuring what you think you’re measuring, generally; what you are measuring is how good your dev team is at gaming your metrics. (Spoiler: they’re probably going to be extremely good, especially if they’re experienced.) I assume everybody has heard the “we paid bonuses for fixing bugs” story — or if you haven’t, you can probably extrapolate — but the key thing here is: almost every single thing you can measure, the devs can game.</p>
<p>Here are the only two things you should be worried about when it comes to the question of how productive a given team of software developers is:</p>
<ol>
<li>How often does the team routinely ship new versions of the software they build?</li>
<li>How often do things break when the team ships a new version?</li>
</ol>
<p><strong>THAT’S IT.</strong> Story points per sprint doesn’t matter; lines of code, doesn’t matter; Jira tickets closed, for the love of everything, do. not. matter.</p>
<p>[…]</p>
<ol start="3">
<li>How often does a new version of the software the team builds spark actual joy in the people who have to use it?</li>
</ol>
</blockquote>
<p>Je suis tellment d&#39;accord ! </p>
<p>Imaginons que l&#39;objectif soit de livrer un maximum de ticket : qu&#39;est-ce qui m&#39;empêche de créer un max de ticket avec presque rien dedans ? </p>
<p>Imaginons que l&#39;objectif soit de &quot;produire plus&quot; et que ce soit mesuré via les story points : qu&#39;est-ce qui m&#39;empêche de sur-estimer chaque ticket ? </p>
<p>Imaginons que l&#39;objectif soit juste de livrer le plus souvent possible : livrons chaque ticket en production directement ! </p>
<p>Imaginons qu&#39;on mesure que la vitesse de correction des bugs : introduisons exprès des bugs tout bête qu&#39;on peut livrer super vite ! </p>
<p>Etc. Etc. </p>
<p>Si vous prenez des métriques qui n&#39;ont pas de sens : les gens trouveront un moyen de jouer avec la métrique ! </p>
<h3 id="article-a-candlepowered-light--hackadayhttpshackadaycom20260223acandlepoweredlight"><a href="https://hackaday.com/2026/02/23/a-candle-powered-light/">A Candle-Powered Light | Hackaday</a><a href="#article-a-candlepowered-light--hackadayhttpshackadaycom20260223acandlepoweredlight" class="anchor" aria-label="permalink">🔗</a></h3>
<p>Allumer une bougie produit 2 choses : de la lumière (ce pourquoi on allume la bougie en général) et de la chaleur (qui est généralement perdue). </p>
<p>Là cette personne s&#39;est dit qu&#39;on devait pouvoir transformer cette chaleur en énergie électrique (via l&#39;effet Peltier)  et s&#39;en servir pour alimenter 2 LEDs qui produiront elle-même de la lumière (en théorie aussi un peu de chaleur mais bon une LED de ce genre ça produit presque rien comme chaleur, c&#39;est pour ça que c&#39;est considéré comme plutôt efficient et moins consommateur en énergie que d&#39;autres systèmes). </p>
<p>Dans la vidéo il arrive à un pique à 0.40W donc vraiment pas grand-chose ! Mais c&#39;est déjà super cool d&#39;avoir réussi et c&#39;est sûrement exploitable autrement, genre avec un condensateur qui allumerait les LED dès que y&#39;a plus de production d&#39;énergie à partir de la chaleur de la bougie (comprendre = quand la bougie va s&#39;éteindre), comme ça on capte la chaleur de la bougie pour éclairer plus longtemps que la bougie plutôt qu&#39;en parallèle ! </p>
<p>Je trouve l&#39;idée intéressante ! </p>
<h3 id="article-plan-9-le-systeme-dexploitation-du-futur--olivier-poncethttpsyoutubegiivpkuir4"><a href="https://youtu.be/G-iivPkuiR4">Plan 9, le système d&#39;exploitation du futur — Olivier Poncet</a><a href="#article-plan-9-le-systeme-dexploitation-du-futur--olivier-poncethttpsyoutubegiivpkuir4" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#OS #Plan-9</p>
<p><a href="https://youtu.be/G-iivPkuiR4"><img src="https://anthonypena.fr/2026/03/03/revue-de-presse-mars/img/youtube-G-iivPkuiR4.jpg" alt="https://youtu.be/G-iivPkuiR4" title="Youtube video preview"/></a></p>
<p>Système d&#39;exploitation d&#39;une autre époque pourtant toujours maintenu par des indépendants (et aussi fortement forké, on peut citer Inferno OS comme fork important), propose énormément de concept intéressant !</p>
<p>Franchement je serais curieux de choper un laptop ultra low spec et utiliser Plan 9 au quotidien pendant quelques semaines pour voir ce que ça donne en 2026 !</p>
<h3 id="article-your-personal-blog-should-have-comments--via-le-hollandais-volanthttpslehollandaisvolantnetid20260220171312"><a href="https://lehollandaisvolant.net/?id%3D20260220171312">Your Personal Blog Should Have Comments — via Le Hollandais Volant</a><a href="#article-your-personal-blog-should-have-comments--via-le-hollandais-volanthttpslehollandaisvolantnetid20260220171312" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Blog #Web</p>
<p>L&#39;article initial pousse l&#39;idée qu&#39;avoir un blog devrait impliquer qu&#39;on puisse commenter les articles. Je comprends l&#39;idée, je comprends l&#39;apport, je sais que je serai capable d&#39;avoir un widget de commentaire que mon blog (quand bien même c&#39;est du SSG) mais je suis d&#39;accord avec Timo : je n&#39;ai pas envie. </p>
<p>J&#39;aime avoir des retours sur mon contenu, savoir qu&#39;on me lit, savoir que ça sert à des gens que je mette tout ça en ligne, mais les commentaires sur le blog, à mon avis ce serait mauvais pour plein de raisons :</p>
<ul>
<li>c&#39;est difficile d&#39;éviter le spam (<a href="https://blog.seboss666.info/2025/08/note-de-service-je-coupe-les-commentaires/">le genre de galère que c&#39;est</a>);</li>
<li>ça m&#39;ajouterait un travail de modération en plus ;</li>
<li>beaucoup trop de gens se battent dans les commentaires, en étant pas du tout constructif au global quand bien même y&#39;a un fond intéressant à prendre ;</li>
<li>en tant que diffuseur de contenu (ce qu&#39;on est en tant que blogueur), on est responsable du contenu qu&#39;on héberge, pas qu&#39;on écrit, mais bien qu&#39;on héberge, donc les commentaires aussi (certes y&#39;a toujours l&#39;option d&#39;une modération avant mise en ligne visible mais ça veut dire être très réactif) ;</li>
</ul>
<p>Timo indique recevoir régulièrement des réponses par mails, moi j&#39;ai régulièrement des commentaires sur LinkedIn ou des messages privés. Ça me va très bien comme ça ! </p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Les trucs à lire dans votre vie de dev]]></title>
      <guid isPermaLink="false">2026/02/18/les-trucs-a-lire-dans-votre-vie-de-dev</guid>
      <description><![CDATA[<p>On m&#39;a déjà demandé ce que je pouvais recommander comme lecture pour s&#39;améliorer en tant que dévelop…</p>
]]></description>
      <link>https://anthonypena.fr/2026/02/18/les-trucs-a-lire-dans-votre-vie-de-dev/index.html</link>
      <category><![CDATA[Avis]]></category>
      <category><![CDATA[Métier de dev]]></category>
      <pubDate>Wed, 18 Feb 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>On m&#39;a déjà demandé ce que je pouvais recommander comme lecture pour s&#39;améliorer en tant que développeur. J&#39;ai fini par écouter cette demande (particulièrement merci à toi Bich de m&#39;avoir vraiment poussé sur ce sujet même si j&#39;aurai mis du tout à le faire !) et me poser sur ce guide !</p>
<h2 id="article-avantpropos">Avant-propos<a href="#article-avantpropos" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je vous avoue que l&#39;exercice est à mon sens assez difficile :</p>
<ul>
<li>les livres techs ça coûte souvent cher (même très cher) ;</li>
<li>il n&#39;y a pas une grosse offre côté occasion (même si vraiment il faut fouiller, ça vaut le coût !) ;</li>
<li>la masse des livres traitent d&#39;une version d&#39;un langage / outil / plateforme et sont vite dépassés ;</li>
<li>il faut se concentrer sur les livres qui partage des concepts / idées pour avoir quelque chose de plutôt intemporel ;</li>
<li>il y a souvent plusieurs éditions des livres, plus ou moins modernes, mais pour les livres à concept une ancienne édition fonctionne généralement très bien ;</li>
<li>pour moi le plus difficile pour les débutants : le gros de la littérature est en anglais, anglais un peu soutenu / formel, avec un vocabulaire pas toujours simple… ;</li>
</ul>
<p>J&#39;ai donc mis dû temps à écrire cet article parce que je voulais me laisser le temps de bien choisir le contenu qui allait y figurer ! Si à la base j&#39;étais resté focus sur des livres papiers, je me suis finalement décidé à inclure d&#39;autres ressources qui pour moi vont parfaitement dans cette catégorie.</p>
<h2 id="article-__lopen-space-ma-tuer__httpswwwbabeliocomlivresisnardslopenspacematuer1271110--alexandre-des-isnards"><a href="https://www.babelio.com/livres/Isnards-Lopen-space-ma-tuer/1271110"><strong>L&#39;open space m&#39;a tuer</strong></a> — Alexandre des Isnards<a href="#article-__lopen-space-ma-tuer__httpswwwbabeliocomlivresisnardslopenspacematuer1271110--alexandre-des-isnards" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je commence par un livre qui n&#39;est pas du tout tech paradoxalement, mais que je trouve hyper important à lire, particulièrement en début de carrière, quand bien même je l&#39;ai moi-même lu que l&#39;année dernière.</p>
<p><em>L&#39;open space m&#39;a tuer</em> est un livre qui m&#39;a marqué car il évoque ce que c&#39;est que de travailler dans un open space, de tout ce que ça implique, surtout de négatif. C&#39;est quelque chose que je pense ait difficile à vraiment anticiper avant de l&#39;avoir vécu. Je pense que ce livre m&#39;aurait vraiment aidé.</p>
<p>Travailler en open space c&#39;est subir un bruit constant, subir les échanges des autres personnes présentes, se gêner continuellement les uns les autres, ne pas avoir d&#39;espace à soi (merci le sacro-saint flex office qui accompagne souvent l&#39;open space), c&#39;est voir / sentir les aller et venus de tout le monde continuellement, etc.</p>
<p>Ce livre est vraiment le symbole de tout ce qui se fait de pire dans l&#39;open space. C&#39;est une lecture très facile à mon sens, ça permet de bien se rendre compte de comment on vit l&#39;open space mais aussi le travail de bureau avec tous ses codes, tous ses rituels, tous ses faux-semblants.</p>
<p>Quand bien même il y a des intérêts sociaux à l&#39;open space, je pense qu&#39;il y a surtout des inconvénients, particulièrement quand c&#39;est mal vu de bosser avec un casque et de la musique pour s&#39;isoler dans sa bulle…</p>
<p>Bref, un livre pas tech, mais qui représente un aspect important du travail de développeur, même si vous avez déjà de l&#39;expérience : c&#39;est un livre à lire !</p>
<h2 id="article-__12-factors-app__https12factornetfr--adam-wiggins"><a href="https://12factor.net/fr/"><strong>12 factors app</strong></a> — Adam Wiggins<a href="#article-__12-factors-app__https12factornetfr--adam-wiggins" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Avant de passer à un autre livre, je vais passer sur la première ressource web. J&#39;ai mis le lien vers la traduction française du site (traduction officielle, créé de manière collaborative sur le github 12factor), mais il existe aussi une version ebook (format epub, reprenant strictement le contenu de la version anglaise du site) qui n&#39;est par contre elle disponible qu&#39;en anglais. À vous de voir.</p>
<p>Le contenu est assez court (environ 25 pages au format livre), mais c&#39;est un livre qu&#39;on devrait tous avoir lu au moins une fois et même relire régulièrement !</p>
<p>On va y retrouver un tas de bonne pratique de conception d&#39;une application en termes de construction, de déploiement, de configuration, monitoring, et tout ce qui va avec. On parle clairement de principes DevOps ici, mais sans forcer la référence à une technologie en particulier. Ici personne ne vous dira que vous devez faire une Kubernetes avec une image particulière, mais quelle méthodologie vous devriez utiliser peu importe la plateforme ou le langage.</p>
<p>J&#39;ai lu ça en tout début de carrière, et clairement ça a été une brique fondamentale de ma manière de penser les applications ensuite.</p>
<h2 id="article-__refactoring__httpswwwbabeliocomlivresfowlerrefactoring1341944--martin-fowler"><a href="https://www.babelio.com/livres/Fowler-Refactoring/1341944"><strong>Refactoring</strong></a> — Martin Fowler<a href="#article-__refactoring__httpswwwbabeliocomlivresfowlerrefactoring1341944--martin-fowler" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Ici on parle d&#39;un livre d&#39;un maître de l&#39;informatique : Martin Fowler.</p>
<p>C&#39;est un livre qui est très didactique, très orienté cas concret, avec beaucoup de méthodes. J&#39;aime beaucoup ce livre, car il remet au centre du sujet le refactoring alors que c&#39;est quelque chose qui est souvent relégué au second plan, une étape optionnelle qu&#39;on ne fait que si on a le temps…</p>
<p>Refactoring va vous aider à vous projeter et à prendre du recul sur votre code. Il va vous aider en vous proposant des schémas reconnaissables pour améliorer votre code et vous assurer qu&#39;il pourra évoluer, qu&#39;il sera maintenable dans le temps, tout en vous fixant les bonnes limites, en vous posant les bonnes questions, en aidant à ne pas casser le projet en faisant ça.</p>
<p>Tous les exemples sont en Java, car c&#39;est un des langages que Martin Fowler maitrise bien tout simplement, mais ne vous inquiétez pas de voir des éléments compliqués de Java moderne : il a été écrit en 1999, on est donc face à du très vieux Java (version 1.2), et plus ou moins tout est transposable à n&#39;importe quel autre langage.</p>
<p>C&#39;est un livre qui sera souvent trouvable neuf assez chers (50-100€), mais si vous cherchez un peu et/ou êtes patient, vous le trouverez assez souvent à une dizaine d&#39;euros. À priori peu importe l&#39;édition, le contenu ne change pas : j&#39;ai une copie imprimé en 2012 mais indiqué comme l&#39;édition de 1999. Tout le contenu est toujours d&#39;actualité, au pire on peut faire encore mieux avec du Java plus moderne !</p>
<blockquote>
<p>Note : j&#39;ai parfois vu des livres qui semblent être des versions françaises de Refactoring, et mes recherches me laissent penser que le livre n&#39;a pas été officiellement traduit. Donc je ne peux que vous orienter vers l&#39;original en anglais, car c&#39;est un anglais assez simple à lire et vous serez certain de la qualité du contenu.</p>
</blockquote>
<h2 id="article-__design-driven-development__httpswwwbabeliocomlivresevansdomaindrivendesign949958--eric-evans"><a href="https://www.babelio.com/livres/Evans-Domain-Driven-Design/949958"><strong>Design Driven Development</strong></a> — Eric Evans<a href="#article-__design-driven-development__httpswwwbabeliocomlivresevansdomaindrivendesign949958--eric-evans" class="anchor" aria-label="permalink">🔗</a></h2>
<p>C&#39;est clairement un livre de référence.</p>
<p>C&#39;est aussi un livre difficile à lire…</p>
<p>Je reste partagé par ce livre. Je suis globalement d&#39;accord pour dire qu&#39;on devrait appliquer à peu près tous les principes de DDD, mais je trouve que le livre est aussi assez difficile à lire et comprendre. Je pense que c&#39;est un livre qui mérite d&#39;être lu mais plutôt par morceau en revenant dessus régulièrement.</p>
<p>Je n&#39;ai jamais réussi à finir ce livre à date, mais tout ce que j&#39;en ai lu à changer ma manière de penser les projets. Et aussi fait réalisé qu&#39;on loupe des étapes fondamentales…</p>
<p>Un exemple qui m&#39;a vraiment marqué : l&#39;ubiquitous language, avoir un langage (au sens : un vocabulaire) unique, clairement défini, qui repose la définition de chaque terme qui peut prêter à confusion pour quelqu&#39;un d&#39;extérieur au projet, avec si possible aucun ou presque synonyme, aucun &quot;à peu près&quot;, etc. Tout ce qu&#39;il faut pour que deux personnes, peu importe leur rôle dans l&#39;équipe parle des mêmes entités métiers avec le même vocabulaire et se comprennent sans aucune ambiguïté. Ça parait évident et pourtant je n&#39;ai jamais vu ça appliqué…</p>
<p>Je pense que c&#39;est un livre dont il faut au moins lire les premiers chapitres qui sont fondamentaux et au pire basculer sur des ressources en ligne pour compléter.</p>
<h2 id="article-the-agile-manifestohttpsagilemanifestoorgisofrmanifestohtml--extreme-programminghttpwwwextremeprogrammingorg"><a href="https://agilemanifesto.org/iso/fr/manifesto.html">The Agile Manifesto</a> &amp; <a href="http://www.extremeprogramming.org/">Extreme Programming</a><a href="#article-the-agile-manifestohttpsagilemanifestoorgisofrmanifestohtml--extreme-programminghttpwwwextremeprogrammingorg" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je regroupe les deux car pour moi c&#39;est plus ou moins la même chose, car écrit plus ou moins par les mêmes personnes.</p>
<blockquote>
<p>Note : pour les puristes qui passeraient pas ici, je sais que The Agile Manifesto et Extreme Programming c&#39;est différent, MAIS pour moi on retrouve à peu près les mêmes idées, juste que Extreme Programming est pour moi plus précis, plus détaillé que The Agile Manifesto, un peu comme Scrum / Kanban.</p>
</blockquote>
<p>Ces deux textes sont le socle de toutes les méthodes agiles : des principes et guides pour comprendre comment organiser un projet (au sens large) et comment l&#39;équipe projet doit s&#39;intégrer à l&#39;organisation de l&#39;entreprise et interagir avec les utilisateurs.</p>
<p>Ce ne sont pas des textes qui sont dirigistes mais plutôt qui vont vous aider à définir un cadre de travail saint, un cadre de travail où vous allez pouvoir délivrer de la valeur tout en vous adaptant aux changements (particulièrement aux changements dus à l&#39;écart entre ce dont vos utilisateurs pensent avoir besoin et ce dont ils ont besoins réellement).</p>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Même si je ne devrais pas vraiment dire ça, mais si vous n&#39;avez pas les moyens / ne vous sentez pas capable de lire un livre comme ça en anglais : n&#39;hésitez pas à jeter un coup d&#39;œil sur des sites comme Anna&#39;s Archive pour trouver une version epub et jeter un coup d&#39;œil. Il sera toujours temps d&#39;acheter le livre plus tard quand l&#39;occasion se présentera !</p>
<p>J&#39;espère vous avoir donné envie d&#39;aller lire au moins une partie de ces livres / contenus avec mon article, en tout cas pour moi il s&#39;agit de lecture qui m&#39;ont vraiment été utile, et peut-être que ça pourrait l&#39;être pour vous aussi !</p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>A cozy, Ghibli-inspired illustration of a futuristic yet organic library. The scene features curved wooden bookshelves filled with floating books, including recognizable titles like &quot;Domain-Driven Design&quot; by Eric Evans, &quot;Refactoring&quot; by Martin Fowler, &quot;The Agile Manifesto,&quot; and &quot;Extreme Programming.&quot; A red panda, sitting cross-legged on a pile of books, holds a parchment with DevOps principles and code diagrams written on it. Around the red panda, holograms of keywords like &quot;Ubiquitous Language&quot; and &quot;Clean Code&quot; gently float in the air. Soft light filters through stained glass windows depicting autumn leaves, casting a warm golden glow over the scene. In the background, a Ghibli-inspired robot organizes books on the shelves. The atmosphere is serene, blending technology and nature, with a focus on timeless knowledge and the harmony between tradition and modernity.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Nouveau blog --  partie 4 : et le reste...]]></title>
      <guid isPermaLink="false">2026/02/10/nouveau-blog-partie-4-et-le-reste</guid>
      <description><![CDATA[<p>Dans cet article je vais parler en vrac de tous les petits trucs qui font que tout fonctionne et qu&#39;…</p>
]]></description>
      <link>https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/index.html</link>
      <category><![CDATA[Web]]></category>
      <category><![CDATA[Frontend]]></category>
      <pubDate>Tue, 10 Feb 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Dans cet article je vais parler en vrac de tous les petits trucs qui font que tout fonctionne et qu&#39;on voit moins : le flux RSS, le déploiement chaque matin, des problèmes aussi… </p>
<nav data-serie="nouveau-blog-marked-deno">
<h2>Série d'article</h2>
<ul>
<li><a href="https://anthonypena.fr/2026/01/15/nouveau-blog-partie-1-html/index.html">Nouveau blog -- partie 1 : HTML</a></li>
<li><a href="https://anthonypena.fr/2026/01/21/nouveau-blog-partie-2-css/index.html">Nouveau blog -- partie 2 : CSS</a></li>
<li><a href="https://anthonypena.fr/2026/01/27/nouveau-blog-partie-3-js/index.html">Nouveau blog -- partie 3 : JavaScript</a></li>
<li><a href="https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/index.html">Nouveau blog --  partie 4 : et le reste...</a></li>
</ul>
</nav>
<h2 id="article-le-flux-rss">Le flux RSS<a href="#article-le-flux-rss" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Le flux RSS c&#39;est une brique qui est devenue quasiment inconnu alors que c&#39;est un outil hyper pratique : vous pouvez suivre les publications de n&#39;importe qui (pour peu qu&#39;il mette à disposition un flux RSS) sans aucun réseau social, sans aucune brique centralisée, en décidant vous-même à quelle fréquence vous souhaitez relever les flux (adieu la pollution de l&#39;attention à cause des notifications), en décidant vous-même de qui vous allez suivre (adieu les réseaux comme Youtube qui vous désabonne sans rien dire ou comme Twitter (non je dirais pas &quot;X&quot;) qui vous force à suivre son propriétaire mégalo), avec le client de votre choix pour avoir la vue qui vous convient le mieux.</p>
<p>Par exemple, j&#39;ai fait le choix d&#39;avoir ma propre instance <a href="https://www.freshrss.org/">FreshRSS</a> que je consulte essentiellement via mon smartphone et l&#39;application <a href="https://github.com/ReadYouApp/ReadYou">Read You</a></p>
<figure id="image-gallery-differentes-vue-de-read-you-sur-mon-smartphone" class="marked-image-gallery" is="gallery-zoom">
<img src="https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/img/read-you-1.jpg" alt="Différentes vue de Read You sur mon smartphone"/>
<img src="https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/img/read-you-2.jpg" alt="Différentes vue de Read You sur mon smartphone"/>
<img src="https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/img/read-you-3.jpg" alt="Différentes vue de Read You sur mon smartphone"/>
<figcaption>Différentes vue de Read You sur mon smartphone</figcaption>
</figure>
<p>Je l&#39;utilise pour suivre des gens que je connais (coucou Nicolas Brondin-Bernard 👋 qui apparait en screenshot, coucou aussi Siegfried 👋), des gens que je ne connais pas (en tout cas pas personnellement, mais les années passant je &quot;connais&quot; bien leur identité en ligne, par exemple Sebsauvage, Seboss666, Korben ou Pierre de minimachines.net), je suis aussi les mises à jours sur des projets Github (par exemple, je suis les mises à jour de FreshRSS comme ça pour avoir tout le détail des releases), Lobsters (qui est un agrégateur de contenu collaboratif), l&#39;actualité mobile / jeux-vidéos / mangas, etc. Je fais l&#39;essentiel de ma veille via du RSS.</p>
<p>Je l&#39;ai montré plus haut : je suis aussi mon propre flux RSS. Pas par égocentrisme, mais pour m&#39;assurer qu&#39;il fonctionne et qu&#39;on voit bien apparaitre mon contenu dans ce flux, vérifier que le contenu est complet aussi, qu&#39;il n&#39;y a pas de bug particulier. (et c&#39;est en disant ça que je vois un bug qui fait que les images ne s&#39;affichent pas, donc je fais une pause dans l&#39;écriture pour corriger ça 🫠)</p>
<p>Il y a des bonnes librairies qui permettent de générer un flux RSS, mais au fond ce n&#39;est qu&#39;un fichier XML, avec des balises spécifiques, donc c&#39;est assez facile de le générer avec un script maison. C&#39;est donc ce que j&#39;ai fait : je produis le flux RSS à la &quot;main&quot;, à chaque build du blog. Vous pouvez donc être informé à chaque nouvel article via mon flux RSS (qui est aussi compatible Atom pour les curieux, je vous laisse aller voir le détail) et lire mon contenu sans même vous rendre sur mon blog : je veux partager, pas générer du trafic, je vous laisse donc le choix.</p>
<h2 id="article-deno-et-typescript-everywhere">Deno et TypeScript everywhere<a href="#article-deno-et-typescript-everywhere" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je ne vais pas refaire un laïus sur le sujet (j&#39;en ai déjà fait un dans la partie 1 de la série) : Deno c&#39;est trop bien, y&#39;a pas de débat pour moi.</p>
<p>J&#39;ai donc choisi cette plateforme pour coder mon blog. Mais comme je vous le dis depuis le début de la série : tout est statique. En effet j&#39;ai écrit un ensemble de script en TypeScript qui vient lire mon contenu Markdown, ajouter ce qu&#39;il faut et produire un site statique. Environ 1200 lignes de TypeScript cerveau-codé (par opposition à vibe-codé, merci Siegfried pour cette expression que j&#39;aime beaucoup), réparti sur une quinzaine de scripts qui font chacun une partie du traitement en séquence.</p>
<p>Sans chercher l&#39;optimisation, mais en utilisant des <code>console.time()</code>/<code>console.timeEnd()</code> pour mesurer le temps de chaque partie (pour savoir si je dois optimiser quelque part un jour), j&#39;ai sur ma machine ça comme mesure de temps avec Deno 2.6.3 :</p>
<pre><code>Prepare env: 79.6ms
List articles files: 2.92ms
Extract metadata: 79.6ms
Convert articles to HTML: 398ms
Copy article statics: 308ms
Copy template statics: 1.66ms
Write raw HTML: 13.8ms
Write article metadata: 6.11ms
Build article pages: 39.0ms
Build full article list: 0.249ms
Build archive pages: 0.682ms
Build index: 1.11ms
Build RSS Feed: 4.01ms
Build server script: 0.308ms
Build: 943ms
</code></pre><p>Moins d&#39;une seconde donc, et on voit que les parties longues c&#39;est la conversion Markdown (presque 400ms) et la copie des fichiers statiques (300ms) pour un total sous la seconde.</p>
<p>Côté pipeline (Github Actions), je suis plutôt autour de 2.5 secondes :</p>
<pre><code>List articles files: 12.1ms
Extract metadata: 137ms
Convert articles to HTML: 856ms
Copy article statics: 1379ms
Copy template statics: 3.39ms
Write raw HTML: 35.8ms
Write article metadata: 18.6ms
Build article pages: 74.3ms
Build full article list: 0.533ms
Build archive pages: 1.38ms
Build index: 1.77ms
Build RSS Feed: 6.24ms
Build server script: 0.504ms
Build: 2545ms
</code></pre><p>On voit là que c&#39;est l&#39;écriture sur le disque qui consomme vraiment beaucoup plus de temps (x4.5) alors que la conversion des fichiers Markdown en HTML n&#39;augmente pas tant que ça (x2).</p>
<p>Dans tous les cas, la performance actuelle de mon système me convient très bien. J&#39;avais peur qu&#39;en étant codant le truc aussi simplement et avec si peu d&#39;effort côté performance ce soit particulièrement lent mais à date ce n&#39;est pas le cas (même si je pourrais clairement faire des optimisations).</p>
<h2 id="article-pipeline-tres-simple">Pipeline très simple<a href="#article-pipeline-tres-simple" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je vous donne mon pipeline qui n&#39;a rien de bien fou :</p>
<pre><code class="hljs language-Yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span> <span class="hljs-string">master</span>
  <span class="hljs-attr">pull_request:</span>
    <span class="hljs-attr">branches:</span> <span class="hljs-string">master</span>
  <span class="hljs-attr">schedule:</span>
    <span class="hljs-comment"># every weekday at 6:00AM (for real: between 6:00AM and 6:30AM)</span>
    <span class="hljs-comment"># les serveur Github sont en UTC donc décalés d&#x27;1h donc mettre 6:00 donne des builds entre 7h00 et 7h30</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">cron:</span> <span class="hljs-string">&quot;0 5 * * 1-5&quot;</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">deploy:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>

    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span> <span class="hljs-comment"># Needed for auth with Deno Deploy</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span> <span class="hljs-comment"># Needed to clone the repository</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Clone</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Deno</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">denoland/setup-deno@v2</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">deno-version:</span> <span class="hljs-string">v2.x</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">step</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">&quot;deno install&quot;</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Fmt</span> <span class="hljs-string">step</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">&quot;deno task fmt:check&quot;</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Lint</span> <span class="hljs-string">step</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">&quot;deno task lint&quot;</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">step</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">&quot;deno task build&quot;</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Upload</span> <span class="hljs-string">to</span> <span class="hljs-string">Deno</span> <span class="hljs-string">Deploy</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">denoland/deployctl@v1</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">project:</span> <span class="hljs-string">&quot;anthonypena-blog&quot;</span>
          <span class="hljs-attr">entrypoint:</span> <span class="hljs-string">&quot;./main.ts&quot;</span>
          <span class="hljs-attr">root:</span> <span class="hljs-string">&quot;./dist&quot;</span><div aria-hidden="true" class="language-tag">Yaml</div>
</code></pre><p>J&#39;ai fait simple. À chaque commit sur la branche <code>master</code>, ou pull request ou chaque matin (j&#39;y reviens plus loin), le pipeline s&#39;enclenche. Ce pipeline va cloner le dépôt dans une image ubuntu (potentiellement je pourrais faire plus optimal ici maintenant que j&#39;y pense), j&#39;installe Deno, j&#39;installe les dépendances de mon projet, je vérifie le formatage du code (pas des Markdown, juste le code du moteur de blog que j&#39;ai codé), je vérifie le lint (que du moteur encore une fois), je lance la construction du blog et pour finir je pousse pour le déploiement (j&#39;y reviendrais plus loin).</p>
<p>Le pipeline complet prend environ 50 secondes.</p>
<p>J&#39;utilise peu de branche (car je travaille seul) mais j&#39;aime bien avoir le pipeline au besoin.</p>
<p>J&#39;ai ajouté une exécution chaque matin pour ajouter le dynamisme qui manquait au côté statique : pour mettre en ligne un article j&#39;ai besoin de recompiler le blog, or, je publie généralement le mardi matin avec un post sur LinkedIn / Twitter à 8h00. Si j&#39;ai tout programmé côté réseaux sociaux ce n&#39;est pas pour avoir une action manuelle pour mettre en ligne l&#39;article lui-même, donc j&#39;ai mis en place une mécanique simple pour vérifier si un article doit être &quot;public&quot; ou pas qui va afficher ou non l&#39;article à partir de la bonne date. Je peux donc au besoin programmer quelques articles d&#39;avance sans effort : tout fonctionne tout seul côté infra.</p>
<p>Par contre, vous l&#39;avez peut-être lu dans les commentaires, j&#39;ai un peu joué avec les heures d&#39;exécution. À la base je voulais une exécution à 7h00 du lundi au vendredi (donc un cron <code>0 7 * * 1-5</code> (minute = 0 ; heure = 7 ; jour du mois = * (=tous) ; mois = * (=tous) ; du lundi au vendredi = 1-5)). Mais ce n&#39;est pas aussi simple… Déjà les runner Github Actions fonctionnent en UTC. Donc demander une exécution à 7h00 UTC implique une exécution à 8h00 heure de Paris… Soit. Je suis passé à <code>0 6 * * 1-5</code>. Et là je me suis rendu compte que l&#39;exécution programmée à &quot;7h00&quot; était plutôt vers &quot;7h30-35&quot; (surement pour des questions de charge de runner), donc comme je veux que l&#39;article soit en ligne à 8h00 pour les réseaux sociaux et un peu avant pour que vous l&#39;ailliez avant ça dans vos lecteurs RSS, ça n&#39;allait pas… Donc j&#39;ai avancé à <code>0 5 * * 1-5</code> pour avoir une construction du blog avant 7h.</p>
<blockquote>
<p>Note : si vous pensez que je parle le cron parfaitement, vous vous trompez. Je suis un utilisateur efficace de Crontab Guru.</p>
<figure>
<img src="https://anthonypena.fr/2026/02/10/nouveau-blog-partie-4-et-le-reste/img/cron-tab-guru.gif" alt="Démonstration de Crontab Guru" is="img-zoom"/>
<figcaption>Démonstration de Crontab Guru</figcaption>
</figure>
</blockquote>
<p>Clairement cette histoire de cron c&#39;est ce qui m&#39;a pris le plus de temps côté pipeline, et je m&#39;y attendais pas… Comme quoi le diable se cache dans les détails… 🥲</p>
<h2 id="article-deno-deploy">Deno Deploy<a href="#article-deno-deploy" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Avec la refonte du blog, j&#39;en ai aussi fini avec le self host. Je suis parfaitement capable d&#39;héberger à la maison ou sur un serveur, mais j&#39;ai choisi la simplicité : je suis passé par Deno Deploy.</p>
<p>Deno Deploy, comme son nom l&#39;indique, est la partie cloud accolé à Deno. Vous n&#39;êtes pas obligé de pousser des applications Deno sur Deno Deploy mais quoi qu&#39;il arrive le moteur qui exécutera votre code sera Deno.</p>
<p>De mon côté, j&#39;ai un site entièrement static ! Ou presque… En fait il y a une toute petite partie qui est dynamique : le routing pour gérer les redirections.</p>
<p>En effet sur Deno Deploy il n&#39;y a pas de manière déclarative de définir des redirections (en self host j&#39;aurai bêtement généré un fichier de config pour nginx par exemple), j&#39;ai donc un script Deno d&#39;une quarantaine de lignes qui prend chaque requête en entrée, regarde si le fichier existe pour le servir directement, sinon fait quelques manipulations :</p>
<ul>
<li>tenter d&#39;ajouter un <code>/index.html</code> pour voir ça existe, ce qui permet que <code>https://anthonypena.fr/2026/01/27/nouveau-blog-partie-3-js</code>, <code>https://anthonypena.fr/2026/01/27/nouveau-blog-partie-3-js/</code> et <code>https://anthonypena.fr/2026/01/27/nouveau-blog-partie-3-js/index.html</code> vous donne la page de l&#39;article ;</li>
<li>voir si une redirection existe dans la liste des redirections pour vous renvoyer un code HTTP <code>301</code> (Moved Permanently, donc votre navigateur vous redirigera directement si vous redemandez l&#39;URL) avec la nouvelle URL ;</li>
<li>gérer quelques cas de 404 proprement ;</li>
</ul>
<p>En effet avec Ghost, j&#39;avais des URLs en <code>k49.fr.nf/ovh-et-vieux-kernel</code> alors que maintenant j&#39;ai décidé que les URLs aurait la forme <code>anthonypena.fr/2016/05/13/ovh-et-vieux-kernel</code> (avec donc la date dans l&#39;URL), je ne voulais pas casser 9 ans de référencement à droite et à gauche, donc j&#39;ai fait en sorte de gérer au maximum les URLs. Je sais qu&#39;il en manque sur des pages plus techniques comme <code>/tag/tutoriel/</code> et <code>/page/2/</code> (remontées par Duck Duck Go via la recherche <code>site:k49.fr.nf</code>) qui vous redirigeront vers la page d&#39;accueil à date, mais c&#39;est plus marginal je pense.</p>
<p>Évidemment, comme j&#39;ai aussi changé de nom de domaine, j&#39;ai aussi mis en place une redirection pour passer de l&#39;ancien domaine au nouveau de manière transparente pour vous.</p>
<h2 id="article-la-ou-ca-grince-encore">Là où ça grince encore<a href="#article-la-ou-ca-grince-encore" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Je n&#39;avais jamais réalisé ça mais mon blog commence à subir le poids des années : le dossier dist pèse un peu plus de 700Mo à date. Vous vous en doutez : c&#39;est essentiellement les images qui pèsent lourd dans la balance.</p>
<p>J&#39;ai été un peu bourrin en copiant tout sans plus de réflexion, mais je sais que je pourrais optimiser ça, déjà en ne copiant que les images vraiment utilisées dans les articles pour éviter de copier des images pour rien. Je pense que je pourrais économiser énormément de poids et donc de temps à uploader le contenu.</p>
<p>Je sais aussi que la page d&#39;accueil est assez longue à charger : il y a beaucoup d&#39;images, là encore ça ne s&#39;invente pas. Mais j&#39;ai des pistes d&#39;améliorations faciles !</p>
<ul>
<li>Passer toutes les images en lazy loading pour que le navigateur les charges en dernier (ça implique de bien gérer la taille des images pour éviter que vous n&#39;aillez trop de layout shift, mais c&#39;est pas compliqué) ;</li>
<li>Profiter d&#39;avoir un peu de code côté serveur pour le routing pour gérer un peu de cache réseau avec les headers de cache adéquat car pour l&#39;instant je me repose entièrement sur le navigateur pour faire les choses bien, et je peux faire mieux ;</li>
<li>produire une version miniature des images spécifiquement pour la page d&#39;accueil de sorte à éviter de charger la version grand format de l&#39;image de couverture ;</li>
</ul>
<p>Je pense que je pourrais optimiser encore plus, mais c&#39;est des pistes évidentes et facile. Je ferai ça dans le futur quand j&#39;aurai du temps pour vraiment me poser là-dessus, en attendant je peux publier du contenu et vous pouvez me lire !</p>
<h2 id="article-conclusion">Conclusion<a href="#article-conclusion" class="anchor" aria-label="permalink">🔗</a></h2>
<p>Cette série arrive enfin à son terme !</p>
<p>Cette refonte me simplifie la vie côté production de contenu, mais évidemment m&#39;ajoute une complexité ailleurs vu que je dois aussi corriger l&#39;affichage sur des appareils divers et variés… Merci à ceux qui me ping pour me pointer un bug, je note et je vais prendre en compte, il y a juste des bugs parfois un peu subtils (oui je pense à toi Romain et ton iphone 8, promis je suis en train de regarder 🫠).</p>
<p>Ça m&#39;ouvre énormément de portes à commencer par la possibilité d&#39;avoir des pages complètement personnalisés pour centraliser tout sur mon site, qui ne sera plus seulement un blog (même si ça restera l&#39;activité principale !).</p>
<p>Merci à ceux qui ont lu toute la série ! Merci évidemment aussi à ceux qui me lisent tout court (que ce soit tout le temps ou de temps en temps) !</p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un port spatial artisanal en bois clair et vieilli, baigné d’une lumière dorée et bleutée tamisée, comme un crépuscule d’automne. Au centre, un panda roux anthropomorphe (Firefox), vêtu d’une veste de capitaine en tissu texturé, supervise le chargement de caisses en bois estampillées &quot;Static HTML&quot; et &quot;Deno Land&quot; sur un vaisseau spatial fait de bois et de cuivre. Le vaisseau, inspiré des machines volantes de Ghibli, est entouré de lanternes en papier flottantes qui guident le chemin vers les étoiles.</p>
<p>Autour du panda roux, des robots miniatures (inspirés des créatures de Ghibli, comme un mélange entre un Totoro et un assistant technique) aident à charger les caisses, tandis qu’un écran holographique (avec un cadre en bois sculpté) affiche une carte stellaire avec des routes vers des planètes nommées &quot;GitHub Pages&quot;, &quot;Netlify&quot;, et &quot;Cloudflare&quot;. Des néons bleutés et des motifs de code binaire flottent dans l’air, comme des étoiles filantes numériques.</p>
<p>En arrière-plan, une grande fenêtre donne sur un ciel étoilé, où des nuages en forme de code binaire reflètent la lumière des lanternes. Une tasse de thé fumant et des parchemins déroulés (symbolisant les logs de déploiement) sont posés sur un bureau en bois, à côté d’un petit robot endormi.</p>
<p>À droite, en bas, le panda roux est légèrement tourné en 3/4 dos, lové sur un coussin, entouré d’un halo lumineux subtil. Il ne dépasse pas le tiers de la hauteur de l’image et observe la scène avec satisfaction, comme s’il contemplait le voyage de son site vers le web.</p>
<p>L’ambiance est cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des jeux de lumière tamisée qui créent des ombres chaleureuses. Les détails sont soignés, avec des textures visibles (grain du bois, tissu de la veste, pelage du panda roux), et une lumière qui met en valeur les éléments tech et artisanaux. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.&quot;&quot;Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un port spatial artisanal en bois clair et vieilli, baigné d’une lumière dorée et bleutée tamisée, comme un crépuscule d’automne. Au centre, un panda roux anthropomorphe (Firefox), vêtu d’une veste de capitaine en tissu texturé, supervise le chargement de caisses en bois estampillées &quot;Static HTML&quot; et &quot;Deno Land&quot; sur un vaisseau spatial fait de bois et de cuivre. Le vaisseau, inspiré des machines volantes de Ghibli, est entouré de lanternes en papier flottantes qui guident le chemin vers les étoiles.</p>
<p>Autour du panda roux, des robots miniatures (inspirés des créatures de Ghibli, comme un mélange entre un Totoro et un assistant technique) aident à charger les caisses, tandis qu’un écran holographique (avec un cadre en bois sculpté) affiche une carte stellaire avec des routes vers des planètes nommées &quot;GitHub Pages&quot;, &quot;Netlify&quot;, et &quot;Cloudflare&quot;. Des néons bleutés et des motifs de code binaire flottent dans l’air, comme des étoiles filantes numériques.</p>
<p>En arrière-plan, une grande fenêtre donne sur un ciel étoilé, où des nuages en forme de code binaire reflètent la lumière des lanternes. Une tasse de thé fumant et des parchemins déroulés (symbolisant les logs de déploiement) sont posés sur un bureau en bois, à côté d’un petit robot endormi.</p>
<p>À droite, en bas, le panda roux est légèrement tourné en 3/4 dos, lové sur un coussin, entouré d’un halo lumineux subtil. Il ne dépasse pas le tiers de la hauteur de l’image et observe la scène avec satisfaction, comme s’il contemplait le voyage de son site vers le web.</p>
<p>L’ambiance est cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des jeux de lumière tamisée qui créent des ombres chaleureuses. Les détails sont soignés, avec des textures visibles (grain du bois, tissu de la veste, pelage du panda roux), et une lumière qui met en valeur les éléments tech et artisanaux. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
    <item>
      <title><![CDATA[Revue de presse - Fevrier 2026]]></title>
      <guid isPermaLink="false">2026/02/04/revue-de-presse-fevrier</guid>
      <description><![CDATA[<blockquote>
<p>Note : Si vous faites partie des gens qui ont vu cet article apparaitre dans leur flux RSS vide hi…</p>
</blockquote>
]]></description>
      <link>https://anthonypena.fr/2026/02/04/revue-de-presse-fevrier/index.html</link>
      <category><![CDATA[Revue de presse]]></category>
      <pubDate>Wed, 04 Feb 2026 06:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<blockquote>
<p>Note : Si vous faites partie des gens qui ont vu cet article apparaitre dans leur flux RSS vide hier : j&#39;en suis désolé, c&#39;est une erreur de ma part et qui a provoqué l&#39;autopublication de cet article avant que je l&#39;ai terminé…</p>
</blockquote>
<h2 id="article-frontend">Frontend<a href="#article-frontend" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-its-hard-to-justify-tahoe-iconshttpstonskymeblogtahoeicons"><a href="https://tonsky.me/blog/tahoe-icons/">It’s hard to justify Tahoe icons</a><a href="#article-its-hard-to-justify-tahoe-iconshttpstonskymeblogtahoeicons" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Apple #UI #UX #Frontend</p>
<p>Je cite directement la conclusion :</p>
<blockquote>
<p>In my opinion, Apple took on an impossible task: to add an icon to every menu item. There are just not enough good metaphors to do something like that.</p>
<p>But even if there were, the premise itself is questionable: if everything has an icon, it doesn’t mean users will find what they are looking for faster.</p>
<p>And even if the premise was solid, I still wish I could say: they did the best they could, given the goal. But that’s not true either: they did a poor job consistently applying the metaphors and designing the icons themselves.</p>
</blockquote>
<p>Franchement l&#39;article est super intéressant ! Et ce n&#39;est pas juste du Apple-baching : qu&#39;on aime ou pas Apple, force est de constater que des patterns de design et d&#39;UX très forts ont émergés chez Apple dès les années 80-90, conduisant à la rédaction du HIG (Human Interface Guideline) ; autant c&#39;est normal que certains trucs évoluent (vu que les pratiques évoluent aussi), mais il ne faut pas le faire n&#39;importe comment, il ne faut pas effacer le travail de recherche qui a été fait dans le passé.</p>
<p>C&#39;est exactement ce qui a été fait récemment chez Apple : on a forcé certains patterns sans forcément être cohérent avec ce que les humains sont capables de suivre / comprendre ou même ce qu&#39;ils attendent. Là l&#39;expemple des icônes est très parlant ! </p>
<p>Pour le coup ça amène à réfléchir sur tout type d&#39;UI, la cohérence, etc. </p>
<h3 id="article-textbased-web-browsershttpscssencecom2026textbasedwebbrowsers"><a href="https://cssence.com/2026/text-based-web-browsers/">Text-based web browsers</a><a href="#article-textbased-web-browsershttpscssencecom2026textbasedwebbrowsers" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Frontend #Web #Navigateur #HTML</p>
<p>On a tendance côté frontend à être beaucoup trop habitué à des navigateurs ultra-modernes comme Firefox ou Chrome, mais il y a d&#39;autres navigateurs. Ils sont peu utilisés aujourd&#39;hui mais les navigateurs textuels sont super intéressants pour plein de raisons !</p>
<p>Personnellement j&#39;aime bien cet article, car il permet de rappeler à quel point le HTML est central, et au passage j&#39;ai découvert des choses que je n&#39;avais jamais croisées :</p>
<ul>
<li>qu&#39;il y a des problèmes d&#39;accessibilités au niveau des data lists… 🫠 ;</li>
<li>l&#39;API Invoker Commands qui permet de déclencher des actions qu&#39;on est censé pouvoir déclencher qu&#39;en JavaScript avec seulement du HTML déclaratif ;</li>
<li>l&#39;attribut <code>inert</code> qui permet de rendre inutilisable certaines parties du contenu ;</li>
</ul>
<p>C&#39;est toujours intéressant de creuser des technologies moins modernes, ça oblige à revenir sur ce qui est important !</p>
<h2 id="article-ia">IA<a href="#article-ia" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-la-fabrique-a-idiots--micodehttpsyoutube4xq6bvbspw"><a href="https://youtu.be/4xq6bVbS-Pw">La Fabrique à Idiots — Micode</a><a href="#article-la-fabrique-a-idiots--micodehttpsyoutube4xq6bvbspw" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#LLM #IA</p>
<p><a href="https://youtu.be/4xq6bVbS-Pw"><img src="https://anthonypena.fr/2026/02/04/revue-de-presse-fevrier/img/youtube-4xq6bVbS-Pw.jpg" alt="https://youtu.be/4xq6bVbS-Pw" title="Youtube video preview"/></a></p>
<blockquote>
<p>Non l&#39;IA ne va pas nous rendre stupides. On va se rendre stupide tout seul en choisissant systématiquement le chemin le plus court.</p>
</blockquote>
<p>C&#39;est la phrase qui résume pour moi parfaitement cette vidéo.</p>
<p>Et je suis totalement d&#39;accord. L&#39;IA c&#39;est un outil. On commence à utiliser massivement l&#39;IA (enfin des LLMs, qui n&#39;ont absolument rien d&#39;intelligent, ce sont juste des boites noires qui vomissent du texte qui tient à peu près la route), en posant notre cerveau, en le laissant travailler, et on va y perdre très fort.</p>
<p>On est en train de vivre une révolution. Pas du genre de la révolution industrielle qui a conduit à réduire le nombre d&#39;ouvrier qui faisaient du travail à la chaise qui les détruisaient mais du genre qui vient couper la phase d&#39;apprentissage de notre vie. C&#39;est un phénomène qui est loin d&#39;être nouveau, c&#39;est ce qu&#39;on appelle le &quot;Google effect&quot;, le fait de ne plus mémoriser certaines informations car on peut les retrouver en une recherche Google (pourquoi notre cerveau retiendrait des centaines d&#39;infos qu&#39;il peut retrouver avec une seule action à connaître ?).</p>
<p>On peut forcer l&#39;IA à être pédagogique, on peut forcer l&#39;IA à aller dans le sens de nous faire progresser. Mais ce n&#39;est pas le réglage par défaut. Par défaut c&#39;est la facilité qui est choisi. Par défaut c&#39;est aller à un résultat pas aider à réfléchir.</p>
<p>Le chemin le plus court c&#39;est aller vers le résultat, ne rien apprendre, ne pas forcément  même comprendre, juste un &quot;ça marche&quot; qui va nous faire perdre des capacités mentales. Choisir le futur c&#39;est chercher par soi même, apprendre, comprendre, peut-être aussi utiliser l&#39;IA pour proposer d&#39;autres pistes, mais développer notre capacité mentale, et donc demain au lieu de repasser 20min à chercher ce sera 5min, et après-demain 1min parce qu&#39;on connaîtra la solution.</p>
<h3 id="article-hitex-press-a-spam-factory-for-aigenerated-bookshttpslaurentlebruneubloghitexaspamfactoryforaigeneratedbooks"><a href="https://laurent.le-brun.eu/blog/hitex-a-spam-factory-for-ai-generated-books">HiTeX Press: A spam factory for AI-generated books</a><a href="#article-hitex-press-a-spam-factory-for-aigenerated-bookshttpslaurentlebruneubloghitexaspamfactoryforaigeneratedbooks" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#IA #Ebook #Livre</p>
<p>À priori si vous voyez un livre / ebook venant de l&#39;éditeur HiTeX, vous pouvez considérer que c&#39;est du &quot;garbage AI&quot;.</p>
<p>Les auteurs semblent ne pas exister, les livres sont produits en masse, et l&#39;exemple sur lequel l&#39;auteur de l&#39;article se penche en particulier (car il concerne un langage qu&#39;il développe lui chez Google) est rempli de contenu faux jusqu&#39;à inventer une runtime qui n&#39;existe pas pour le langage…</p>
<p>Malheureusement, le contenu peut sembler valide de prime abord, particulièrement à un relecteur non-expert… La magie de l&#39;IA et c&#39;est pas fini…</p>
<h2 id="article-securite">Sécurité<a href="#article-securite" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-cybersecurite--pourquoi-il-faut-toujours-demander-le-menu-au-restaurant--avec-des-experts---cyrus-northhttpsyoutubegek9umg6gp8"><a href="https://youtu.be/Gek9uMG6gp8">Cybersécurité : Pourquoi il faut toujours demander le menu au restaurant ? (avec des experts) —  Cyrus North</a><a href="#article-cybersecurite--pourquoi-il-faut-toujours-demander-le-menu-au-restaurant--avec-des-experts---cyrus-northhttpsyoutubegek9umg6gp8" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité #Vie-privée</p>
<p><a href="https://youtu.be/Gek9uMG6gp8"><img src="https://anthonypena.fr/2026/02/04/revue-de-presse-fevrier/img/youtube-Gek9uMG6gp8.jpg" alt="https://youtu.be/Gek9uMG6gp8" title="Youtube video preview"/></a></p>
<p>Table ronde très intéressante sur ce que c&#39;est la cybersécurité.</p>
<p>C&#39;est très orienté grand public, mais il y a tous les sujets de fonds qui sont abordés, tous les sujets importants, avec pas mal de notions importantes :</p>
<ul>
<li>c&#39;est quoi une attaque de masse / une attaque ciblé ?</li>
<li>est-ce qu&#39;on est une cible potentielle ?</li>
<li>comment on se protège ?</li>
<li>à quoi sert à gestionnaire de mot de passe ?</li>
<li>c&#39;est quoi le danger des pubs / trackers ?</li>
<li>comment on protège son identité ? et pourquoi ? et contre quoi ?</li>
<li>etc.</li>
</ul>
<p>Clairement, ça vaut le coup !</p>
<h3 id="article-creepylinkhttpscreepylinkcom"><a href="https://creepylink.com/">CreepyLink</a><a href="#article-creepylinkhttpscreepylinkcom" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Sécurité</p>
<p>Meilleur outil pour faire peur aux personnes qui gèrent la sécurité : un outil qui va créer une version &quot;effrayante&quot; de votre lien.</p>
<p>Par exemple :</p>
<p>J&#39;ai donné à l&#39;outil &quot;<a href="https://press.k49.fr.nf/">https://press.k49.fr.nf/</a>&quot; et il m&#39;a donné &quot;<a href="https://verify.ic6do.com/z6K89n_video_player_update.exe">https://verify.ic6do.com/z6K89n_video_player_update.exe</a>&quot;. Ça pourrait trigger pas mal de système pour le coup.</p>
<p>Est-ce que c&#39;est utile ? Nope… Est-ce que ça peut être drôle ? OUI ! 😈</p>
<h3 id="article-microsoft-gave-fbi-bitlocker-encryption-keys-exposing-privacy-flawhttpssebsauvagenetlinksxhroiq"><a href="https://sebsauvage.net/links/?XhRoIQ">Microsoft Gave FBI BitLocker Encryption Keys, Exposing Privacy Flaw</a><a href="#article-microsoft-gave-fbi-bitlocker-encryption-keys-exposing-privacy-flawhttpssebsauvagenetlinksxhroiq" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Microsoft #Sécurité #Windows</p>
<p>Je cite sebsauvage :</p>
<blockquote>
<p>Microsoft : &quot;Ah non on ne peut pas lire votre disque dur quand il est chiffré avec BitLocker !&quot;
Also Microsoft : Donne au FBI des clés BitLocker qu&#39;il a stockées.</p>
<p>(Sous Linux quand vous chiffrez votre disque avec LUKS, il n&#39;y a que VOUS qui pouvez lire le disque. Un point c&#39;est tout. Je dis ça, je dis rien.)</p>
</blockquote>
<p>Mais évidemment quand y&#39;a quelques années je disais que c&#39;était un problème que Microsoft garde une copie des clés Bitlocker, on me disait que j&#39;exagerais à l&#39;époque… </p>
<h2 id="article-jeuxvideos">Jeux-videos<a href="#article-jeuxvideos" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-ce-jeu-steam-devient-injouable-parce-que-les-jeunes-ne-savent-plus-envoyer-un-mailhttpswwwphonandroidcomcejeusteamdevientinjouableparcequelesjeunesnesaventplusenvoyerunmailhtml"><a href="https://www.phonandroid.com/ce-jeu-steam-devient-injouable-parce-que-les-jeunes-ne-savent-plus-envoyer-un-mail.html">Ce jeu Steam devient injouable parce que les jeunes ne savent plus envoyer un mail</a><a href="#article-ce-jeu-steam-devient-injouable-parce-que-les-jeunes-ne-savent-plus-envoyer-un-mailhttpswwwphonandroidcomcejeusteamdevientinjouableparcequelesjeunesnesaventplusenvoyerunmailhtml" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Steam #Jeux-videos #E-mail</p>
<blockquote>
<p>Dans une interview donnée à nos confrères de Polygon, le développeur Petter Malmehed explique que son jeu devient injouable pour une partie de son public. Son titre, After Hours, repose sur un concept original : les joueurs doivent résoudre une série d’énigmes dans un environnement inspiré des vieux ordinateurs. À un moment clé, ceux-ci doivent envoyer un vrai email pour recevoir un indice. Mais de plus en plus de jeunes échouent à cette étape pourtant banale.</p>
</blockquote>
<p>J&#39;ai envie de dire : Oups 🤦‍♂️ </p>
<p>Bon bah faut dire que les nouvelles générations ont sans doute beaucoup plus utilisé de messagerie instantanée que de mail </p>
<h2 id="article-divers">Divers<a href="#article-divers" class="anchor" aria-label="permalink">🔗</a></h2>
<h3 id="article-shhp--the80srobothttpsgithubcomthe80srobotshhp"><a href="https://github.com/the80srobot/shhp">shhp — the80srobot</a><a href="#article-shhp--the80srobothttpsgithubcomthe80srobotshhp" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#Shell #Linux</p>
<blockquote>
<p>This script gives your shell hitpoints. You start with 3 hp. Every time you run a command that fails, you take damage. If you run out of hp, the shell exits.</p>
</blockquote>
<p>Ça motive à réfléchir à ce qu&#39;on tape comme commande au moins 😂</p>
<p>En vrai l&#39;idée est marrante et je pense qu&#39;on pourrait en fait quelque chose de presque utile !</p>
<h3 id="article-microquickjshttpsgithubcombellardmquickjstabreadmeovfile"><a href="https://github.com/bellard/mquickjs?tab%3Dreadme-ov-file">MicroQuickJS</a><a href="#article-microquickjshttpsgithubcombellardmquickjstabreadmeovfile" class="anchor" aria-label="permalink">🔗</a></h3>
<p>#JavaScript</p>
<p>Moteur JavaScript pour l&#39;embarqué (100 kB of ROM, 10 kB of RAM). écrit en C et supportant un subset de JavaScript es5.</p>
<p>Ce moteur aussi être exécuté sur desktop, donc c&#39;est une option qui pourrait être utile pour un moteur d&#39;extension ou pour du paramétrage.</p>
<p>Je trouve ça intéressant de voir fleurir des moteurs comme ça !</p>
<p>Crédit photo : Générée via Mistral AI avec le prompt suivant : </p>
<blockquote>
<p>Une scène chaleureuse et immersive, inspirée par l’esthétique poétique de Studio Ghibli, représentant un bureau de travail en bois clair et vieilli, baigné d’une lumière dorée et tamisée, comme un après-midi d’automne. Au centre, une silhouette stylisée (style anime Ghibli : traits doux, visage non détaillé, vêtements amples et confortables) est assise en tailleur sur un tapis épais, absorbée par la lecture d’un journal tech futuriste. Le journal est ouvert, ses pages légèrement froissées, avec des titres en en-tête calligraphiés à la main : &quot;Frontend&quot;, &quot;Backend&quot;, &quot;IA&quot;, &quot;Sécurité&quot;, et &quot;Vie privée&quot;. Les pages brillent d’un halo bleu pâle, évoquant des lignes de code et des schémas techniques qui s’animent discrètement, comme par magie.
Autour d’elle, des piles de magazines et de carnets s’empilent de manière désordonnée mais harmonieuse. Certains sont ouverts, révélant des extraits d’articles, des croquis de frameworks (représentés par des icônes génériques : un crochet pour le frontend, un engrenage pour le backend, un cerveau pour l’IA, un cadenas pour la sécurité, et un masque pour la vie privée), ou des diagrammes de réseaux de neurones dessinés à la main. Un écran transparent et flottant (style holographique, mais avec un cadre en bois sculpté) affiche des flux d’informations en temps réel : des graphiques de données, des alertes de sécurité, et des extraits de code, le tout dans un style doux et organique, comme intégré à la scène.
En arrière-plan, une grande fenêtre donne sur un paysage urbain nocturne style Ghibli : des bâtiments aux formes arrondies, des lanternes suspendues, et des néons bleutés qui reflètent des motifs de code binaire sur les murs. Une tasse de thé fumant et un petit robot de bureau (inspiré des créatures de Ghibli, comme un mélange entre un Totoro miniature et un assistant tech) observent la scène avec curiosité.
À droite, un panda roux (ton animal préféré) est lové sur un coussin, les yeux mi-clos, comme s’il écoutait attentivement. Il ne doit pas dépasser le tiers de la hauteur de l’image et est positionné en bas à droite, légèrement tourné vers le centre, avec une queue soyeuse enroulée autour de lui.
L’ambiance est à la fois cosy, onirique et high-tech : les couleurs sont douces (beiges, bleus pâles, oranges chauds), avec des contrastes subtils pour mettre en valeur les éléments tech. Les détails sont soignés, avec des textures visibles (grain du bois, tissu du tapis, pelage du panda), et une lumière qui crée des jeux d’ombres chaleureuses. Le tout respire la sérénité et l’inspiration, comme un moment suspendu entre la magie et la technologie.</p>
</blockquote>
]]></content:encoded>
      <dc:creator><![CDATA[Anthony Pena]]></dc:creator>
      <media:content medium="image" url="https://anthonypena.fr/img/cover.min.jpg"/>
    </item>
  </channel>
</rss>