browser-control : piloter un vrai navigateur depuis un shell, sans SDK ni serveur
A tiny, fast Rust CLI that drives a real browser over the Chrome DevTools Protocol — built for coding agents.
En bref
- De quoi s’agit-il ?
- Un binaire Rust unique qui expose le Chrome DevTools Protocol sous forme de sous-commandes compactes, pensé pour les agents de code. Ce qu'il fait, comment il le fait, et où il vous laissera tomber.
- À qui s’adresse-t-il ?
- Adoptez browser-control si votre agent sait déjà lancer un processus et lire stdout : dans ce cas, la surface de commandes remplace un SDK entier. Ne l'adoptez pas si vous avez besoin d'orchestration multi-onglets complexe ou d'un support éditeur, le projet en est à la v0.1.1.
- Puis-je l’utiliser commercialement ?
- Oui. MIT est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 20 jours.
- En quel langage est-il écrit ?
- Principalement Rust, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème : un agent qui sait exécuter une commande mais pas cliquer
Un agent de code dispose généralement d'un shell. Il ne dispose pas d'un moyen simple d'ouvrir une page, de repérer un bouton et d'appuyer dessus. Les bibliothèques d'automatisation classiques imposent un langage, une dépendance à installer dans le projet, et souvent un serveur qui tourne en parallèle du travail de l'agent. browser-control prend le problème par l'autre bout : le README annonce une CLI qui expose le navigateur comme un tuyau, avec des sous-commandes qui impriment du texte compact ou du JSON. La phrase du README est explicite : le projet ne contient pas de LLM, n'exige pas MCP, et n'impose pas de framework. Le public visé est donc précis : un agent qui sait déjà lancer un processus et lire sa sortie standard. Pas une équipe QA qui veut écrire des suites de tests, pas un data engineer qui veut scraper à grande échelle.
Des références @e1 plutôt que des sélecteurs écrits à la main
Le mécanisme central est la commande snapshot. Elle renvoie une liste d'éléments actionnables avec des identifiants stables de la forme @e1, @e2, que les commandes suivantes acceptent directement : click @e3. Le README justifie ce choix par la fragilité des sélecteurs rédigés à la main, un problème réel quand c'est un modèle qui produit la cible. Trois styles de ciblage cohabitent : la référence issue du snapshot, le sélecteur CSS avec une option --wait qui interroge la page jusqu'à ce que l'élément apparaisse, et les coordonnées x,y pour les canvas ou les cartes où aucun noeud stable n'existe. C'est la bonne granularité : l'échappatoire existe sans devenir le chemin par défaut. Une réserve toutefois, la documentation ne précise pas la durée de vie d'une référence @e1. Si le DOM est reconstruit entre le snapshot et le clic, rien dans le matériel fourni n'indique si la référence est revalidée ou si elle échoue silencieusement sur un autre élément.
Le démon caché et les anneaux d'événements
Le projet ne se contente pas d'envoyer des ordres au navigateur. Un démon non exposé en surface conserve en mémoire des anneaux d'événements DOM, de requêtes réseau et de messages console. Trois sous-commandes les consultent : events, network, console. La commande doctor, elle, rapporte l'endpoint, le navigateur, le pid lancé, l'état du démon et l'espace de travail. Deuxième mécanisme d'observabilité : chaque échec de commande dépose une trace compacte sous .browser-control/traces/, ce qui permet à l'agent de se diagnostiquer sans instrumenter quoi que ce soit lui-même. C'est la partie la plus intéressante du design et aussi la moins documentée dans le README. La taille des anneaux, leur politique de rotation et le format exact des fichiers de trace ne sont pas décrits. Pour un usage interactif cela suffit. Pour une session longue avec beaucoup de trafic réseau, la question de la mémoire consommée par le démon reste ouverte.
Installation : trois chemins, un seul binaire
Depuis crates.io, la commande est cargo install browser-control-cli. Attention au piège de nommage signalé dans le README : le crate s'appelle browser-control-cli parce que le nom browser-control était pris, mais le binaire installé est bien browser-control. Les binaires précompilés évitent la toolchain Rust, avec par exemple une archive browser-control-aarch64-apple-darwin.tar.gz récupérée depuis la dernière release GitHub. Depuis les sources, il faut rustup toolchain install pour installer la version épinglée dans rust-toolchain.toml, puis cargo build --locked --release. Le drapeau --locked n'est pas décoratif : les dépendances directes de Cargo.toml sont en versions exactes et les dépendances transitives sont figées par Cargo.lock. Le README recommande --locked en CI et pour reproduire une mesure. Côté configuration, tout passe par des variables d'environnement : BROWSER_CONTROL_CDP_URL pour un endpoint HTTP, BROWSER_CONTROL_CDP_WS pour une websocket, avec les alias courts BU_CDP_URL et BU_CDP_WS. Les commandes de base s'enchaînent ainsi : browser-control init pour créer l'espace .browser-control/, browser-control launch https://example.com pour démarrer Chrome et se connecter, puis browser-control doctor. Si un navigateur écoute déjà sur CDP, launch devient inutile.
Ce que la surface d'aide ne couvre pas
Le README revendique une échappatoire vers le protocole brut, et elle est réelle : browser-control cdp Runtime.evaluate '{"expression":"location.href","returnByValue":true}' envoie une commande CDP arbitraire. Deux détails pratiques méritent d'être connus avant de s'engager. Le premier concerne eval : le README précise qu'un return au niveau supérieur est encapsulé dans une IIFE, donc eval 'const x = 1; return x' fonctionne tel quel. Le second concerne les cadres : eval accepte --frame suivi d'une sous-chaîne d'URL d'iframe, ce qui évite de basculer manuellement de contexte. Reste une limite de conception assumée : le projet est en v0.1.1, publiée le 21 juin 2026, la v0.1.0 datant de la veille. Une API de CLI à ce stade peut encore bouger, et rien dans le matériel fourni ne décrit de politique de compatibilité entre versions. Un agent qui génère des scripts browser-control devra donc être repassé après chaque mise à jour.
Chrome local ou session distante, mêmes commandes
Le projet se présente comme indépendant du fournisseur cloud. Le README cite Browser Use, Steel, Hyperbrowser et Browserbase, ainsi que tout fournisseur exposant du CDP. Le mécanisme est le même que pour un Chrome local : on renseigne une URL ou une websocket via variable d'environnement, et les sous-commandes snapshot, click ou eval ne changent pas. C'est un vrai argument face à une bibliothèque qui intègre un fournisseur en dur. La contrepartie est que browser-control ne gère ni le provisionnement ni l'authentification de ces services : il faut obtenir soi-même l'URL CDP, et le README ne détaille pas ce que chaque fournisseur attend exactement. Le badge de la page projet liste quatre noms, mais aucun exemple de configuration par fournisseur n'apparaît dans l'extrait disponible.
Playwright et browser-control : deux philosophies opposées
L'alternative la plus évidente est Playwright, qui pilote aussi un navigateur réel. La différence n'est pas la couverture du protocole, c'est le modèle d'exécution. Playwright suppose qu'un programme hôte importe une bibliothèque et décrit un scénario dans un fichier de test, avec ses attentes automatiques et son runner. browser-control suppose l'inverse : aucun programme hôte, une suite de commandes shell dont la sortie est lue par un agent. Cette différence a des conséquences concrètes. Playwright sait attendre un état réseau avant de rendre la main, browser-control propose --wait sur un sélecteur, ce qui couvre le cas courant mais pas les scénarios de navigation complexe. Playwright offre un support éditeur et un débogage pas à pas, browser-control dépose des traces dans .browser-control/traces/ et s'arrête là. Pour une suite de tests versionnée et rejouée en CI, Playwright reste l'outil adapté. Pour un agent qui doit cliquer sur un bouton pendant une tâche ponctuelle, la CLI évite d'installer un runtime dans le projet.
Coût de maintenance et licence
Le projet est distribué sous licence MIT, ce qui autorise la réutilisation et la modification avec conservation du texte de licence. Ce paragraphe décrit le texte de la licence, il ne constitue pas un conseil juridique. La reproductibilité est traitée sérieusement pour un projet à ce stade : toolchain épinglée, Cargo.lock committé, dépendances directes en versions exactes, et un script scripts/verify.sh présenté comme la vérification locale en une commande. Le coût de mise à jour se concentre donc sur un point : la compatibilité de l'interface en ligne de commande, encore en 0.1.x. La dernière poussée sur le dépôt date du 27 août 2026, soit environ deux mois après la v0.1.1, sans nouvelle release publiée depuis. Cela ne dit rien de l'activité réelle, mais un utilisateur qui épingle une version devra vérifier lui-même ce qui a changé avant de sauter à la suivante.
Conclusion éditoriale
Adoptez browser-control si votre agent sait déjà lancer un processus et lire stdout : dans ce cas, la surface de commandes remplace un SDK entier. Ne l'adoptez pas si vous avez besoin d'orchestration multi-onglets complexe ou d'un support éditeur, le projet en est à la v0.1.1. Vérifiez d'abord que browser-control doctor détecte bien votre Chrome, puis lisez le contenu réel de .browser-control/traces/ après un échec : c'est le seul mécanisme de diagnostic documenté.
Notes de la communauté