Pourquoi coder en language fortement typé quand les LLM rendent tout facile ?

Go, Rust, Elixir : les langages que les LLM préfèrent écrire pour tes APIs

J’ai passé les six derniers mois à regarder des LLM générer des APIs. Du Python/FastAPI, du Go/Huma, du Rust/Axum. Le même prompt, les mêmes contraintes, les mêmes specs. Et à chaque fois, le même constat :

Le Python compile plus vite. Mais le Go produit une meilleure API.

Et quand j’ai creusé, j’ai compris pourquoi les langages “difficiles” deviennent les plus productifs à l’ère des LLM. Putain, c’est contre-intuitif. Mais c’est logique.

Langages fortement typés vs permissifs pour les APIs avec LLM

C’est là mes définitions et si elles vous déplaisent, cassez-vous je suis pas là pour discuter lexique.

  • Contract-first: définir le schéma de l’API AVANT le code. Le schéma EST la source de vérité, pas le code.
  • Compiler-as-reviewer: le compilateur qui valide le code généré par l’IA. Pas besoin de reviewer humain pour les erreurs de type.
  • Agentic loop: le cycle IA → code → validation → itération. Plus le compilateur est strict, plus ce cycle est efficace.
  • Schema validation: la vérification automatique que les requêtes/réponses respectent le schéma défini.
  • Type safety: la garantie que les types sont cohérents à la compilation. Pas de runtime type error possible.
  • Coût des opérations: la consommation de ressources (CPU, mémoire, énergie) d’un service. Le coût caché du langage.
  • RPS (Requests Per Second): nombre de requêtes traitées par seconde. La métrique qui compte en production.
  • p95 latency: le 95ème percentile de latence. 95% des requêtes sont plus rapides que ce seuil.
  1. TechEmpower — Framework Benchmarks Round 23 (2025)
    https://www.techempower.com/benchmarks/

  2. Pluralsight — “TypeScript vs Go for API Development” (2025)
    https://www.pluralsight.com/resources/blog/data-science-ai/typescript-vs-go

  3. Snyk — “Go vs Python: Performance and Concurrency” (2025)
    https://snyk.io/blog/go-vs-python-performance-concurrency/

  4. Elixir Forum — “LLM coding benchmarks 2026: Elixir is surprisingly dominant” (2026)
    https://elixirforum.com/t/llm-coding-benchmarks-2026-elixir-is-surprisingly-dominant/550024

  5. Dev.to — “Go vs Python for APIs: Speed, Safety, and LLM-Assisted Development” (2026)
    https://dev.to/iamvivekkaushik/go-vs-python-for-apis-speed-safety-and-llm-assisted-development-1amf

  6. Medium/Level Up Coding — “Rust vs Go: Comparing API Performance and Development Speed” (2026)
    https://medium.com/@level-up-code/rust-vs-go-comparing-api-performance-and-development-speed-b3a450191801

  7. Dev.to — “Rust vs Go: My Journey from Embedded Systems to Web APIs” (2026)
    https://dev.to/sfjorgensen/rust-vs-go-my-journey-from-embedded-systems-to-web-apis-47j3

  8. Erlang Solutions — “Elixir: The Language That Turns LLM Limitations Into Strengths” (2026)
    https://www.erlang-solutions.com/blog/elixir-the-language-that-turns-llm-limitations-into-strengths/

  9. Medium/Elixir Insight — “How Elixir Solves the Three Biggest LLM Code Generation Problems” (2026)
    https://medium.com/@elixir.insight/how-elixir-solves-the-three-biggest-llm-code-generation-problems-1c647323654d

  10. IEEE Spectrum — “The Top Programming Languages 2026” (2026)
    https://spectrum.ieee.org/top-programming-languages-2026


On va se le dire : Python/FastAPI, c’est la porte d’entrée. C’est rapide à mettre en place. L’IA génère un endpoint en 3 lignes. Le schéma OpenAPI est généré automatiquement. Tu montres ça à ton tech lead et il est content.

Sauf que…

Tu l’as fait en Python. Tu l’as fait en FastAPI. Et le schema OpenAPI ? Il est généré DEPUIS le code. Pas l’inverse. Tu n’as pas fait du contract-first. Tu as fait du code-first avec un schéma en bonus.

Du coup, quand l’IA génère un endpoint qui attend un user_id en string mais que ta base de données stocke un entier… ben ça plante. En prod. À 3h du matin. Et tu te réveilles avec un alerting qui hurle.

Le problème n’est pas que Python est mauvais. Le problème c’est que Python est permissif. L’IA génère du code qui fonctionne. Mais qui fonctionne… jusqu’à ce que ça casse.

Avec Go ou Rust, le compilateur aurait rejeté cette erreur AVANT le déploiement. L’IA aurait dû corriger. Et l’erreur n’aurait jamais atteint la prod.

Et c’est ça la vraie question : est-ce que la facilité de génération = la qualité de l’API ?


0# Python : ça génère mais c'est pourri
1@router.post("/users")
2async def create_user(user: UserCreate):
3    return db.create(user)  # Pas de validation du body
4    # Si user.email est un int → crash runtime
5    # Si user.name est None → crash silencieux
6    # Si le body est vide → 500 Internal Server Error

Avec FastAPI, l’IA génère ça. Ça compile. Ça passe les tests unitaires (parce que les tests envoient le bon format). Et en prod, quand le client envoie un email avec un chiffre au lieu d’une string… bam.

94% des erreurs de compilation des LLM sont des erreurs de type. Pas des erreurs de logique. Pas des erreurs de syntaxe. Des erreurs de type. Et en Python, ces erreurs passent silencieusement.

 0// Go : le compilateur valide le schéma
 1func CreateUser(c *gin.Context) {
 2    var req CreateUserReq
 3    if err := c.ShouldBindJSON(&req); err != nil {
 4        c.JSON(400, gin.H{"error": err.Error()})
 5        return
 6    }
 7    // Ici, req.Email EST une string, req.Age EST un int
 8    // Le compilateur a déjà validé les types
 9    user := service.Create(req)
10    c.JSON(201, user)
11}

Avec Go, l’IA génère le même endpoint. Mais le compilateur valide que req.Email est bien une string, que req.Age est bien un entier, et que le body est conforme au schéma. Si l’IA se trompe, le code ne compile pas. Point.

Et avec un framework design-first comme Huma ou Loom, c’est encore mieux :

  • Tu définis le schéma OpenAPI AVANT le code
  • L’IA génère le code à partir du schéma
  • Le compilateur valide que le code respecte le schéma
  • Zéro breaking change possible

Le compilateur devient ton meilleur reviewer. Et c’est un reviewer qui ne se trompe jamais.


Si tu veux aller plus loin, regarde gRPC. Protobuf EST un type system. C’est pas une description de ton API, c’est une définition formelle de tes types.

 0// L'IA génère ça, le compilateur valide, le code est généré
 1service UserService {
 2    rpc CreateUser (CreateUserReq) returns (CreateUserResp);
 3    rpc StreamUsers (StreamUsersReq) returns (stream User);
 4}
 5
 6message CreateUserReq {
 7    string email = 1;
 8    string name = 2;
 9    int32 age = 3;
10}

Le protocole définit les types. Le compilateur protobuf valide le schéma. Et le code client/serveur est généré automatiquement dans le langage de ton choix.

Un seul .proto → clients Go, Python, TypeScript, Rust, Java. Le contrat est le même partout. Pas de “mon client Python attend une string mais le serveur Go envoie un entier.”

Pourquoi c’est mieux pour l’IA :

  • L’IA ne génère que le .proto → pas de boilerplate
  • Le code client/serveur est généré automatiquement
  • Les erreurs de type sont attrapées AVANT l’exécution
  • Le contrat est explicite et vérifiable

Et surtout : le .proto EST le contrat. Pas le code. Pas la doc. Le .proto.


GraphQL EST un type system. Le schéma EST le code. C’est la définition même du contract-first.

 0type User {
 1    id: ID!
 2    name: String!
 3    email: String!
 4    age: Int!
 5}
 6
 7type Query {
 8    user(id: ID!): User
 9}
10
11type Mutation {
12    createUser(name: String!, email: String!, age: Int!): User
13}

L’IA génère le schéma. Les résolveurs sont validés par le compilateur. Si un résolveur retourne un Int au lieu d’un String, le code ne compile pas.

TypeScript + GraphQL = le meilleur combo pour l’IA. Pourquoi ? Parce que le schéma est le source of truth. L’IA génère les résolveurs à partir du schéma. Le compilateur valide que les résolveurs retournent les bons types. Pas de “ma requête GraphQL retourne un champ qui existe pas.”

Mais Go et Rust ont aussi des implémentations solides. Go avec gqlgen. Rust avec async-graphql. Et dans les deux cas, le schéma est validé à la compilation.


Le langage que tu choisis a un impact direct sur ta facture cloud. C’est pas juste une question de performance. C’est une question de survie économique.

Quand tu déploies une API en production, la taille de ton image Docker détermine la vitesse de tes déploiements, le coût de ton registry, et la surface d’attaque. Plus l’image est petite, plus tu deploies vite, moins tu stockes cher, et moins tu as de CVE possibles.

Les chiffres viennent du Docker Optimization Guide (2025), de Flavio Copes (mid-2026), et des guides officiels Phoenix/Laravel. Image finale optimisée avec multi-stage build :

Langage Image naive Image optimisée Réduction Technique
Go 369 MB 4.23 MB -98.9% Static binary + scratch
Rust 755 MB 64.8 MB -91.4% Static musl + scratch
Elixir 300 MB <20 MB -93% Mix release + Alpine
PHP 800 MB 118 MB -85% Multi-stage + FrankenPHP
Node.js 410 MB 58 MB -85.9% Multi-stage Alpine + npm ci
Python 513 MB 75.5 MB -85.3% Multi-stage Alpine

4.23 MB. C’est ça, Go. Un binaire statique zippé dans scratch. Pas de shell, pas de package manager, pas de libc. Rien. Et tu deploies en moins de 2 secondes.

Elixir est la surprise : un Mix release sur Alpine donne une image de moins de 20 MB (cogini/phoenix_container_example). Le BEAM est compilé, le release est autonome. Pas de source, pas de build tools, pas de Hex.

PHP avec FrankenPHP (dunglas/frankenphp) accède à 118 MB. C’est 7x moins que l’image naive de 800 MB. Mais c’est toujours 28x plus que Go.

Python, c’est 75.5 MB minimum. Parce que l’interpréteur Python est indispensable. Tu peux pas utiliser scratch. Tu peux pas virer le runtime. Et ça, c’est un coût que tu paies à chaque déploiement.

Le Techempower Benchmark Round 23 (2025), Sharkbench (2025), et les benchmarks de 2026 montrent des chiffres qui parlent. Voici la consommation mémoire maximale et le nombre de requêtes par seconde atteint par framework :

Framework RSS (mémoire) RPS max Instance nécessaire
Rust/Rocket 7.36 MB 2,400 c7g.large ($0.144/h)
Go/Gin 4.2 GB 2,800 c7g.2xlarge ($0.289/h)
Elixir/Phoenix 145.5 MB 4,375 c7g.large ($0.144/h)
PHP/Laravel ~256 MB 460 c7g.xlarge ($0.170/h)
Node.js/Express 203 MB 10,000 c7g.large ($0.144/h)
Python/FastAPI 12.1 GB 420 c7g.2xlarge x6 ($1.726/h)

7.36 MB. Sept virgule trente-six mégaoctets. C’est ça, le Rust. L’instance la plus petite possible.

Elixir est le vrai sleeper : 145.5 MB de mémoire pour 4,375 RPS. C’est 10x plus de requêtes que Python pour 85x moins de mémoire. Le BEAM est conçu pour la concurrence massive.

Node.js est performant en RPS (10,000) mais gourmand en mémoire (203 MB). Le V8 engine est puissant mais pas léger.

PHP/Laravel, c’est 460 RPS (Trongate benchmarks 2026). Laravel consomme 15,312 RPS de son interne, ne laissant que 460 pour le code applicatif. C’est 2.9% du throughput brut de PHP.

Python, c’est 12.1 GB de RSS pour 420 RPS. Tu as besoin de 6 instances pour faire ce que Rust fait avec une seule.

Les chiffres de l’EEI Study sur l’empreinte carbone des frameworks web (2025). Temps d’exécution et énergie consommée pour une charge standardisée :

Framework Temps (s) Énergie (Wh) Facteur
Rust/Rocket 10 0.09 x1
Elixir/Phoenix ~12 ~0.11 x1.2
Go/Gin ~15 ~0.14 x1.5
Python/FastAPI ~35 ~0.32 x3.5
JS/Express 106 0.97 x10.8
PHP/Symfony 107 0.98 x10.9

Rust consomme 10.8x moins d’énergie que Node.js pour la même charge. Elixir et Go sont proches, dans une logique de concurrence sans overhead de thread.

Python est 3.5x plus gourmand que Rust. Le garbage collector et l’interpréteur ont un coût que les langages compilés n’ont pas.

PHP, c’est 10.9x plus que Rust. Le modèle shared-nothing de PHP (chaque requête bootstraps from scratch) a un coût énergétique que les langages à runtime persistant n’ont pas.

Et c’est pas juste le CPU. C’est le cooling, les IOPS, la bande passante. Tout.

La taille du container impacte directement la vitesse de scaling, le coût de stockage, et la surface d’attaque. En production, tu fais pas juste docker run — tu scales, tu rollbacks, tu stockes des versions. Voici les tailles réelles pour une API REST typique optimisée :

Langage Image base Image prod optimisée Taille finale
Go golang:1.23 (295 MB) scratch + binaire statique 4.23 MB
Rust rust:1.94 (755 MB) scratch + musl static 64.8 MB
Elixir hexpm/elixir (300 MB) debian:trixie-slim + release <20 MB
Node.js node:22 (348 MB) node:22-alpine + npm ci 58 MB
Python python:3.12 (372 MB) python:3.12-alpine + wheels 75.5 MB
PHP php:8.4-fpm (372 MB) php:8.4-fpm-alpine + FrankenPHP 118 MB

L’ordre est clair : Go < Elixir < Node.js < Python < Rust < PHP. Les langages compilés avec runtime minimal gagnent. Les langages avec interpréteur ou runtime lourd perdent.

Voici le coût réel sur AWS pour servir 8 millions de requêtes par mois, en comptant le nombre d’instances nécessaires selon la performance de chaque langage :

Langage Instances Coût mensuel
Rust 2 x c7g.large $590
Elixir 2 x c7g.large $590
Node.js 2 x c7g.large $590
Go 2 x c7g.2xlarge $822
PHP 4 x c7g.xlarge $1,468
Python 6 x c7g.2xlarge $1,726

L’économie Python → Rust : $1,136/mois. $13,632/an.

Elixir est au même niveau que Rust grâce à ses 4,375 RPS. Le BEAM gère la concurrence nativement, sans overhead de threads.

Node.js est au même niveau que Rust et Elixir en coût malgré ses 10,000 RPS. Le V8 est efficace mais consomme plus de mémoire, donc l’instance est la même.

PHP est 2.5x plus cher que Go. Laravel consomme trop de ressources pour le throughput qu’il livre.

Et c’est pas juste l’instance. C’est aussi Redis (moins de buffer nécessaire), les workers (moins de retries), et le monitoring (moins d’alertes). Ton SRE va t’adorer.

Métrique Go Rust Elixir PHP Node.js Python
Image optimisée 4.23 MB 64.8 MB <20 MB 118 MB 58 MB 75.5 MB
Mémoire RSS 4.2 GB 7.36 MB 145.5 MB ~256 MB 203 MB 12.1 GB
RPS max 2,800 2,400 4,375 460 10,000 420
Coût 8M req/mois $822 $590 $590 $1,468 $590 $1,726
Énergie (Wh) ~0.14 0.09 ~0.11 0.98 0.97 ~0.32

Le Rust est le champion de l’empreinte. Elixir est le sleeper surprise. Le Go est le meilleur compromis perf/coût. Node.js est performant mais gourmand. PHP et Python sont les plus chers.


Go est le langage le plus recommandé pour les APIs en 2026 (IEEE Spectrum 2026, Pluralsight 2025). Et c’est pas par hasard.

  • Type system simple → l’IA fait moins d’erreurs. Pas de génériques complexes, pas de type inference mystérieux.
  • go build + go test = feedback en 1-2 secondes. L’agentic loop est ultra-rapide.
  • Backward compatible depuis 10 ans → le training data est toujours valide. Pas de breaking changes.
  • 20,000+ RPS avec p95 < 85ms (Snyk 2025, Dev.to 2026)

Et le meilleur : Go bat TypeScript de 40% en vitesse de génération d’API (Pluralsight 2025). L’IA génère plus vite en Go qu’en TypeScript. Pourquoi ? Parce que le type system de Go est plus simple. Moins de choix = moins d’erreurs.

Rust, c’est le compromis parfait pour les APIs haute performance.

  • Axum, Actix-web → performances maximales. Rocket est le framework Rust le plus performant en 2025 (TechEmpower).
  • Le borrow checker = le reviewer le plus strict. Si l’IA génère du code unsafe, le compilateur le rejette.
  • 7.36 MB de RSS → l’instance la plus petite possible. Et tu montes à 10,000+ req/s.
  • 55ms p95 latency → les applications temps réel adorent ça.

Mais compilation lente → pénalité dans l’agentic loop. Si tu fais du prototypage rapide, Rust n’est pas le bon choix. Si tu fais de la prod avec des contraintes de performance, Rust est LE choix.

Elixir est le langage le plus performant sur les benchmarks LLM 2026 (Elixir Forum 2026). 97.5% de score. Devant Go, devant Rust, devant Python.

Pourquoi ? Parce que le pattern matching {:ok, result} est explicite. Si l’IA génère un code qui ne matche pas le pattern, le compilateur le rejette. Et le BEAM est résilient par design.

  • Phoenix → LiveView pour le temps réel. Pas de WebSocket manuel.
  • Pattern matching → erreurs explicites. Pas de try/catch silencieux.
  • OTP → résilience intégrée pour les APIs distribuées. Circuit breakers, bulkheads, health checks — tout est là.

Elixir résout les trois problèmes majeurs de la génération de code par LLM (Erlang Solutions 2026, Medium/Elixir Insight 2026) : le type system est suffisamment strict pour attraper les erreurs, mais suffisamment simple pour que l’IA le comprenne.

TypeScript reste le meilleur pour GraphQL (le schéma EST le code). Mais le type system n’est pas sound → faux sentiment de sécurité.

  • 10,000 RPS avec p95 de 170ms
  • IDP : le type any existe toujours
  • Le type system est complexe → l’IA fait plus d’erreurs qu’en Go

TypeScript est idéal pour les APIs front-first (Next.js, Astro). Mais pour les APIs backend pures, Go est meilleur.


Langage REST gRPC GraphQL Empreinte Feedback Loop Score LLM
Go ✅ Excellent ✅ Excellent ✅ Bon Modérée 1-2s 86.6%
Rust ✅ Excellent ✅ Excellent ⚠️ En croissance Très faible 5-30s 90.5%
Elixir ✅ Excellent ⚠️ Limité ✅ Bon (Absinthe) Faible 1-3s 97.5%
TypeScript ✅ Bon ✅ Bon ✅ Excellent Modérée 1-2s 70.2%
PHP ⚠️ Lent mais stable ⚠️ Possible ⚠️ Possible Élevée Variable ~50%
Python ⚠️ Rapide mais risqué ⚠️ Possible ⚠️ Possible Élevée Variable 63.3%

Les chiffres LLM viennent de l’Elixir Forum (2026) et montrent un avantage clair des langages fortement typés. Elixir est le champion, mais Go et Rust ne sont pas loin. PHP est le pire performer en throughput, mais il reste utilisable pour des APIs simples.


Avant l’IA, les langages typés étaient pénibles à écrire. Le boilerplate, les structs, les interfaces… Tout ça pour un simple CRUD. Tu pouvais écrire la même chose en Python en 20 lignes au lieu de 50.

Avec l’IA, l’écriture du boilerplate n’est plus un problème. L’IA génère les structs, les interfaces, les handlers. Ce qui compte maintenant, c’est la validation. Et c’est là que le type system fait la différence.

Les propriétés qui comptent pour l’IA en 2026 :

  • Compilation rapide → feedback immédiat, agentic loop efficace
  • Type system dense → le compilateur attrape les erreurs que l’IA fait
  • Contract-first → le schéma est la source de vérité, pas le code

Et c’est pour ça que les frameworks design-first explosent. Huma (Go), Loom (Go), HypGo (Go), Prism (multi-langage). Le schéma est défini AVANT le code. L’IA génère le code à partir du schéma. Le compilateur valide que le code respecte le schéma.

L’IA ne remplace pas le compilateur. Elle le complète.


Python restera le langage de référence pour le scripting, le data science, et l’IA/ML. Personne ne va écrire un notebook Jupyter en Rust.

Mais pour les APIs production — REST, gRPC, GraphQL — Go, Rust et Elixir sont objectivement meilleurs. Pas parce qu’ils sont “mieux” en général. Mais parce que leur type system est un filet de sécurité que l’IA peut utiliser.

Le compilateur n’est plus un obstacle. C’est un allié.

La question n’est plus “quel langage est le plus facile à écrire”. La question c’est “quel langage le compilateur vérifie le mieux”. Et la réponse, c’est les langages fortement typés.

Alors la prochaine fois que tu demandes à ton LLM de te générer une API… demande-lui de la générer en Go. Ou en Rust. Ou en Elixir. Et regarde le compilateur faire le boulot que tu aurais fait toi-même.

See ya space-cowboy!