A lightweight, type-safe bridge between Effect HTTP API clients and TanStack Query (queryOptions, mutationOptions, and getQueryKey).
- Seamless Integration: Effortlessly map Effect
HttpApiClientendpoints to TanStack Query config objects. - End-to-End Type Safety: Automatically infers inputs (
params,query,headers,payload), success types, and error types directly from your Effect schemas. - Zero Boilerplate: Generates
queryKeyand execution functions under the hood using ES6 Proxies. - Developer Friendly: Smart optional parameters when no input arguments are required.
Install using your preferred package manager:
# Using npm
npm install @tiesen/effect-tanstack-query
# Using yarn
yarn add @tiesen/effect-tanstack-query
# Using bun
bun add @tiesen/effect-tanstack-query
# Using pnpm
pnpm add @tiesen/effect-tanstack-queryimport { Schema } from 'effect'
import { HttpApi, HttpApiEndpoint, HttpApiGroup } from 'effect/unstable/httpapi'
class ApiGroup extends HttpApiGroup.make('ApiGroup')
.add(
HttpApiEndpoint.get('hello', '/hello/:name', {
success: Schema.String,
params: Schema.Struct({
name: Schema.String,
}),
query: Schema.Struct({
greeting: Schema.String.pipe(Schema.optionalKey),
}),
})
)
.add(
HttpApiEndpoint.post('goodbye', '/goodbye', {
success: Schema.String,
payload: Schema.Struct({
name: Schema.String,
}),
})
) {}
export class Api extends HttpApi.make('Api').add(ApiGroup) {}import { Context, Function, Layer } from 'effect'
import {
FetchHttpClient,
HttpClient,
HttpClientRequest,
} from 'effect/unstable/http'
import { HttpApiClient } from 'effect/unstable/httpapi'
class ApiClient extends Context.Service<
ApiClient,
HttpApiClient.ForApi<typeof Api>
>()('ApiClient') {
public static live = Layer.effect(
this,
HttpApiClient.make(Api, {
transformClient: (client) =>
client.pipe(
HttpClient.mapRequest(
Function.flow(HttpClientRequest.prependUrl('http://localhost:3000'))
)
),
})
).pipe(Layer.provide(FetchHttpClient.layer))
}import { ManagedRuntime } from 'effect'
import { createTanstackQueryOptionsProxy } from '@tiesen/effect-tanstack-query'
const runtime = ManagedRuntime.make(ApiClient.live)
const api = createTanstackQueryOptionsProxy(ApiClient, runtime)import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query'
// Query Example
const query = useQuery(
api.ApiGroup.hello.queryOptions({
params: { name: 'John' },
query: { greeting: 'Hi' },
})
)
// Mutation Example
const mutation = useMutation(api.ApiGroup.goodbye.mutationOptions())
mutation.mutate({ name: 'John' })
// Invalidate Query Example
const queryClient = useQueryClient()
void queryClient.invalidateQueries({
queryKey: api.ApiGroup.hello.getQueryKey(),
})This project is licensed under the MIT License. See the LICENSE file for details.