Nehos Groupe
Définition & Concepts

tRPC

Version Décideur

L'essentiel

Avec une API REST classique, vous écrivez un endpoint côté serveur, vous documentez les types (souvent dans un fichier OpenAPI ou à la main), et vous réécrivez ces mêmes types côté client. Trois sources de vérité qui se désynchronisent dès qu'un développeur modifie le serveur sans mettre à jour la doc. Avec GraphQL, vous gérez un schéma .graphql, vous générez des types TypeScript depuis ce schéma (codegen), vous attendez le terminal. Puissant, mais lourd pour une équipe de 2 à 5 développeurs sur un projet interne. Avec tRPC : vous écrivez une fonction TypeScript côté serveur. C'est tout. Côté client, vous appelez cette fonction et TypeScript sait déjà ce qu'elle retourne. Pas de doc à maintenir, pas de code à générer. Si le serveur change, le client TypeScript refuse de compiler. L'erreur est attrapée avant d'arriver en production. C'est le choix évident pour un monorepo Next.js où le frontend et le backend sont dans le même dépôt. En dehors de ce contexte précis, c'est généralement le mauvais outil.

Version Expert

Détails Techniques

tRPC (TypeScript Remote Procedure Call) est un framework open source (MIT) conçu pour construire des APIs client-serveur entièrement typées en TypeScript, sans étape de génération de code intermédiaire et sans langage de description d'interface (pas de GraphQL SDL, pas d'OpenAPI YAML). **Fonctionnement technique** : 1. **Définition des procédures serveur** avec validation Zod : ```ts // server/routers/user.ts import { z } from 'zod' import { router, publicProcedure } from '../trpc' export const userRouter = router({ getById: publicProcedure .input(z.object({ id: z.string().uuid() })) .query(async ({ input, ctx }) => { return ctx.db.user.findUniqueOrThrow({ where: { id: input.id } }) }), create: publicProcedure .input(z.object({ email: z.string().email(), name: z.string().min(2) })) .mutation(async ({ input, ctx }) => { return ctx.db.user.create({ data: input }) }), }) ``` 2. **Export du type AppRouter** depuis le serveur — seul le type est exporté (pas le code serveur) : ```ts // server/index.ts export type AppRouter = typeof appRouter ``` 3. **Client entièrement typé sans configuration manuelle** : ```ts // client import { createTRPCClient } from '@trpc/client' import type { AppRouter } from '../server' const trpc = createTRPCClient<AppRouter>({ /* ... */ }) // TypeScript infère automatiquement : { id: string, email: string, name: string, ... } const user = await trpc.user.getById.query({ id: '...' }) ``` **Transport** : tRPC utilise HTTP (JSON par défaut) ou WebSocket pour les subscriptions. Il s'intègre dans Next.js via un handler dans `app/api/trpc/[trpc]/route.ts`. **Context et middleware** : système de contexte typé (accès DB, session, permissions) et middleware de procédure (protectedProcedure, adminProcedure) similaire aux middleware Express mais avec inférence de types sur le contexte. **Zod** est recommandé (mais pas obligatoire) pour la validation des inputs. D'autres validateurs (Valibot, Yup, ArkType) sont supportés via l'adaptateur `@trpc/server/adapters`.

#Définition tRPC

tRPC (TypeScript Remote Procedure Call) est un framework open source (MIT) conçu pour construire des APIs client-serveur entièrement typées en TypeScript, sans étape de génération de code intermédiaire et sans langage de description d'interface (pas de GraphQL SDL, pas d'OpenAPI YAML). Fonctionnement technique : Pour approfondir, consultez la page service Development Next.js Nehos.

Traduit en termes opérationnels, 1. Définition des procédures serveur avec validation Zod : ts // server/routers/user.ts import { z } from 'zod' import { router, publicProcedure } from './trpc' export const userRouter = router({ getById: publicProcedure .input(z.object({ id: z.string().uuid() })) .query(async ({ input, ctx }) => { return ctx.db.user.findUniqueOrThrow({ where: { id: input.id } }) }), create: publicProcedure .input(z.object({ email: z.string().email(), name: z.string().min(2) })) .mutation(async ({ input, ctx }) => { return ctx.db.user.create({ data: input }) }), }) 2. Export du type AppRouter depuis le serveur — seul le type est exporté (pas le code serveur) : ts // server/index.ts export type AppRouter = typeof appRouter 3. Client entièrement typé sans configuration manuelle : ts // client import { createTRPCClient } from '@trpc/client' import type { AppRouter } from './server' const trpc = createTRPCClient<AppRouter>({ /* .. */ }) // TypeScript infère automatiquement : { id: string, email: string, name: string, .. } const user = await trpc.user.getById.query({ id: '..' }) Transport : tRPC utilise HTTP (JSON par défaut) ou WebSocket pour les subscriptions. Il s'intègre dans Next.js via un handler dans app/api/trpc/[trpc]/route.ts. Context et middleware : système de contexte typé (accès DB, session, permissions) et middleware de procédure (protectedProcedure, adminProcedure) similaire aux middleware Express mais avec inférence de types sur le contexte. Zod est recommandé (mais pas obligatoire) pour la validation des inputs. D'autres validateurs (Valibot, Yup, ArkType) sont supportés via l'adaptateur @trpc/server/adapters.

La compréhension fine de tRPC différencie les équipes qui livrent des résultats de celles qui accumulent de la dette.

#tRPC expliqué simplement

Avec une API REST classique, vous écrivez un endpoint côté serveur, vous documentez les types (souvent dans un fichier OpenAPI ou à la main), et vous réécrivez ces mêmes types côté client. Trois sources de vérité qui se désynchronisent dès qu'un développeur modifie le serveur sans mettre à jour la doc.

Avec GraphQL, vous gérez un schéma .graphql, vous générez des types TypeScript depuis ce schéma (codegen), vous attendez le terminal. Puissant, mais lourd pour une équipe de 2 à 5 développeurs sur un projet interne.

Avec tRPC : vous écrivez une fonction TypeScript côté serveur. C'est tout. Côté client, vous appelez cette fonction et TypeScript sait déjà ce qu'elle retourne. Pas de doc à maintenir, pas de code à générer. Si le serveur change, le client TypeScript refuse de compiler. L'erreur est attrapée avant d'arriver en production.

C'est le choix évident pour un monorepo Next.js où le frontend et le backend sont dans le même dépôt. En dehors de ce contexte précis, c'est généralement le mauvais outil.

Imaginez que vous dirigez une PME ou une scale-up. La différence entre théorie et terrain ? Les chiffres. Et les chiffres, on les a.

#Cas d'usage concrets

SaaS B2B Next.js monorepo (tRPC + Zod + Better Auth) — Application SaaS RH en monorepo Turborepo : apps/web (Next.js 16) + apps/api (Next.js API routes tRPC) + packages/types. 47 procédures tRPC (queries + mutations + 3 subscriptions WebSocket). Validation Zod sur tous les inputs. Better Auth pour la session passée en contexte tRPC. Résultat : zéro erreur de type serveur/client en production sur 14 mois. Refactorings de types : le compilateur détecte les incohérences avant le merge. Temps de développement -30 % vs approche REST + types manuels estimé par l'équipe.

Outil interne Nehos (dashboard analytics + reporting) — Dashboard analytics interne Nehos : Next.js App Router + tRPC pour les Server Actions enrichies. Procédures pour l'agrégation des données de performance SEO, génération de rapports PDF, gestion des accès clients. tRPC React Query integration (@trpc/react-query) pour le cache client-side. Avantage mesuré : onboarding d'un nouveau dev sur le codebase en 90 min (types auto-documentés dans l'IDE) vs 3h avec une API REST non typée documentée en Notion.

Migration Express REST → tRPC pour une startup scale-up — Startup EdTech : migration de 23 endpoints REST Express non typés vers tRPC en 3 sprints. Phase 1 : ajouter tRPC en parallèle de l'API REST existante. Phase 2 : migrer les consommateurs un par un. Phase 3 : supprimer les anciens endpoints. Bilan : 34 bugs de types runtime éliminés (types string/number incohérents entre front et back), dette technique estimée à -180h de corrections futures, DX développeur améliorée (autocomplétion IDE sur 100 % des appels API).

#tRPC chez Nehos Groupe

Chez Nehos, on a mesuré les résultats sur le terrain. Sur les 3 derniers projets impliquant tRPC, on a documenté les résultats avec des KPIs précis. Notre service Development Next.js Nehos couvre ce périmètre de A à Z.

La méthode Nehos est documentée sur stack technique Nehos 2026 (Next.js + tRPC + Payload). Chaque mission démarre par un cadrage structuré : objectifs chiffrés, périmètre technique, jalons à 30/60/90 jours. Les résultats mesurés sur nos clients : 30 % est un ordre de grandeur courant. On livre, on mesure, on itère. Pas de slides sans livrable.

#Termes associés

Ce concept ne vit pas isolé.

Chaque terme est défini dans notre glossaire avec la même approche : définition technique, vulgarisation, cas concrets et méthode Nehos.

Applications Concrètes

Contexte : SaaS B2B Next.js monorepo (tRPC + Zod + Better Auth)

"Application SaaS RH en monorepo Turborepo : apps/web (Next.js 16) + apps/api (Next.js API routes tRPC) + packages/types. 47 procédures tRPC (queries + mutations + 3 subscriptions WebSocket). Validation Zod sur tous les inputs. Better Auth pour la session passée en contexte tRPC. Résultat : zéro erreur de type serveur/client en production sur 14 mois. Refactorings de types : le compilateur détecte les incohérences avant le merge. Temps de développement -30 % vs approche REST + types manuels estimé par l'équipe."

Contexte : Outil interne Nehos (dashboard analytics + reporting)

"Dashboard analytics interne Nehos : Next.js App Router + tRPC pour les Server Actions enrichies. Procédures pour l'agrégation des données de performance SEO, génération de rapports PDF, gestion des accès clients. tRPC React Query integration (`@trpc/react-query`) pour le cache client-side. Avantage mesuré : onboarding d'un nouveau dev sur le codebase en 90 min (types auto-documentés dans l'IDE) vs 3h avec une API REST non typée documentée en Notion."

Contexte : Migration Express REST → tRPC pour une startup scale-up

"Startup EdTech : migration de 23 endpoints REST Express non typés vers tRPC en 3 sprints. Phase 1 : ajouter tRPC en parallèle de l'API REST existante. Phase 2 : migrer les consommateurs un par un. Phase 3 : supprimer les anciens endpoints. Bilan : 34 bugs de types runtime éliminés (types string/number incohérents entre front et back), dette technique estimée à -180h de corrections futures, DX développeur améliorée (autocomplétion IDE sur 100 % des appels API)."

Questions & Réponses

Questions fréquentes sur tRPC

Deux cas d'usage distincts, pas vraiment concurrents. tRPC : choix optimal si server et client sont dans le même monorepo TypeScript, équipe de 2 à 10 développeurs, API interne non exposée publiquement. DX supérieure (pas de codegen, types auto-inférés), intégration native Next.js. GraphQL : choix optimal si l'API doit être consommée par des clients externes (app mobile tierce, partenaires), si plusieurs clients avec des besoins de données différents (query flexible), ou si l'équipe est déjà formée GraphQL. En monorepo Next.js full-stack, tRPC gagne haut la main sur la DX. Sur une API publique multi-clients, GraphQL est imbattable.
Quatre situations où REST/OpenAPI est le bon choix face à tRPC. (1) API publique documentée pour des consommateurs externes (partenaires, intégrateurs, clients enterprise) : OpenAPI génère une spec lisible, des SDK dans n'importe quel langage. (2) Architecture microservices multi-langages : service Python consommant une API Node.js — tRPC ne fonctionne qu'en TypeScript. (3) Équipe mobile (iOS Swift, Android Kotlin) sans couche TypeScript partagée. (4) Réglementations imposant une documentation d'API formelle auditée. Pour Nehos, la règle est simple : API interne monorepo = tRPC, API publique ou multi-clients = REST/OpenAPI ou GraphQL.
Oui, avec quelques adaptations. Le handler tRPC est placé dans `app/api/trpc/[trpc]/route.ts` (fetch handler). Les React Server Components (RSC) peuvent appeler directement les procédures serveur sans passer par HTTP (appel direct de la fonction router) — pattern appelé 'server-side caller'. Les Client Components utilisent `@trpc/react-query` pour les queries et mutations avec cache React Query. La combinaison tRPC + RSC + React Query couvre tous les patterns de fetching dans App Router.
Via le contexte tRPC. Le contexte est créé à chaque requête et contient la session utilisateur. Pattern recommandé avec Better Auth ou NextAuth : récupérer la session dans la fonction `createContext`, la passer dans le contexte. Créer un middleware `protectedProcedure` qui vérifie `ctx.session` et lance une `TRPCError({ code: 'UNAUTHORIZED' })` si absent. Toutes les procédures nécessitant une authentification utilisent `protectedProcedure` au lieu de `publicProcedure`. Le typage garantit que `ctx.session` est non-null dans les procédures protégées.
Quatre limites réelles documentées. (1) Pas de spec exportable : impossible de générer automatiquement une Postman collection ou une doc Swagger lisible par des non-développeurs. (2) Typage uniquement TypeScript : les clients mobiles (Swift, Kotlin) ne peuvent pas bénéficier de l'inférence de types. (3) Difficile à scaler en microservices : tRPC suppose une co-localisation des types, compliqué si les services sont dans des repos séparés (bien que des patterns existent). (4) Debugging réseau plus complexe : les requêtes tRPC ont des URLs moins lisibles (`/api/trpc/user.getById`) que des routes REST sémantiques.
Pas directement. Payload CMS expose sa propre API REST et GraphQL pour l'accès aux collections. Dans l'architecture Nehos, tRPC est utilisé pour la logique métier custom (procédures non couvertes par Payload) dans `apps/web`, pas pour wrapper l'API Payload. Exemple : Payload gère les CRUD de contenus via son API GraphQL native, tRPC gère les procédures métier custom (calculs analytics, workflows d'approbation, intégrations tierces). Les deux coexistent dans le monorepo sans conflit.
tRPC n'a pas de versioning natif (pas de `/v1`, `/v2`). Dans un monorepo, c'est un non-problème : client et serveur évoluent en même temps dans le même repo. Pour une API tRPC exposée à des clients externes (cas rare mais possible), deux approches : (1) créer des routers versionnés (`v1Router`, `v2Router`) et maintenir les deux pendant la transition, (2) ajouter des champs optionnels sans supprimer les anciens (évolution additive). Si le besoin de versioning est fort, c'est souvent le signe que REST/OpenAPI serait plus approprié.
Réserver un audit