Kitmul a commencé comme quelque chose de bien plus modeste que ce qu'il est aujourd'hui. Je maintiens deux bibliothèques open source (NextTranslate et Teaful) et j'avais besoin d'un vrai projet Next.js pour itérer dessus. Pas de démos artificielles ni de dépôts d'exemple : un produit vivant où les bugs apparaissent naturellement et les limitations deviennent évidentes.
C'était le seul objectif.

L'effet multiplicateur de l'IA
Pour accélérer le développement, j'ai commencé à utiliser des agents de codage IA : Claude Code, Gemini et Codex. Pas seulement pour la productivité. Je voulais comprendre de première main comment ces agents se comportent dans un workflow de développement réel. Ce qu'ils font bien, où ils échouent, et comment ils changent la façon dont on pense la construction de logiciels.
Ce que je n'avais pas anticipé, c'est l'effet sur la portée du projet. Quand on peut implémenter une idée en minutes au lieu d'heures, on arrête de trier les idées. On les construit, tout simplement. Je suis passé de « je maintiens deux bibliothèques » à « je construis 300+ outils » en seulement 3 semaines.
Actuellement, j'utilise Claude Code 20x. La combinaison d'un agent qui comprend profondément ta codebase et qui peut exécuter des tâches multi-étapes de manière autonome est le plus grand multiplicateur de vélocité que j'ai expérimenté.
Des outils pour développeurs aux outils pour tout le monde
En tant que développeur open source, j'ai toujours construit pour d'autres développeurs. Des bibliothèques, des outils CLI, des utilitaires de build. Public limité, impact limité.
Avec Kitmul, j'ai inversé la question. Au lieu de « quel outil a besoin un dev », je me suis demandé : « quel outil les gens cherchent-ils sur Google pour finir sur un site qui leur fait payer ou qui téléverse leurs fichiers sur un serveur ».
La réponse : des centaines d'outils. Supprimer les arrière-plans d'images, séparer les pistes audio, convertir des formats, compresser des PDFs, générer des QR codes. Des outils que les gens utilisent au quotidien, et pour lesquels de nombreux sites facturent 10-20 € par mois.
Aujourd'hui, Kitmul en compte plus de 300. Et ce ne sont pas des wrappers triviaux.
L'architecture : tout s'exécute sur l'appareil de l'utilisateur
La décision technique fondamentale de Kitmul est que tout s'exécute côté client. Sans exception, dans la mesure du possible.
Le stack est direct : si le JavaScript natif suffit, on utilise JavaScript. Si l'opération est intensive (traitement audio, manipulation d'images lourde, séparation de pistes) on compile en WebAssembly. Et pour les parties où la performance est critique, du Rust compilé en WASM.
Par exemple, voici comment on charge et exécute un module WASM pour le traitement de PDFs :
import { PDFDocument } from 'pdf-lib';
export async function mergePDFs(files) {
const merged = await PDFDocument.create();
for (const file of files) {
const bytes = await file.arrayBuffer();
const pdf = await PDFDocument.load(bytes);
const pages = await merged.copyPages(pdf, pdf.getPageIndices());
pages.forEach((page) => merged.addPage(page));
}
return merged.save(); // Returns Uint8Array — never leaves the browser
}
Zéro appel réseau. Le fichier passe de File API → pdf-lib → téléchargement.
Pourquoi Rust + WASM : le vérificateur de nombres premiers
Pour les calculs plus lourds, JavaScript atteint un mur. Un exemple concret de Kitmul : notre Vérificateur de Nombres Premiers. JavaScript peut vérifier la primalité pour de petits nombres, mais essaye de tester un nombre de plus de 1 200 chiffres et le navigateur va se bloquer. BigInt ne peut tout simplement pas gérer ça.
Voici l'approche JavaScript, qui fonctionne bien pour les nombres jusqu'à ~13 chiffres :
function isPrime(n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 === 0 || n % 3 === 0) return false;
for (let i = 5; i * i <= n; i += 6) {
if (n % i === 0 || n % (i + 2) === 0) return false;
}
return true;
}
// Fonctionne pour les petits nombres, mais pour un nombre de 1200+ chiffres ?
// L'arithmétique BigInt devient si lente que l'onglet se fige.
La solution : on a compilé un crate Rust qui utilise num-bigint avec un test de primalité de Miller-Rabin en WASM. Le côté Rust reçoit le nombre sous forme de chaîne de caractères (parce qu'il peut faire des milliers de chiffres) et retourne s'il est premier :
use num_bigint::BigUint;
use num_traits::{One, Zero};
#[no_mangle]
pub extern "C" fn is_number_prime(ptr: *const u8, len: usize) -> i32 {
let bytes = unsafe { std::slice::from_raw_parts(ptr, len) };
let num_str = std::str::from_utf8(bytes).unwrap_or("0");
let n = num_str.parse::<BigUint>().unwrap_or_else(|_| BigUint::zero());
if n <= BigUint::one() { return 0; }
if miller_rabin(&n) { 1 } else { 0 }
}
Ensuite, côté JavaScript, on charge le module WASM et on passe le nombre sous forme d'octets :
// Charger le WASM et vérifier un nombre de 1200+ chiffres
const { instance } = await WebAssembly.instantiate(wasmBuffer, {});
const exports = instance.exports;
const numStr = "12345..."; // nombre de 1200+ chiffres
const bytes = new TextEncoder().encode(numStr);
const ptr = exports.wasm_alloc(bytes.length);
new Uint8Array(exports.memory.buffer).set(bytes, ptr);
const result = exports.is_number_prime(ptr, bytes.length);
exports.wasm_dealloc(ptr, bytes.length);
// result: 1 = premier, 0 = non premier
JavaScript avec BigInt ne peut pas gérer les nombres au-dessus de ~1 200 chiffres. Le module Rust WASM gère des nombres de n'importe quelle taille ; on l'a testé avec des nombres de plus de 3 000 chiffres. Même navigateur, même appareil, mais le crate num-bigint de Rust utilise une arithmétique de limbs optimisée que JavaScript ne peut tout simplement pas égaler.
Les implications de cette architecture :
- Coût d'infrastructure quasi nul : pas de serveurs qui traitent des fichiers.
- Confidentialité réelle, pas simplement promise : les données ne quittent littéralement jamais l'appareil.
- Scalabilité sans provisionnement : chaque utilisateur apporte sa propre puissance de calcul.
La thèse : les agents IA ne devraient pas contrôler tes apps. Ils devraient ÊTRE l'app.
C'est là que je pense que l'industrie fait fausse route.
OpenAI avec Operator, Anthropic avec Computer Use, Google avec Project Mariner : les grands acteurs construisent tous des agents IA qui contrôlent des applications existantes. Ils prennent des captures d'écran, déplacent ta souris, cliquent sur des boutons, remplissent des formulaires. En substance, ils construisent des bots RPA très sophistiqués.
Je pense que cette approche est fondamentalement défaillante. Voici pourquoi :
1. On construit par-dessus des interfaces conçues pour des humains, pas pour des machines. Quand un agent IA navigue sur un site web, il se bat contre les menus déroulants, les modales, les bannières de cookies, les CAPTCHAs et les changements de mise en page. Chaque refonte de site peut casser l'agent. C'est fragile par design.
2. On dépend toujours de services tiers. L'agent IA a beau être intelligent, il téléverse quand même ton PDF sur iLovePDF, il envoie quand même tes images sur les serveurs de Canva, il donne quand même tes données à quelqu'un d'autre. Le problème de confidentialité ne disparaît pas juste parce que c'est un robot qui clique sur les boutons.
3. C'est lent. Capture d'écran → analyse → clic → attente du chargement → nouvelle capture. Cette boucle prend des secondes par action. Pendant ce temps, un appel de fonction direct prend des millisecondes.
L'approche alternative (et ce que je construis avec Kitmul) est radicalement différente :
L'agent IA ne contrôle pas des apps. L'agent IA EST l'app.
Au lieu de naviguer vers SmallPDF pour fusionner des fichiers, l'agent appelle mergePDFs() directement. Au lieu d'ouvrir Canva pour supprimer un arrière-plan, il exécute un modèle WASM dans le navigateur. Pas de captures d'écran, pas de mouvements de souris, pas d'attente de chargement. Des appels de fonctions directs, des résultats directs.
// L'approche "capture d'écran et clic" (Operator, Computer Use) :
// 1. Naviguer vers smallpdf.com (~3s)
// 2. Trouver le bouton upload (~1s)
// 3. Téléverser le fichier (~5s)
// 4. Attendre le traitement (~3s)
// 5. Cliquer sur télécharger (~2s)
// 6. Attendre le téléchargement (~3s)
// Total : ~17 secondes + tes fichiers sur le serveur de quelqu'un d'autre
// L'approche Kitmul :
const merged = await mergePDFs(files); // ~300ms, ne quitte jamais ton appareil
Ça représente une différence de vitesse de 30-50x, avec le bonus que tes fichiers ne touchent jamais un serveur distant.
L'orchestration en pratique
Kitmul dispose déjà d'un chat intégré où l'IA agit comme orchestrateur. L'utilisateur décrit ce qu'il veut en langage naturel. L'IA sélectionne les outils du catalogue, les exécute en séquence et chaîne les sorties.
Un exemple concret : tu téléverses un fichier audio. L'IA le sépare en pistes à l'aide d'un modèle WASM de séparation de sources. Puis elle applique une réduction de bruit sur la piste vocale. Convertit le résultat en MP3. Le tout enchaîné, dans le navigateur, sans que le fichier ne quitte ton appareil.
L'orchestrateur utilise un registre d'outils qui mappe les intentions en langage naturel vers des fonctions concrètes :
// Version simplifiée du fonctionnement de l'orchestrateur
const toolRegistry = {
'merge_pdf': { fn: mergePDFs, input: 'file[]', output: 'file' },
'split_audio': { fn: splitAudio, input: 'file', output: 'file[]' },
'compress_image': { fn: compressImage, input: 'file', output: 'file' },
// ... 300+ outils supplémentaires
};
// L'IA décide du plan d'exécution, puis l'exécute :
const plan = await ai.plan("Sépare cette chanson et supprime le bruit des voix");
// → [{ tool: 'split_audio', input: userFile },
// { tool: 'noise_reduction', input: '$prev.vocals' },
// { tool: 'convert_to_mp3', input: '$prev' }]
for (const step of plan) {
step.result = await toolRegistry[step.tool].fn(resolve(step.input));
}
Ce n'est pas un concept. Ça fonctionne aujourd'hui.
La partie vraiment intéressante : les outils qui se construisent eux-mêmes
C'est là que Kitmul diverge de tout le reste.
Avec 300+ outils, on couvre beaucoup de cas d'usage. Mais quand un utilisateur demande quelque chose qu'on n'a pas, au lieu de répondre « désolé, on ne peut pas faire ça », le système devrait être capable de créer l'outil à la volée avec l'IA ; et ensuite, point crucial, avoir un humain dans la boucle qui vérifie que l'outil généré fonctionne correctement avant qu'il n'intègre le catalogue permanent.
Réfléchis-y :
- Un utilisateur demande : « J'ai besoin d'un outil qui convertit les fichiers MIDI en partition. »
- L'IA génère l'outil : une implémentation côté client utilisant WebAssembly.
- Un reviewer humain (moi, ou à terme une communauté de contributeurs) vérifie que l'outil fonctionne, gère les cas limites et respecte les standards de qualité de Kitmul.
- Une fois approuvé, l'outil est ajouté de manière permanente au catalogue.
- Le prochain utilisateur qui demande la même chose obtient l'outil vérifié, en qualité production, instantanément.
Le système se construit littéralement lui-même en fonction des besoins des utilisateurs. Chaque requête sans réponse devient un signal. Chaque outil vérifié rend la plateforme plus capable. C'est un volant d'inertie où l'IA génère, les humains vérifient, et le catalogue grandit organiquement.
C'est fondamentalement différent de l'approche « générer du code au runtime » que certaines entreprises d'IA poursuivent. Du code généré qui s'exécute sans vérification, c'est un risque : il peut contenir des bugs, des failles de sécurité, ou tout simplement ne pas fonctionner pour les cas limites. L'étape humaine dans la boucle n'est pas une limitation ; c'est une feature. Elle garantit que chaque outil du catalogue est en qualité production.
Voir en action
Voici une démo rapide du fonctionnement de Kitmul :
L'objectif : 4 000 outils en un an
J'ai un backlog de plus de 4 000 idées d'outils. Ce n'est pas un nombre arbitraire : c'est la taille réelle de la liste après avoir analysé ce que les gens recherchent et ce qui nécessite actuellement de téléverser des fichiers sur un serveur ou de payer un abonnement.
Avec Claude Code 20x et l'approche d'auto-construction, ce n'est pas un moonshot. Beaucoup d'outils se construisent en une seule session. Les plus complexes (ceux qui nécessitent du WASM personnalisé ou du traitement de signal) prennent plus de temps, mais restent des ordres de grandeur plus rapides que sans IA.
La suite
L'orchestration fonctionne pour les flux simples, mais les workflows complexes avec des branchements, des conditions et des boucles de feedback nécessitent encore du travail. Le pipeline d'auto-construction est en cours de conception.
La vision à long terme : un système où toute tâche que tu fais aujourd'hui avec des logiciels fragmentés (téléverser des fichiers ici, payer un abonnement là, installer une app pour autre chose) peut être résolue dans une seule interface, exécutée localement, orchestrée par l'IA, et en expansion constante basée sur ce dont les utilisateurs ont réellement besoin.
La question que je veux te laisser : A-t-on vraiment besoin d'agents IA qui manipulent nos apps existantes ? Ou faut-il repenser ce que l'app elle-même devrait être ?
Je pense que c'est la deuxième option. Et je pense que le navigateur est le bon runtime pour le prouver.