Skip to content

Why I Switched from REST to tRPC: End-to-End Type Safety and Better Developer Productivity

REST versus tRPC comparison showing traditional API endpoints alongside end-to-end TypeScript type safety and client-server communication.

Originally published February 26, 2026 | Updated October 2026

For years, REST APIs have been a fundamental part of how I’ve built and integrated web applications.

Whether working with WordPress, custom JavaScript applications, external services, or backend integrations, REST has provided a flexible, predictable approach to moving data between systems.

But as modern applications become increasingly complex, particularly those built with TypeScript on both the frontend and backend, maintaining consistent data contracts introduces an additional challenge.

That’s where tRPC (TypeScript Remote Procedure Call) becomes interesting.

Rather than manually maintaining separate API definitions and client-side types, tRPC allows TypeScript applications to infer the available procedures, inputs, and output types directly from the server.

The result is an approach that can reduce boilerplate, improve autocomplete, and catch certain integration mistakes before an application reaches production.

In this article, I’m revisiting why tRPC caught my attention, how it compares with REST, what it offers developers in 2026, and why I still believe REST is the right choice for many projects.

The Problem with Traditional REST APIs

REST isn’t inherently complicated.

In fact, one of its biggest advantages is simplicity.

A typical API might expose endpoints such as:

GET /api/users/123

POST /api/users

PATCH /api/users/123

Each endpoint represents a resource or operation using familiar HTTP methods.

This works exceptionally well when different applications, programming languages, or external services need to communicate.

However, when you’re building both sides of an application in TypeScript, you can end up defining the same information in multiple places.

For example, the backend might define a user response with a name, email address, and role.

The frontend maintains its own TypeScript interface describing that same data.

As the application evolves, those definitions can drift apart.

If a backend property is renamed or its type changes, a manually maintained frontend interface may not reflect that change.

The result can be bugs that only appear when the application runs.

And the larger the application becomes, the more effort it can take to maintain those contracts.

Enter tRPC: A Different Approach to API Communication

tRPC is a TypeScript-focused framework that enables end-to-end type-safe communication between clients and servers.

Unlike a conventional REST workflow, where separate client definitions may be maintained manually, tRPC can infer the API’s TypeScript types directly from its server-side router.

This means the server’s procedure definitions become the source of truth.

When an application changes, the client can recognize corresponding type changes through TypeScript rather than relying on developers to update duplicate definitions.

One of the biggest benefits is that tRPC achieves this without requiring a separate API schema or a code-generation step.

The result can be a more streamlined development experience for applications where the client and server share a TypeScript ecosystem.

How tRPC Works

Consider a simple application that retrieves user information.

With a conventional REST API, the frontend might make a request using fetch() and then parse the JSON response.

With tRPC, the developer creates a server-side procedure and exposes it through a router.

The client then invokes that procedure using an inferred TypeScript interface.

For example, a conceptual tRPC server might expose a procedure named getUserById.

The procedure validates an ID, queries the database, and returns the appropriate user record.

When the client calls that procedure, TypeScript understands the expected input and inferred output types.

This creates several practical benefits.

Autocomplete: Development tools can suggest available procedures and their properties.

Type checking: Many mismatches between expected and actual API types become visible during development or compilation.

Reduced duplication: Developers don’t need to manually reproduce every API type on both sides of the application.

Refactoring support: When an API contract changes, TypeScript can identify affected consumers.

These improvements can become particularly valuable in applications with many related frontend and backend components.

The Biggest Advantage: End-to-End Type Safety

For me, the most compelling part of tRPC is its approach to type safety.

In a conventional TypeScript application, developers can define interfaces that describe the expected shape of an API response.

But those interfaces don’t automatically prove that the remote server actually returns matching data.

TypeScript checks types during development; it doesn’t inherently validate arbitrary JSON responses at runtime.

tRPC approaches this differently by using the server router’s types to inform the client.

When both parts of the application are developed together, this can provide a much stronger connection between implementation and usage.

It can also reduce an entire category of mistakes associated with manually synchronized types.

However, type safety isn’t the same thing as runtime security or input validation.

That’s why tRPC applications commonly pair TypeScript with runtime validation libraries such as Zod.

Together, they provide a foundation for validating incoming data while maintaining useful development-time type information.

Less Boilerplate, More Focus on Application Logic

Another advantage of tRPC is the opportunity to reduce repetitive API plumbing.

A traditional API integration may involve defining a route, maintaining request and response types, writing client wrappers, and keeping everything synchronized.

Those steps aren’t necessarily difficult individually.

But repetition adds up.

In a tightly integrated TypeScript application, tRPC can simplify this process.

Instead of maintaining a separate handwritten client for every endpoint, developers can consume procedures through the typed tRPC client.

This allows more attention to go toward the functionality that actually matters: business logic, application behavior, data validation, and user experience.

For smaller development teams, reducing repetitive code can make a meaningful difference.

tRPC vs. REST: Which Is Better?

Neither approach is universally superior.

They solve overlapping but different problems.

REST is particularly effective when building publicly accessible APIs, connecting independent services, or supporting clients written in multiple programming languages.

tRPC is especially attractive when the frontend and backend are part of the same TypeScript application or share a common development environment.

For example, imagine building an internal dashboard using a TypeScript-based backend and React frontend.

If both applications are developed and deployed together, tRPC can provide a convenient way to keep their communication contracts synchronized.

Now imagine building a public service used by WordPress plugins, mobile applications, external agencies, and third-party integrations.

In that situation, a language-neutral REST API may be considerably more appropriate.

The decision should be based on the architecture of the application, not simply which technology is newer.

What About WordPress?

This is an especially important distinction for my own development work.

WordPress is primarily a PHP-based platform with an established REST API.

Its API ecosystem makes it possible to integrate websites with external applications, JavaScript frontends, automation tools, and third-party services.

tRPC isn’t a direct replacement for the WordPress REST API.

For a standard WordPress site or custom PHP plugin, I would generally continue using the existing REST infrastructure.

However, if I were building a separate TypeScript application with its own backend, tRPC could become useful for communication within that application.

For example, a React application with a dedicated TypeScript backend could use tRPC internally while continuing to communicate with WordPress through REST.

That hybrid architecture could provide a useful balance between established platform compatibility and modern developer experience.

tRPC and React Applications

tRPC also works well with modern React development.

Its ecosystem includes integrations with TanStack Query, providing a way to handle server-state management and API communication.

Depending on the selected integration, developers can use features such as query caching, loading states, mutations, and background refetching.

This can simplify application development by combining typed server procedures with established frontend data-management patterns.

The specifics depend on the version and integration being used.

For projects adopting tRPC today, I recommend following the current v11 documentation rather than copying older examples written for v9 or v10.

Does tRPC Improve Performance?

It’s important to separate developer productivity from raw application performance.

tRPC doesn’t automatically make every request faster than REST.

Network latency, database queries, caching, serialization, and server infrastructure all remain important.

However, tRPC supports request batching through its client links.

This can allow multiple operations to be combined into fewer HTTP requests when appropriately configured.

That may reduce some network overhead in certain applications.

But the actual performance improvement depends on the implementation and workload.

I wouldn’t choose tRPC solely because of performance claims.

Its strongest appeal is the developer experience and type-safe API integration.

What About Security?

Another point worth emphasizing is that end-to-end type safety does not automatically make an application secure.

Even with tRPC, developers still need to implement authentication, authorization, input validation, rate limiting, and appropriate error handling.

For example, a user ID being correctly typed as a string doesn’t establish whether the current user is authorized to retrieve that record.

That permission check must still happen on the server.

Similarly, sensitive values should not be exposed simply because the API is private to an application.

From a cybersecurity perspective, I see tRPC as a useful development tool rather than a replacement for secure application architecture.

When I Would Choose tRPC Today

For a modern project built entirely around TypeScript, I would seriously consider tRPC when:

  • The frontend and backend are maintained together.
  • TypeScript is used throughout the application.
  • Development speed and predictable refactoring are priorities.
  • The application has numerous internal API procedures.
  • The team wants strong editor support without separate client code generation.

For projects with these characteristics, the benefits can outweigh the additional dependency on the tRPC ecosystem.

When I Would Still Choose REST

There are also plenty of situations where REST would remain my preferred approach.

If I’m developing a WordPress plugin, integrating with an established SaaS platform, creating a public API, or connecting systems written in different languages, REST remains an excellent option.

I would also consider REST with OpenAPI-generated TypeScript clients when I need both language-neutral API contracts and strongly typed frontend integrations.

That can provide many of the developer experience benefits associated with tRPC while preserving a more broadly consumable API specification.

Ultimately, the best solution depends on who consumes the API and how independently its clients and server need to evolve.

Should You Migrate an Existing REST API to tRPC?

Not necessarily.

One of the easiest mistakes in software development is introducing architectural changes simply because a newer tool looks appealing.

If an existing REST API is stable, well documented, properly tested, and successfully supports its consumers, there may be little reason to replace it.

For an existing full-stack TypeScript application, adopting tRPC incrementally may make more sense than rewriting everything.

New application functionality can use tRPC while existing REST endpoints continue serving established clients.

This allows teams to evaluate the advantages without creating unnecessary migration risk.

Final Thoughts: Choosing the Right Tool for the Job

My interest in tRPC comes from a broader principle that has guided much of my development work: eliminate unnecessary complexity wherever possible.

When you’re responsible for both the frontend and backend of an application, maintaining duplicate type definitions and manually synchronized API contracts can become repetitive.

tRPC offers an interesting solution by taking advantage of TypeScript’s type inference to connect those layers.

But that doesn’t make REST obsolete.

REST remains one of the most useful approaches to system integration, especially when working with WordPress, external services, and applications built with different technologies.

For me, the takeaway is simple:

Use tRPC when a shared TypeScript ecosystem makes end-to-end type safety valuable. Use REST when interoperability, established standards, and broad compatibility matter more.

The goal isn’t to adopt every new framework.

It’s to build applications that are secure, maintainable, and appropriate for the problem you’re solving.

Further Reading


About the Author

I’m Jeremy Anderson, a software developer, cybersecurity specialist, and AI consultant focused on WordPress development, custom web applications, API integrations, automation, and emerging technologies.

Through Jeremy Anderson Tech, I explore practical approaches to building secure, maintainable, and efficient digital solutions.