Poonda
Poonda2w ago

Best Monorepo Pattern for Sharing tRPC Logic Across Apps

Hey tRPC community! I'm working on a monorepo with a standalone tRPC server, a React Native app, and a Next.js app. Both frontend apps share a lot of common logic, particularly custom React hooks that wrap tRPC calls. Currently, my proposed solution is to create shared hooks that require a React context providing the tRPC client. This approach allows each app to instantiate its own tRPC client (both based on the same AppRouter) while maintaining shared logic. Specifically: - Each app creates its own tRPC client and react-query provider - Shared hooks live in a separate package - These hooks require a context that provides the tRPC client - This allows flexibility for different client configurations I'm looking for feedback: 1. Are there any potential issues with this approach? 2. Do you know of a more elegant pattern for managing shared tRPC logic in a multi-app monorepo? Any insights or alternative strategies would be greatly appreciated.
2 Replies
P.S.Nikhil
P.S.Nikhil2w ago
check t3 turbo
Poonda
PoondaOP2w ago
Thanks, what t3 turbo has is pretty much the state of our current app, in the example they are only sharing the tRPC router. each application build the logic around the procedures. In my case in need to share frontend logic that use the trpc calls. Let take a simple example (my use case is more complex, that why i want to share the logic)
const utils = api.useUtils();
const createPost = api.post.create.useMutation({
onSuccess: async () => {
form.reset();
await utils.post.invalidate();
},
onError: (err) => {
toast.error(
err.data?.code === "UNAUTHORIZED"
? "You must be logged in to post"
: "Failed to create post",
);
},
});
const utils = api.useUtils();
const createPost = api.post.create.useMutation({
onSuccess: async () => {
form.reset();
await utils.post.invalidate();
},
onError: (err) => {
toast.error(
err.data?.code === "UNAUTHORIZED"
? "You must be logged in to post"
: "Failed to create post",
);
},
});
Let say in wrap this logic in a hook an put it in a shared package for the two app to use. I need a way to inject the api trpc client for this hook. Option 1 which is too dumb and lots of maintenance work - drill down the trpc client Option 2 that i thought was better is pass it with a context. I hope I clarified the question