tRPC vs GraphQL Comparación

Cero generación de código, seguridad de tipos TypeScript de extremo a extremo

VS
GraphQL

Esquema primero, lenguaje de consulta universal para múltiples clientes

16 min de lecturaBackend

Veredicto rápido

Decide según el contexto — la 'seguridad de tipos' por sí sola no es una razón para elegir GraphQL. Si usas un único monorepo TypeScript con un único cliente web, tRPC casi siempre reduce más el trabajo: cero codegen, y un cambio en el servidor se convierte al instante en un error de TS en el cliente. Si tienes una app móvil, una API pública abierta a desarrolladores externos o necesitas federación multi-equipo, el contrato de esquema independiente del lenguaje de GraphQL y su ecosistema Apollo Federation ofrecen una ventaja estructural.

tRPCGraphQL
Leer el veredicto completo

Comparación de puntuaciones

Cargando gráfico...

Puntuación detallada

Puntuación detallada: tRPC y GraphQL — puntuaciones por categoría sobre 10
CategoríatRPCGraphQL
Rendimiento
7/10
6/10
Facilidad de aprendizaje
8/10
5/10
Ecosistema
6/10
9/10
Comunidad
7/10
8/10
Mercado laboral
5/10
8/10
A prueba de futuro
7/10
8/10

Pros y contras

tRPC

Pros

  • No hay generación de código ni paso de compilación — los tipos del servidor fluyen directamente al cliente
  • Cuando modificas el servidor, el cliente ve el error de TypeScript antes de guardar el archivo
  • Existen adaptadores oficiales para React, Next.js, Express, Fastify, AWS Lambda, Solid y Svelte
  • Integración nativa con TanStack Query — las factories de queryKey/queryOptions vienen listas
  • Empresas como Netflix y Pleo lo usan en producción según las FAQ oficiales
  • Incluso la dependencia de TanStack Query es opcional — basta un cliente vanilla sencillo
  • Las subscriptions se admiten con WebSocket o SSE; se recomienda la configuración SSE por ser más simple
  • Licencia MIT, totalmente de código abierto — sin capa empresarial de pago

Contras

  • El uso compartido de tipos depende del mismo monorepo TypeScript — un cliente móvil nativo pierde esta ventaja
  • No existe una superficie de API pública/REST oficial; se necesita un paquete de terceros como `trpc-to-openapi`
  • No tiene introspección de esquema — no ofrece a un desarrollador externo un contrato autodocumentado
  • No hay selección de campos — cada procedimiento tiene un tipo de retorno fijo
  • No se puede usar en escenarios donde el backend está en un lenguaje distinto de JavaScript/TypeScript
  • No existe un estándar oficial de composición de esquemas para federación/múltiples servicios

Ideal para

Productos con un único monorepo TypeScript + un único cliente webProyectos full-stack TS basados en Next.js, Express o FastifyEquipos pequeños-medianos que buscan iteración rápidaHerramientas internas y paneles de administración sin consumidores externosProyectos que ya usan TanStack Query

GraphQL

Pros

  • El cliente selecciona solo los campos que necesita — el over/under-fetching se resuelve estructuralmente
  • Contrato de esquema independiente del lenguaje — da servicio nativo a iOS, Android, web y cualquier cliente de terceros
  • Se autodocumenta mediante introspección; es explorable con herramientas como GraphiQL
  • Permite la evolución del esquema sin cambios disruptivos gracias al mecanismo de deprecation
  • El paquete oficial `graphql/dataloader` resuelve el problema N+1 con batching y caching
  • Apollo Federation ofrece soporte oficial de composición en arquitecturas multi-equipo/multi-servicio
  • Está gobernado desde 2018 por la GraphQL Foundation, bajo el paraguas de la Linux Foundation
  • Clientes oficiales como Relay evitan renders innecesarios con una caché normalizada

Contras

  • No tiene una estructura de URL compatible con caché HTTP — requiere ID global + caché de cliente normalizada
  • El diseño de esquemas, la arquitectura de resolvers y conceptos como dataloader elevan la curva de aprendizaje
  • La federación todavía está en proceso de estandarización — el Composite Schema Working Group sigue activo
  • A escala empresarial, capas como Apollo GraphOS son de pago (plan Developer: 5 $ por millón de solicitudes)
  • Dejar el riesgo de N+1 sin dataloader es una clase de error frecuente
  • En escenarios CRUD simples requiere más boilerplate (esquema + resolver) que tRPC o REST

Ideal para

APIs con consumidores móviles (iOS/Android) o de tercerosArquitecturas que requieren federación en organizaciones multi-equipo/multi-servicioAPIs públicas que se abrirán a desarrolladores externosAplicaciones que consultan grafos de datos complejos y anidadosSistemas a gran escala que requieren SLA empresarial y gobernanza de esquemas

Comparación de código

tRPC
// tRPC — definición de router (servidor)
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
// db = cliente Prisma/ORM (importado desde un archivo aparte)

const t = initTRPC.create();

export const appRouter = t.router({
  getUser: t.procedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      return db.user.findUnique({ where: { id: input.id } });
    }),
});

export type AppRouter = typeof appRouter;

// Cliente — el tipo del servidor se infiere automáticamente, sin codegen
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from './server';

const client = createTRPCClient<AppRouter>({
  links: [httpBatchLink({ url: 'http://localhost:3000/trpc' })],
});

const user = await client.getUser.query({ id: '1' });
// user: { id: string; name: string; ... } — seguridad de tipos completa en tiempo de compilación
GraphQL
// graphql-js + @apollo/server — esquema, resolver y servidor en un solo archivo
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
// db = cliente Prisma/ORM (importado desde un archivo aparte)

const typeDefs = `#graphql
  type Post {
    id: ID!
    title: String!
  }

  type User {
    id: ID!
    name: String!
    posts: [Post!]!
  }

  type Query {
    user(id: ID!): User
  }
`;

const resolvers = {
  Query: {
    user: (_parent, { id }, { db }) => db.user.findUnique({ where: { id } }),
  },
  User: {
    posts: (user, _args, { db }) =>
      db.post.findMany({ where: { authorId: user.id } }),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

const { url } = await startStandaloneServer(server, {
  context: async () => ({ db }),
  listen: { port: 4000 },
});
console.log(`Servidor listo: ${url}`);

// Consulta del cliente — solo se seleccionan los campos necesarios:
// query { user(id: "1") { name posts { title } } }

Conclusión

Decide según el contexto — la 'seguridad de tipos' por sí sola no es una razón para elegir GraphQL. Si usas un único monorepo TypeScript con un único cliente web, tRPC casi siempre reduce más el trabajo: cero codegen, y un cambio en el servidor se convierte al instante en un error de TS en el cliente. Si tienes una app móvil, una API pública abierta a desarrolladores externos o necesitas federación multi-equipo, el contrato de esquema independiente del lenguaje de GraphQL y su ecosistema Apollo Federation ofrecen una ventaja estructural.

Solicita una consultoría gratuita
FAQ

Preguntas frecuentes

Si trabajas en un único monorepo TypeScript con un único cliente web, tRPC requiere menos código y configuración (cero codegen, inferencia de TS de extremo a extremo — trpc.io). Si tienes una app móvil, una API pública abierta a desarrolladores externos o varios servicios independientes, el contrato de esquema de GraphQL y su ecosistema de federación (Apollo Federation) ofrecen una abstracción más adecuada.

Artículos de blog relacionados

Ver todos los artículos
Todas las comparaciones