@api-hooks/dh
v1.0.1
Published
React hooks for the Docker Hub API, built on @tanstack/react-query
Downloads
238
Maintainers
Readme
@api-hooks/dh
React hooks for the Docker Hub API, built on dockerhub-api-client and @tanstack/react-query.
Requirements
| Peer dependency | Version |
| --------------- | ------- |
| react | >=19.0.0 |
| @tanstack/react-query | ^5.0.0 |
Installation
npm install @api-hooks/dh @tanstack/react-querySetup
Wrap your application with a QueryClientProvider once at the root:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { DhClientProvider } from '@api-hooks/dh';
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<DhClientProvider>
<YourApp />
</DhClientProvider>
</QueryClientProvider>
);
}For authenticated requests, obtain a token via useDockerHubLogin and pass it through DhClientProvider:
<DhClientProvider options={{ token: 'your-jwt-token' }}>
<YourApp />
</DhClientProvider>Hooks
Query hooks return a UseQueryResult — you get the full TanStack Query API: data, isLoading, isFetching, isError, error, refetch, and more.
useDockerHubLogin returns a UseMutationResult since it performs a POST request.
Repository hooks
| Hook | Description | Returns |
| ---- | ----------- | ------- |
| useDockerHubRepository(namespace, name) | Repository metadata | DockerHubRepository |
| useDockerHubRepositoryTags(namespace, name, options?) | Image tags for a repository | DockerHubPagedResponse<DockerHubTag> |
| useDockerHubRepositoryTagsInfinite(namespace, name, options?) | Infinite-scroll variant of useDockerHubRepositoryTags | InfiniteData<DockerHubPagedResponse<DockerHubTag>> |
User hooks
| Hook | Description | Returns |
| ---- | ----------- | ------- |
| useDockerHubUser(username) | Public user profile | DockerHubUser |
| [useDockerHubUserRepositories(username, options?)](#usedockerhubuser repositoriesusername-options) | Public repositories of a user | DockerHubPagedResponse<DockerHubRepository> |
| useDockerHubUserRepositoriesInfinite(username, options?) | Infinite-scroll variant of useDockerHubUserRepositories | InfiniteData<DockerHubPagedResponse<DockerHubRepository>> |
Organization hooks
| Hook | Description | Returns |
| ---- | ----------- | ------- |
| useDockerHubOrg(orgname) | Organization profile | DockerHubOrganization |
Search hooks
| Hook | Description | Returns |
| ---- | ----------- | ------- |
| useDockerHubSearch(query, options?) | Search repositories on Docker Hub | DockerHubPagedResponse<DockerHubSearchResult> |
| useDockerHubSearchInfinite(query, options?) | Infinite-scroll variant of useDockerHubSearch | InfiniteData<DockerHubPagedResponse<DockerHubSearchResult>> |
Auth hooks
| Hook | Description | Returns |
| ---- | ----------- | ------- |
| useDockerHubLogin() | Authenticate and obtain a JWT token (POST) | string |
API Reference
useDockerHubRepository(namespace, name)
Fetches metadata for a Docker Hub image repository. For official images use 'library' as namespace.
import { useDockerHubRepository } from '@api-hooks/dh';
function RepoInfo() {
const { data, isLoading, isError } = useDockerHubRepository('library', 'nginx');
if (isLoading) return <p>Loading…</p>;
if (isError) return <p>Not found.</p>;
return (
<div>
<h1>{data.name}</h1>
<p>Pulls: {data.pull_count.toLocaleString()}</p>
<p>Stars: {data.star_count}</p>
</div>
);
}| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| enabled | boolean | true | Disabled when namespace or name is empty |
useDockerHubRepositoryTags(namespace, name, options?)
Lists image tags for a Docker Hub repository, with optional filtering by name prefix.
const { data } = useDockerHubRepositoryTags('library', 'nginx', { page_size: 10 });
data?.results.forEach(tag => console.log(tag.name, tag.digest));
// Filter by name prefix
const { data: stable } = useDockerHubRepositoryTags('library', 'nginx', { name: 'stable' });| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| page | number | — | Page number |
| page_size | number | — | Results per page |
| name | string | — | Filter tags by name prefix |
| ordering | string | — | Sort order |
| enabled | boolean | true | Disabled when namespace or name is empty |
useDockerHubRepositoryTagsInfinite(namespace, name, options?)
Infinite-scroll variant of useDockerHubRepositoryTags. Call fetchNextPage() to load the next page.
import { useDockerHubRepositoryTagsInfinite } from '@api-hooks/dh';
function TagList({ namespace, name }: { namespace: string; name: string }) {
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =
useDockerHubRepositoryTagsInfinite(namespace, name, { page_size: 10 });
const allTags = data?.pages.flatMap(p => p.results) ?? [];
return (
<>
<ul>
{allTags.map(tag => (
<li key={tag.id}>{tag.name}</li>
))}
</ul>
{hasNextPage && (
<button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
Load more
</button>
)}
</>
);
}useDockerHubUser(username)
Fetches the public profile of a Docker Hub user.
const { data } = useDockerHubUser('johndoe');
console.log(data?.full_name); // 'John Doe'
console.log(data?.gravatar_url); // 'https://...'| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| enabled | boolean | true | Disabled when username is empty |
useDockerHubUserRepositories(username, options?)
Lists public repositories owned by a Docker Hub user.
const { data } = useDockerHubUserRepositories('johndoe', { page_size: 25 });
data?.results.forEach(r => console.log(r.name, r.pull_count));| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| page | number | — | Page number |
| page_size | number | — | Results per page |
| ordering | string | — | Sort order |
| enabled | boolean | true | Disabled when username is empty |
useDockerHubUserRepositoriesInfinite(username, options?)
Infinite-scroll variant of useDockerHubUserRepositories.
const { data, hasNextPage, fetchNextPage } =
useDockerHubUserRepositoriesInfinite('johndoe', { page_size: 10 });
const allRepos = data?.pages.flatMap(p => p.results) ?? [];useDockerHubOrg(orgname)
Fetches a Docker Hub organization's profile.
const { data } = useDockerHubOrg('docker');
console.log(data?.full_name); // 'Docker'
console.log(data?.type); // 'Organization'| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| enabled | boolean | true | Disabled when orgname is empty |
useDockerHubSearch(query, options?)
Searches for repositories on Docker Hub.
const { data } = useDockerHubSearch('nginx', { page_size: 10 });
data?.results.forEach(r => {
console.log(r.repo_name, r.pull_count, r.is_official);
});| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| page | number | — | Page number |
| page_size | number | — | Results per page |
| type | 'image' | — | Filter by content type |
| enabled | boolean | true | Disabled when query is empty |
useDockerHubSearchInfinite(query, options?)
Infinite-scroll variant of useDockerHubSearch.
import { useDockerHubSearchInfinite } from '@api-hooks/dh';
function InfiniteSearch() {
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =
useDockerHubSearchInfinite('nginx', { page_size: 10 });
const allResults = data?.pages.flatMap(p => p.results) ?? [];
return (
<>
<ul>
{allResults.map(r => (
<li key={r.repo_name}>{r.repo_name}</li>
))}
</ul>
{hasNextPage && (
<button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
Load more
</button>
)}
</>
);
}useDockerHubLogin()
Authenticates against Docker Hub and returns a JWT token. Pass the token to DhClientProvider for subsequent authenticated requests.
Returns a UseMutationResult — call mutate({ username, password }) to trigger.
import { useState } from 'react';
import { useDockerHubLogin } from '@api-hooks/dh';
function LoginForm() {
const { mutate, isPending, isError } = useDockerHubLogin();
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const form = new FormData(e.currentTarget);
mutate(
{ username: form.get('username') as string, password: form.get('password') as string },
{ onSuccess: (token) => console.log('Token:', token) },
);
}
return (
<form onSubmit={handleSubmit}>
<input name="username" />
<input name="password" type="password" />
<button type="submit" disabled={isPending}>Login</button>
{isError && <p>Invalid credentials.</p>}
</form>
);
}License
MIT © ElJijuna
