Remix and GraphQL: A match made in heaven with type-safety DX

Learn how to use GenQL and Remix with GraphQL to provide a better solution, improve its shortcomings, and enhance development experience (DX).

One common challenge developers face while implementing APIs is the difficulty of working with data structures and manually typing every query response, which can be hard to maintain. Currently, there are several alternatives to address these challenges and simplify this process. Such as tRPC, which natively integrates TypeScript and provides you with schema definitions to simplify the development of your application, but maintenance is difficult, its support with other programming languages is limited, and its use is not suitable for all types of applications.

Another option is GraphQL, a popular choice for delivering APIs, which reduces the load on your servers; it streamlines data management and performance. However, it lacks TypeScript support and requires excessive boilerplate code for initial setups, leading to reduced productivity and potential runtime errors, making it less optimal for type-safe applications.

In this blog post, we'll share our experience solving these challenges by taking full advantage of the potential and benefits of GraphQL combined with Remix and GenQL, improving its shortcomings, offering a better solution and a seamless and enjoyable development experience (DX).

How did we solve it?

To solve these pain points and take advantage of the potential of our GraphQL API, we integrated the GenQL library into our Remix projects. GenQL helps us obtain all the definitions and data types from our API queries and mutations within our code base, enabling type-safety access to properties, autocomplete, validations, and error highlighting, reducing the constant switching between the code editor and query explorer tools (like Apollo Studio), which improves our developer ergonomics, increasing productivity and development quality.

We used Remix as our server-side framework due to its performance optimization, security strategies, and built-in data management. Using a GenQL client inside the Remix loader and actions functions, we can get the definition of queries from our API and extract only the properties we need with their correct data type.

In the following case, the type of <Movie> is automatically inferred, allowing you to easily access all its properties so you can write your query.


Here you can take advantage of the generated types to build your components, knowing the shape of the data GraphQL will give, so it helps reduce bugs since we know what a title is and if it should have value.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import type { Movie } from "~/@types/gen"; type Props = Pick<Movie, "title" | "synopsis" | "year" | "director" | "id">; export function MovieCard({ title, synopsis, year, director }: Props) { return ( <Card className="w-full md:max-w-[350px] h-full flex flex-col"> <CardHeader> <CardTitle>{title}</CardTitle> <CardDescription> by {director} - {year} </CardDescription> </CardHeader> <CardContent className="mb-auto"> <p>{synopsis}</p> </CardContent> </Card> ); }

Using Composabase, you only need to get your endpoint URL from the dashboard and run the following script.

And all the magic will happen! You can confidently create all your applications while having a better DX

1 2 3 $ genql --endpoint --output ./@types/gen Success! Generated client code inside './@types/gen'

What are the benefits?

By doing so, we can access available properties across all nested components in our application. So it reduces prompt errors while coding, tons of copy/paste operations, flattens the learning curve of your code base, and increases efficiency in writing more efficient and optimized GraphQL queries providing you with the certainty of knowing what you're handling powered by autocomplete, data normalization, validations, etc. Furthermore, with the power of a single library (GenQL), we can reduce the manual work required to write complex queries in our application and avoid issues such as too much or too little data fetching.

Developing with type-safety using Remix and GraphQL can significantly improve the developer experience (DX), as it takes advantage of TypeScript and allows easy codebase maintenance. While also allows for pulling only the necessary information, minimizing unnecessary data transfer, and improving the developer's performance.

How can Composabase help you?

While GraphQL enables you to build complex applications more easily and securely, it also leaves on your side the responsibility of creating and configuring a server for your API, designing a consistent schema, and managing the cache for better performance. Composabase will help you to easily integrate all your existing data sources and provide your app with a production-ready GraphQL API in record time. In addition, with its composable architecture, you can power up your app with out-of-the-box features like cache and security, capabilities that would otherwise be challenging to implement manually.

Learn everything about GraphQL and the state of modern API integration in 2024 in our most comprehensive guide on the topic here.  

Share with others

Try Composabase Now!

Find how to improve your DX by leveraging the true potential of GraphQL.