Rails est-il vraiment fini ?
DHH reconstruit HEY sans Rails, Lucas Dohmen le déclare terminé. Moi, je trouve qu'il reste plein de choses à faire.
À Rails World la semaine dernière, DHH a expliqué que 37signals n’écrivait presque plus de code à la main, et que HEY était en train d’être réécrit en applis natives avec un backend en Rust, donc sans Rails.
Six semaines plus tôt, Lucas Dohmen publiait Rails is done : pour lui, le cœur de Rails ne bouge quasiment plus depuis 2019, et c’est très bien comme ça. (Son texte parle surtout de gouvernance, j’y reviendrai.)
Qu’il ne bouge plus, d’accord. Que ce soit une bonne chose, beaucoup moins. Je fais du Rails depuis 2008, et sur chaque nouveau projet je refais à la main des trucs que le framework pourrait gérer.
Rails a quand même bougé. Rails 8 a intégré un générateur d’authentification, Solid Queue, Solid Cache et Solid Cable pour se passer de Redis, SQLite en production pour se passer de Postgres ou MySQL, et Kamal pour déployer sur ses propres serveurs.
Tout n’est pas à mon goût, comme le choix du tout-SQLite par défaut : une base de données dans un fichier se prête mal au compute jetable qui scale à la demande. 37signals n’a pas ce problème, puisqu’ils hébergent tout sur leurs propres serveurs depuis leur cloud exit. Heureusement, ce n’est qu’un défaut : rails new -d postgresql, et les Solid tournent sur Postgres.
Rails 8.1, sorti en octobre 2025, a continué : des jobs qui reprennent là où ils s’étaient arrêtés, des événements structurés pour l’observabilité, une CI locale avec bin/ci, et la possibilité de répondre directement en Markdown, parce que Markdown serait devenu la lingua franca de l’IA.
Bref, Rails sait faire. Alors pourquoi s’arrêter là ?
Front-end et assets : un isolement inutile
Pourquoi fermer la porte aux frameworks JS populaires ? Avec rails new, c’est Hotwire ou tu te débrouilles. Laravel propose des starter kits React, Vue et Svelte. Symfony a des intégrations React et Vue. Inertia Rails existe, il manque juste l’option au démarrage.
Pourquoi bouder Vite ? Laravel l’utilise par défaut, Astro est construit dessus, Symfony s’y est mis. Vite Ruby fait le pont, mais rails new ne le propose toujours pas.
Pourquoi rien pour les fonts et les images ? Next.js et Astro auto-hébergent les polices et gèrent nativement srcset, formats modernes et lazy loading. Active Storage s’arrête toujours au simple redimensionnement.
IA et DX : le retard sur les nouveaux standards
Pourquoi pas d’Active LLM ? RubyLLM fait le boulot, mais Laravel a sorti son propre AI SDK (intégré aux queues et à l’ORM) et Symfony a Symfony AI.
Pourquoi pas de fichier AGENTS.md à l’initialisation ? Phoenix et Next.js en génèrent un dès la création du projet pour orienter directement les agents de code.
Pourquoi pas de doc embarquée pour les LLM ? Apple livre des skills avec Xcode pour aider devs et agents à migrer, Next.js embarque sa doc à jour du package.
Architecture backend : la roue réinventée en boucle
Pourquoi chaque équipe réinvente-t-elle ses form objects ? Hanami a ses schémas, Phoenix ses changesets, Django ses Forms. On attend toujours une façon standard de valider les paramètres par cas d’usage.
Pourquoi pas de pagination dans Active Record ? On choisit encore entre Kaminari, Pagy ou will_paginate. Chez Laravel, ->paginate() est dans l’ORM, et Django a son Paginator.
Pourquoi devoir ajouter une gem pour du soft delete ? On installe encore Paranoia ou Discard, là où Eloquent a son trait SoftDeletes et Hibernate son @SoftDelete.
Pourquoi le vide sur les API REST et GraphQL ? Rien pour décrire un schéma, le valider et générer une doc OpenAPI exploitable par un LLM, à la manière de FastAPI.
Les briques produit : ce qu’on recode à chaque projet
Pourquoi aucun système de notifications ? Envoyer un message par e-mail, SMS, Slack ou in-app impose d’écrire une classe par canal. Laravel et Symfony ont leur système multi-canal clé en main.
Pourquoi pas de feature flags ni de recherche native ? Laravel a Pennant et Scout. Côté Rails, on repart systématiquement sur une gem tierce (pg_search, Searchkick) ou une intégration maison.
Pourquoi faire l’impasse sur le SEO et le GEO ? Pas de meta tags, de sitemap ni de llms.txt natifs. Next.js a son API Metadata et génère sitemap et robots, Django a son framework de sitemaps.
Tout se discute. Il en manque, et certains points sont sûrement à côté de la plaque. Mais sur des sujets que presque tous les projets rencontrent, pourquoi réinventer la roue à chaque fois ?
Rails s’est toujours vendu comme le framework d’une seule personne, et sa page Rails is built for AI va plus loin : avec ses conventions et un Ruby très concis, un agent s’y retrouve vite. Dans Pencils Down, Notation Up, Sam Ruby compare deux versions de Campfire : l’app Rails d’origine et sa version compilée en C. En Rails, l’app fait autour de 60 000 tokens, assez peu pour qu’un agent la lise d’un coup. En C, framework compris, autour de 4 millions. Pour lui, même si on finit par compiler nos apps en Rust pour la perf, c’est le code Rails que l’agent devrait modifier. (J’écrivais à peu près la même chose en février.)
Le problème, c’est tout ce que Rails ne couvre pas. Là, l’agent prend une gem au hasard ou code le truc lui-même, avec sa propre structure. Sur une fonctionnalité, ça passe. Sur dix générées en une semaine, on obtient ce que DHH a raconté dans sa keynote à propos de Basecamp 5 : des pull requests correctes une par une, et une architecture en gruyère à la fin.
Je ne demande pas à Rails de tout embarquer. Mais certaines briques ont besoin du reste du framework pour bien marcher : un Active LLM qui lance ses appels dans Active Job, range ses fichiers dans Active Storage et streame ses réponses avec Turbo, ou des feature flags qui connaissent Current.user. Et ça peut passer par un générateur, comme celui de l’authentification dans Rails 8, qui pose le code dans l’app et te laisse le modifier.
Pourquoi ne pas ouvrir une pull request ? Parce qu’ouvrir la porte à React ou ajouter une brique LLM, ça ne se règle pas en une PR, c’est un choix de direction. Et Rails est omakase, comme l’écrivait DHH en 2012 : au restaurant, on laisse le chef composer le menu. Ce qui entre dans le framework vient surtout des besoins de celleux qui le portent, comme les événements structurés de Rails 8.1, menés par Shopify.
Rails n’est pas mort, ni terminé, alors à nous de décider ce qu’on veut en faire. Moi, j’aimerais un framework qui continue de nous emmener de l’idée à la production, en moins de tokens et avec moins de vibe code foireux.
Sauf qu’en omakase, c’est le chef qui décide. Et dans le même billet, DHH se présentait lui-même comme le chef principal. Aujourd’hui, 37signals mise sur Rust pour HEY, et DHH affiche des idées d’extrême droite, racistes et transphobes.
Alors quand le chef décide de tout et qu’on ne se reconnaît plus dans le chef, on fait quoi ?