De Rust à Ruby
(xlii.space)- Il s’agit d’une expérimentation personnelle consistant à migrer un crate d’application web Rust vers Ruby on Rails, portant sur 14 943 lignes de code basées sur Tera et Axum
- La configuration Rust existante exige un coût de test élevé, avec Playwright E2E, des espaces de noms de base de données isolés, des services mockés et même un crate d’API interne
- Dans une comparaison via LLM, Rails obtient un score total de 710 contre 480 pour Rust/Axum/Diesel, avec comme points forts la vitesse de développement et la facilité des tests unitaires
- La conversion en one-shot avec Local Qwen3.6 a pris environ 30 minutes et le code Ruby a été réduit à 3 322 lignes, mais l’exécution n’a pas encore été vérifiée
- Rails se distingue par ses fonctionnalités intégrées et des tests concis, tandis que le manque de sûreté de typage de Ruby peut être compensé par Sorbet ou par l’ajout de types via des agents
Contexte de l’expérience de migration
- Un crate d’application web Rust, qui fait partie d’un projet personnel, a été choisi comme candidat à une migration vers Ruby on Rails
- Le projet complet compte environ 30 000 lignes, et le crate ciblé ressemble à une application web écrite avec Tera et Axum
- Le code Rust visé par la migration totalise 14 943 lignes et sa compilation prend environ 10 secondes
- Le code lui-même n’est pas énorme, mais sa structure traîne de nombreuses dépendances
- La configuration Rust existante a un coût de test élevé
- Les tests E2E nécessitent une configuration Playwright
- Comme le mocking est difficile, il faut des espaces de noms de base de données isolés et des services mockés
- Un crate d’API interne séparé est aussi nécessaire pour que Playwright interagisse avec l’application en mode headless
- Ruby et Ruby on Rails sont envisagés comme une alternative plus concise
- Ruby n’est pas typé, ce qui peut le rendre moins sûr que Rust
- L’utilisation de Sorbet permet de compenser en partie la sûreté de typage côté Ruby
- Une comparaison menée avec plusieurs instances de LLM sur la complexité, la stabilité, la facilité de test et d’autres critères donne un meilleur score à Rails
- Le total de Rust/Axum/Diesel est de 480, Rails obtient 710 et Rails + Sorbet 695
- Rails est très bien noté pour son adéquation à un développeur solo à 90, sa vitesse de développement à 90 et sa facilité pour les tests unitaires à 90
- Rust/Axum/Diesel est très bien noté en sûreté à 95 et en performances à 95, mais faible sur la facilité des tests unitaires à 20 et des tests d’intégration à 30
- Sur la base de la simple somme des scores, l’auteur estime qu’une application Rails pourrait produire un résultat 1,47 fois meilleur
Résultats de la conversion et points à examiner
- Un projet relativement petit a été converti en one-shot avec Local Qwen3.6
- La conversion a pris environ 30 minutes
- Rien n’a encore été exécuté, donc le bon fonctionnement réel n’a pas été confirmé
- Le changement le plus important est la réduction du nombre de lignes de code
- Total des lignes dans les fichiers Rust : 14 943 lignes
- Total des lignes dans les fichiers Ruby : 3 322 lignes
- Le volume a diminué de 77 %, soit environ 4,49 lignes de Rust pour 1 ligne de Ruby
- Le code Ruby converti semble propre et idiomatique dans le survol qui en a été fait
- Des bugs restent possibles
- Un examen plus approfondi est prévu ensuite
- Les autres points à examiner sont le renforcement du typage, les fonctionnalités intégrées de Rails et la simplification des tests
- L’ajout de types à l’aide d’agents peut atténuer les problèmes de sûreté de typage
- Ruby/Rails est considéré comme plus proche de « batteries + kitchen sink included » et préférable à 3 GiB de dépendances compilées
- Les tests devraient devenir nettement plus faciles
- L’exemple de test Ruby est une forme courte qui encapsule l’appel LLM avec
VCR.use_cassette("llm_call")et vérifie la taille du résultatVCR.use_cassette("llm_call") do result = LlmClient.match(entry, data_list) expect(result.results.size).to eq(data_list.size) end - L’exemple de test Rust est plus long, car il faut implémenter directement un fournisseur mocké
- Il utilise
Arc<RwLock<Vec<Response>>>,AtomicUsize,async_trait,tokio::test, etc. - Il faut créer un
MockProviderqui gère la liste des réponses et le nombre d’appels, implémenter ensuitematchdu traitProvider, puis vérifier dans le test le résultat et le nombre d’appels
- Il utilise
- Comme il s’agit d’un projet personnel, des choix plus audacieux sont possibles, et le passage de Rust à Ruby sera examiné de près à l’avenir
1 commentaires
Réactions sur Hacker News
J’ai du mal à y croire. On dirait : « J’avais un petit point technique qui me démangeait, une IA locale a bouclé le boulot en 30 minutes. Je n’ai même pas cliqué sur Start pour voir si ça tournait, mais j’ai quand même écrit un billet de blog… »
à moins que ça n’ait été poussé par des bots
2026 : regardez ce que je n’ai pas écrit !
2036 : comment j’ai écrit 200 lignes en C, cette ancienne forme de latin
Au début, je pensais que ce serait un article intéressant, puis dès que j’ai vu qu’il avait utilisé un LLM pour la conversion, j’ai immédiatement perdu tout intérêt. C’est un peu comme dire : « J’ai demandé à un subordonné de le faire, et maintenant je vais vous raconter l’histoire. »
Comme il n’a ni fait la conversion lui-même ni vraiment réfléchi en profondeur, je ne vois pas trop pourquoi je lirais ça
Du coup, un simple smoke test peut donner l’impression que tout a marché
En dehors de la programmation artisanale, le langage lui-même va devenir assez secondaire
À mesure que les LLM s’améliorent, il s’agira surtout de décider dans quel type de langage générer la spécification
En un sens, le camp UML et RUP a fini par prendre sa revanche
Comme d’autres commentaires l’ont dit, il a fait une revue assez large. Ce n’est pas un gros projet, et à part quelques morceaux épicés, c’est surtout une web app
Dire qu’il « n’a pas réfléchi » me paraît injuste. Il n’a pas juste appuyé sur un bouton en mode YOLO
Il a étudié les compromis et les résultats, les différences entre les morceaux de code Rust et Rails étaient réelles, et la testabilité de l’app Rust était un sujet sur lequel il réfléchissait depuis 2 mois
Comme disent les amateurs de LLM, le contexte compte ;)
Je ne suis pas sûr qu’il existe un langage ou un framework qui fasse autant passer le bonheur des développeurs en priorité que Ruby on Rails
C’est un truc composé quelque part, impossible de savoir où, et au final je dois arrêter ce que je fais pour aller lire la doc pendant une heure. Pour quelqu’un qui fait du Rails toute la journée, ça passe peut-être, mais pour moi, la convention plutôt que la configuration est un énorme anti-pattern
Le bonheur ne se traduit pas toujours en performances. Ça me rappelle le célèbre cas du logo de Twitter avant sa migration vers la JVM et Scala
Ruby on Rails s’est fait un nom, mais j’avais déjà connu des expériences similaires avec AOLServer et Vignette basés sur Tcl
Dans une startup portugaise, ils avaient même créé leur propre variante, et ses fondateurs ont ensuite lancé OutSystems. C’était l’un des premiers outils RAD graphiques pour développer des sites web et des systèmes distribués, en low-code/no-code sur infrastructure JVM ou CLR
Cela dit, je suis quand même content de voir que le JIT de CRuby devient maintenant intégré par défaut
J’ai créé un ensemble de gems appelé propel_rails qui pousse encore plus loin le côté concis du code Ruby on Rails. Il génère des classes de haut niveau comme des contrôleurs d’API et des concerns, puis à partir de là il produit toute une ressource RESTful (modèle, contrôleur, sérialiseur, tests unitaires et tests E2E) sans le moindre boilerplate
Au final, les contrôleurs ne contiennent plus que la liste des attributs autorisés par l’API, puisque les actions RESTful sont générées automatiquement. C’est un peu difficile à expliquer complètement, mais la puissance de la métaprogrammation en Ruby permet vraiment de faire facilement des choses impressionnantes
Ça fonctionne si on raisonne à partir du modèle de domaine ?
Je suis dans une situation assez proche
J’aime Go et Rust, ce sont tous les deux d’excellents langages avec leurs forces et leurs faiblesses. Mais malheureusement, je n’ai réussi à construire aucune app SaaS avec l’un ou l’autre. J’ai l’impression d’essayer de faire entrer une cheville carrée dans un trou rond
Je peux me tromper lourdement, mais les outils SaaS traînent énormément de choses autour d’eux, et je n’ai pas envie de tout réinventer
RoR est « suffisamment bon ». On peut ajouter du typage quand on en a envie, on peut aller vite, et l’outillage tient la route
Mon premier travail pro, c’était du PHP, et il y avait bien trop de pièges. Ruby me semblait un peu plus orienté e-commerce, ce qui m’a intrigué, et si c’est assez bien pour Shopify, alors ça me va
Si passer de Rust à Ruby a du sens dans ce cas, alors avoir choisi Rust au départ était déjà une erreur
Ceux qui pensent que Ruby est plus lent que Rust seraient surpris d’apprendre qu’aujourd’hui, Ruby est en pratique plus rapide que Python, tout en restant plus lent que Go ou Rust
Mais quand on a plusieurs workers en arrière-plan et que chacun commence à consommer plus de 2 Go de mémoire, ça s’accumule très vite
J’ai écrit un service Rust en production, et ce qui m’a le plus impressionné, plus encore que la vitesse, c’est qu’il tournait avec 30 Mo de mémoire
C’est peut-être provocateur, mais si Rust est pratique pour afficher un QI de 900+ devant les paysans du coin, beaucoup de développeurs intelligents et talentueux n’aiment pas tant Rust que ça. Certains préfèrent créer leur propre langage de programmation et leur propre compilateur plutôt que d’écrire une ligne de Rust
Je pense à Jai de Jonathan Blow et à Odin de Ginger Bill
Il y a aussi bien d’autres personnes dont la créativité et la profondeur sont prouvées, qui ont construit des bibliothèques et des frameworks magnifiques et largement utilisés, mais je n’ai pas envie de gaspiller de place ici
Cela dit, Rust a un super club macho et une fraternité très soudée
Claude fonctionne vraiment bien sur les apps Rails. Comme l’a aussi souligné l’auteur de cet article, Ruby permet de faire beaucoup avec peu de code, et Rails utilise la convention plutôt que la configuration, ce qui rend les apps Rails encore plus concises
Une hypothèse pour expliquer pourquoi Claude écrit bien des apps Rails, c’est l’efficacité en tokens
J’avais déjà vu ce projet qui essaie de mesurer et comparer l’efficacité en tokens selon les projets, et Rails s’en sortait plutôt bien
https://felipemrvieira.github.io/SyntaxTax/dashboard/
Je suis parfois surpris par la taille des projets. Une base de code de 30 000 lignes, c’est petit ? Je sais que le plafond peut être bien plus haut, mais 30 000 lignes peuvent contenir énormément d’informations et de subtilités de comportement
C’est peut-être lié à mon parcours, plutôt orienté backend/réseau en Go. Au-delà de 10 000 à 15 000 lignes, il m’a souvent semblé difficile de garder le modèle global du codebase en tête, ce qui devenait déjà assez lourd