LicenseKit
février 2026 → juillet 2026

Devant un dépôt vide, il y a toujours ce moment où il faut choisir une licence. On sait vaguement que MIT est permissive et que GPL oblige à quelque chose, on copie ce qu'on a vu ailleurs, et on passe à autre chose. Les outils que je connaissais généraient bien un fichier LICENSE, mais aucun ne m'expliquait ce que je venais de signer.
LicenseKit est un outil en ligne de commande qui aide à choisir, comprendre et ajouter la bonne licence à un projet.
npx @drosscend/licensekit
Il y avait une autre motivation, plus personnelle : j'installe des dizaines d'outils comme celui-là, et je voulais une fois passer de l'autre côté. Publier quelque chose que n'importe qui puisse lancer en une commande.
Comprendre avant de générer
L'outil affiche ce qu'une licence permet, ce qu'elle exige et ce qu'elle exclut, en langage clair plutôt qu'en juridique.

Il compare aussi deux licences côte à côte, ce qui reste le moyen le plus rapide de saisir une différence. Sur MIT face à GPL-3.0, on voit d'un coup d'œil que les deux autorisent l'usage commercial, mais que seule la GPL impose de documenter ses modifications et de redistribuer sous la même licence.

Enfin, il génère le fichier LICENSE, en remplissant l'auteur et l'année qu'il devine tout seul depuis la configuration Git locale, et il propose de mettre à jour le champ license du package.json au passage. On ne devrait jamais avoir à saisir une information que le programme peut déduire.
L'assistant, ou mon avis encodé en points
Le mode guidé pose quelques questions sur le projet, puis classe les licences par pertinence.
Derrière, il n'y a aucune intelligence : c'est une matrice de score écrite à la main. Chaque réponse ajoute ou retire des points à des licences précises. Répondre « bibliothèque » favorise MIT, Apache et les BSD ; répondre « projet commercial » pénalise les GPL de deux points ; « documentation » fait remonter CC0.
Autrement dit, ce classement, ce sont mes convictions transformées en pondérations. C'est un avis argumenté, pas une vérité, et je préfère le dire clairement. Dans le même esprit : l'outil aide à comprendre et à dégrossir, il ne remplace pas un avis juridique.
D'où viennent les textes
Les quatorze licences proposées ne sont pas recopiées à la main. Un script va chercher leur texte et leurs métadonnées sur l'API de GitHub, puis les embarque dans le paquet.
Ce que j'ai fait manuellement, en revanche, c'est la catégorisation : permissive, copyleft, copyleft faible, domaine public. C'est cette classification qui structure l'affichage et alimente le questionnaire. Elle n'existe pas dans les données d'origine.
Trois dépendances, et c'est tout
Un analyseur d'arguments, une bibliothèque d'invites interactives, un peu de couleur.
Pour un outil qu'on lance avec npx sans l'installer, chaque dépendance est du téléchargement à chaque exécution. Un outil qui met dix secondes à démarrer ne sera pas lancé deux fois. La légèreté n'est pas une élégance, c'est une condition d'usage.
L'internationalisation, elle, n'était pas négociable : tout est disponible en français et en anglais, avec détection de la langue du système et possibilité de forcer avec --lang. Les traductions vivent dans des fichiers séparés, donc ajouter une langue ne demande pas de toucher au code.
Passer du côté de l'auteur
C'était mon premier paquet npm, et la partie publication m'a autant appris que le code.
Le nom, d'abord. Les noms courts sont pris depuis longtemps, d'où le paquet sous portée, @drosscend/licensekit. Ensuite le format : déclarer le binaire, construire avant de publier, soigner les métadonnées pour que la page npm veuille dire quelque chose.
La partie que je trouve la plus intéressante est la chaîne de publication. Poser un tag suffit à déclencher la mise en ligne : la CI vérifie que le tag correspond bien à la version du package.json, lance le lint, les types et les quatre-vingt-douze tests, construit le paquet et le publie avec une attestation de provenance. Le tout sans jeton stocké, grâce à l'authentification par OIDC entre GitHub et npm. Il n'y a aucun secret npm dans le dépôt, et c'est exactement ce qu'on veut pour une mise en production automatique.
L'outil est prévu pour aller plus loin que Node : la détection du manifeste passe par un registre d'adaptateurs, dont un seul existe aujourd'hui, celui de package.json. Ajouter Cargo.toml ou pyproject.toml demanderait un fichier, pas une refonte.
Ce que la relecture a révélé
En reprenant le code pour écrire ces lignes, j'ai trouvé deux défauts.
Le premier : la comparaison affichait toutes les limitations comme absentes. Les données de GitHub utilisent les étiquettes liability et warranty, alors que mes règles internes attendaient no-liability et no-warranty. La commande de détail passait par une table d'équivalences, la comparaison l'avait oubliée.
Le second était plus vicieux, et il ne venait pas du code. La chaîne d'intégration appelait le compilateur TypeScript sans que la version soit figée dans le projet : elle prenait donc celle du jour. Tant que TypeScript 5 était la dernière publiée, tout allait bien. Le jour où TypeScript 7 est sorti, la publication s'est mise à échouer, sur un projet dont pas une ligne n'avait bougé depuis février. Les erreurs partaient d'ailleurs d'un seul point : sans les types de Node, process.exit() ne promettait plus de ne jamais rendre la main, donc le compilateur ne pouvait plus déduire qu'une variable était non nulle après ce contrôle.
Les deux sont corrigés, les dépendances sont à jour et les versions d'outillage sont désormais déclarées dans le projet. La leçon est simple : une dépendance non figée finit toujours par bouger, y compris sur un projet auquel on ne touche plus.
Où en est le projet
Écrit et publié en deux jours, avec Claude Code, sur une portée volontairement fermée : un outil qui fait une chose, complètement.
Je ne le maintiens pas activement et je ne m'en sers pas au quotidien, mais il vit sa vie : une trentaine de téléchargements par mois, par des gens que je ne connais pas. Pour un premier paquet, ça suffit à donner envie de recommencer.