https://github.com/peterferguson/hono-rq
A zero-overhead React Query integration for Hono RPC clients with full type safety.
https://github.com/peterferguson/hono-rq
hono honojs react-query tanstack-react-query
Last synced: 10 months ago
JSON representation
A zero-overhead React Query integration for Hono RPC clients with full type safety.
- Host: GitHub
- URL: https://github.com/peterferguson/hono-rq
- Owner: peterferguson
- Created: 2025-09-08T07:38:19.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-09-09T12:11:59.000Z (10 months ago)
- Last Synced: 2025-09-11T07:32:43.154Z (10 months ago)
- Topics: hono, honojs, react-query, tanstack-react-query
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/hono-rq
- Size: 352 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# hono-rq
[](https://badge.fury.io/js/hono-rq)
[](https://choosealicense.com/licenses/mit/)
[](http://www.typescriptlang.org/)
A zero-overhead React Query integration for [Hono](https://hono.dev/) RPC clients with full type safety.
## Features
- ๐ **Full Type Safety** - Preserves all Hono RPC types end-to-end
- ๐ **Zero Runtime Overhead** - Minimal proxy-based implementation
- โก **React Query Integration** - Generate `queryOptions`, `infiniteQueryOptions`, and `mutationOptions`
- ๐ฏ **Smart Query Keys** - Automatic, stable query key generation based on endpoint and parameters
- ๐ **Developer Experience** - IntelliSense support with autocomplete for all endpoints
- ๐งช **Well Tested** - Comprehensive test coverage including browser and integration tests
- ๐ฆ **Tree Shakable** - Only bundle what you use
## Installation
```bash
npm install hono-rq @tanstack/react-query hono
```
```bash
pnpm add hono-rq @tanstack/react-query hono
```
```bash
yarn add hono-rq @tanstack/react-query hono
```
```bash
bun add hono-rq @tanstack/react-query hono
```
## Quick Start
### 1. Extend your Hono client
```typescript
import { extend } from 'hono-rq';
import { hc } from 'hono/client';
import type { AppType } from './server'; // Your Hono app type
const client = hc('http://localhost:3000');
const extendedClient = extend(client);
```
### 2. Use with React Query
```tsx
import { useQuery, useMutation } from '@tanstack/react-query';
function UsersList() {
// Generate query options for GET requests
const queryOptions = extendedClient.users.$get.queryOptions();
const { data, isLoading, error } = useQuery(queryOptions);
// Generate mutation options for POST requests
const mutationOptions = extendedClient.users.$post.mutationOptions();
const createUser = useMutation(mutationOptions);
if (isLoading) return
Loading...;
if (error) return Error: {error.message};
return (
{data?.users.map(user => (
{user.name}
))}
createUser.mutate({
json: { name: 'New User', email: 'user@example.com' }
})}
>
Add User
);
}
```
## API Reference
### `extend(client)`
Extends a Hono RPC client with React Query integration methods.
```typescript
import { extend } from 'hono-rq';
const extendedClient = extend(client);
```
**Parameters:**
- `client` - Any Hono RPC client created with `hc()`
**Returns:**
- Extended client with React Query methods added to each endpoint
### Query Options
Generate React Query options for GET endpoints:
```typescript
// Basic usage
const queryOptions = extendedClient.users.$get.queryOptions();
// With parameters
const queryOptions = extendedClient.users[':id'].$get.queryOptions({
param: { id: '123' }
});
// With query parameters
const queryOptions = extendedClient.users.$get.queryOptions({
query: { limit: '10', offset: '0' }
});
// With React Query options
const queryOptions = extendedClient.users.$get.queryOptions(
{ query: { limit: '10' } },
{
enabled: true,
staleTime: 5000,
retry: 3
}
);
```
### Infinite Query Options
Generate options for paginated data with React Query's infinite queries:
```typescript
const infiniteQueryOptions = extendedClient.posts.$get.infiniteQueryOptions(
(pageParam) => ({
query: {
page: pageParam?.toString() ?? '1',
limit: '10'
}
}),
{
initialPageParam: 1,
getNextPageParam: (lastPage, pages) =>
lastPage.hasMore ? pages.length + 1 : undefined,
}
);
const {
data,
fetchNextPage,
hasNextPage,
isLoading
} = useInfiniteQuery(infiniteQueryOptions);
```
### Mutation Options
Generate options for POST, PUT, PATCH, DELETE endpoints:
```typescript
// Basic mutation
const mutationOptions = extendedClient.users.$post.mutationOptions();
// With React Query options
const mutationOptions = extendedClient.users[':id'].$patch.mutationOptions(
undefined,
{
onSuccess: (data) => {
console.log('User updated:', data);
},
onError: (error) => {
console.error('Update failed:', error);
}
}
);
const mutation = useMutation(mutationOptions);
```
## TypeScript
hono-rq is built with TypeScript and provides full type safety:
```typescript
// All types are preserved from your Hono app
type UsersResponse = InferResponseType;
type CreateUserRequest = InferRequestType;
// Query options have correct types
const queryOptions = extendedClient.users.$get.queryOptions();
// queryOptions.queryFn return type matches your Hono endpoint
// Mutations are fully typed
const mutation = useMutation(
extendedClient.users.$post.mutationOptions()
);
// mutation.mutate() expects the correct request type
```
## Advanced Usage
### Error Handling
```typescript
const queryOptions = extendedClient.users.$get.queryOptions(undefined, {
retry: (failureCount, error) => {
// Custom retry logic
if (error.status === 404) return false;
return failureCount < 3;
},
onError: (error) => {
console.error('Query failed:', error);
}
});
```
## Examples
### Complete CRUD Example
```tsx
import { extend } from 'hono-rq';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
const extendedClient = extend(client);
function UserManager() {
const queryClient = useQueryClient();
// List users
const usersQuery = useQuery(
extendedClient.users.$get.queryOptions()
);
// Get single user
const userQuery = useQuery(
extendedClient.users[':id'].$get.queryOptions({
param: { id: selectedUserId }
}, {
enabled: !!selectedUserId
})
);
// Create user
const createUser = useMutation(
extendedClient.users.$post.mutationOptions(undefined, {
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: extendedClient.users.$get.queryOptions().queryKey
});
}
})
);
// Update user
const updateUser = useMutation(
extendedClient.users[':id'].$patch.mutationOptions(undefined, {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
}
})
);
// Delete user
const deleteUser = useMutation(
extendedClient.users[':id'].$delete.mutationOptions(undefined, {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
}
})
);
return (
{/* Your UI here */}
);
}
```
## Requirements
- **Node.js**: 18+
- **React**: 18+
- **@tanstack/react-query**: 5.0+
- **hono**: 4.0+
- **TypeScript**: 5.0+ (recommended)
## Contributing
We welcome contributions! Please see our [Contributing Guide](https://github.com/peterferguson/hono-rq/blob/main/CONTRIBUTING.md) for details.
## License
MIT ยฉ [Peter Ferguson](https://github.com/peterferguson)
## Related Projects
- [Hono](https://hono.dev/) - Ultrafast web framework for the Edges
- [TanStack Query](https://tanstack.com/query) - Powerful data synchronization for web applications
- [tRPC](https://trpc.io/) - End-to-end typesafe APIs made easy