{"_id":"@api-hooks/dh","_rev":"3-439f6fadc2025c17c9a2fea99d3379b7","name":"@api-hooks/dh","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@api-hooks/dh","version":"1.0.0","keywords":["react","hooks","docker","dockerhub","api","react-query","tanstack"],"author":{"url":"https://github.com/ElJijuna","name":"pilmee","email":"pilmee@gmail.com"},"license":"MIT","_id":"@api-hooks/dh@1.0.0","maintainers":[{"name":"pilmee","email":"pilmee@gmail.com"}],"homepage":"https://github.com/ElJijuna/api-hooks#readme","bugs":{"url":"https://github.com/ElJijuna/api-hooks/issues"},"dist":{"shasum":"4d70369c21321004e19c8adaf1e741b6be0763cd","tarball":"https://registry.npmjs.org/@api-hooks/dh/-/dh-1.0.0.tgz","fileCount":53,"integrity":"sha512-1PlwQGkMkW9olN4m2AtvicL6TFq0rJSX9qIxYbC/Pd8pG1gMwwpsreqPnLL5Q2am6KTHv1nhsUUHhkNEGp0Ebw==","signatures":[{"sig":"MEUCIHS/of2m7qlIg+sPnOdmsSxwYTg75eVmXcYzyIyZBYq0AiEA+JSdoZk0D0cU8CBh3Z/xz+VgjHglLqFP/PlqVFdIQ14=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61610},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"4f4aa1ddc1704d254d66a0cef02ff5dcb26ed790","scripts":{"dev":"vite build --watch","docs":"typedoc","test":"jest --passWithNoTests","build":"vite build && tsc --emitDeclarationOnly --declarationMap","typecheck":"tsc --noEmit","test:coverage":"jest --coverage --passWithNoTests"},"_npmUser":{"name":"pilmee","email":"pilmee@gmail.com"},"repository":{"url":"git+https://github.com/ElJijuna/api-hooks.git","type":"git","directory":"packages/dh"},"_npmVersion":"11.14.1","description":"React hooks for the Docker Hub API, built on @tanstack/react-query","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"dockerhub-api-client":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.4.2","vite":"^8.0.16","react":"^19.2.7","typedoc":"^0.28.19","react-dom":"^19.2.7","@tanstack/react-query":"^5.101.0","@testing-library/react":"^16.3.2","jest-environment-jsdom":"^30.4.1","vite-magic-tree-shaking":"^1.0.0"},"peerDependencies":{"react":">=19.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dh_1.0.0_1780852459126_0.988193992390423","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@api-hooks/dh","version":"1.0.1","keywords":["react","hooks","docker","dockerhub","api","react-query","tanstack"],"author":{"url":"https://github.com/ElJijuna","name":"pilmee","email":"pilmee@gmail.com"},"license":"MIT","_id":"@api-hooks/dh@1.0.1","maintainers":[{"name":"pilmee","email":"pilmee@gmail.com"}],"homepage":"https://github.com/ElJijuna/api-hooks#readme","bugs":{"url":"https://github.com/ElJijuna/api-hooks/issues"},"dist":{"shasum":"e6f8609be684e76c5703cbaf1d29abdbc7de68d1","tarball":"https://registry.npmjs.org/@api-hooks/dh/-/dh-1.0.1.tgz","fileCount":53,"integrity":"sha512-8es0y/eKmHqpwm26Lrm1VaWDbVgiOsior69qSiWGUeMxonf0osptqgX1mTPP5030FvyZb8AyW12hHg1BQB4vAA==","signatures":[{"sig":"MEUCIFyfDMPpLvlgv5OKyAFa7f1+Q7WiF8CgByoeMMAKLv2YAiEAlO82eReDC2N+t+oSUWMWb7LMHAv9SuBBswWINNVReic=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61738},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"e958826372dcee51f03f2c3438a272d2ae51247d","scripts":{"dev":"vite build --watch","docs":"typedoc","test":"jest --passWithNoTests","build":"vite build && tsc --emitDeclarationOnly --declarationMap","typecheck":"tsc --noEmit","test:coverage":"jest --coverage --passWithNoTests"},"_npmUser":{"name":"pilmee","email":"pilmee@gmail.com"},"repository":{"url":"git+https://github.com/ElJijuna/api-hooks.git","type":"git","directory":"packages/dh"},"_npmVersion":"11.14.1","description":"React hooks for the Docker Hub API, built on @tanstack/react-query","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"dockerhub-api-client":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.4.2","vite":"^8.0.16","react":"^19.2.7","typedoc":"^0.28.19","react-dom":"^19.2.7","@tanstack/react-query":"^5.101.0","@testing-library/react":"^16.3.2","jest-environment-jsdom":"^30.4.1","vite-magic-tree-shaking":"^1.0.0"},"peerDependencies":{"react":">=19.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dh_1.0.1_1780939068947_0.939687627535315","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@api-hooks/dh","version":"1.1.0","description":"React hooks for the Docker Hub API, built on @tanstack/react-query","keywords":["react","hooks","docker","dockerhub","api","react-query","tanstack"],"license":"MIT","homepage":"https://github.com/ElJijuna/api-hooks#readme","repository":{"type":"git","url":"git+https://github.com/ElJijuna/api-hooks.git","directory":"packages/dh"},"bugs":{"url":"https://github.com/ElJijuna/api-hooks/issues"},"publishConfig":{"access":"public"},"type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"vite build && tsc --emitDeclarationOnly --declarationMap","dev":"vite build --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage --passWithNoTests","typecheck":"tsc --noEmit","docs":"typedoc"},"peerDependencies":{"@tanstack/react-query":"^5.0.0","react":">=19.0.0"},"devDependencies":{"@tanstack/react-query":"^5.101.0","@testing-library/react":"^16.3.2","jest":"^30.4.2","jest-environment-jsdom":"^30.4.1","react":"^19.2.7","react-dom":"^19.2.7","typedoc":"^0.28.19","vite":"^8.0.16","vite-magic-tree-shaking":"^1.0.0"},"dependencies":{"dockerhub-api-client":"^1.0.0"},"author":{"name":"pilmee","email":"pilmee@gmail.com","url":"https://github.com/ElJijuna"},"gitHead":"79a355f0566d21911cd94b4b993db01cef37dd01","_id":"@api-hooks/dh@1.1.0","_nodeVersion":"22.23.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-hZJRgkVxlbs/i2eheQhwDyODajJvlZSbOjjlH21VXYo+D8e0NvAH2cGcJAwakejO5qoejLonjZGSyi+aDuBOUQ==","shasum":"08104d796f0496b4a7d9dbab60d01e09f91a6016","tarball":"https://registry.npmjs.org/@api-hooks/dh/-/dh-1.1.0.tgz","fileCount":56,"unpackedSize":68721,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICMBqRc4lk0BKCUrMIaLWCcRpIhVk2odl0cb7OndEuaeAiAtAM/gg8Tp2RiHFyD+h2kyNOmlODBZCJlma3JPcIDvGQ=="}]},"_npmUser":{"name":"pilmee","email":"pilmee@gmail.com"},"directories":{},"maintainers":[{"name":"pilmee","email":"pilmee@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dh_1.1.0_1782996268085_0.5291566019059482"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-07T17:14:18.995Z","modified":"2026-07-02T12:44:28.352Z","1.0.0":"2026-06-07T17:14:19.276Z","1.0.1":"2026-06-08T17:17:49.086Z","1.1.0":"2026-07-02T12:44:28.215Z"},"bugs":{"url":"https://github.com/ElJijuna/api-hooks/issues"},"author":{"name":"pilmee","email":"pilmee@gmail.com","url":"https://github.com/ElJijuna"},"license":"MIT","homepage":"https://github.com/ElJijuna/api-hooks#readme","keywords":["react","hooks","docker","dockerhub","api","react-query","tanstack"],"repository":{"type":"git","url":"git+https://github.com/ElJijuna/api-hooks.git","directory":"packages/dh"},"description":"React hooks for the Docker Hub API, built on @tanstack/react-query","maintainers":[{"name":"pilmee","email":"pilmee@gmail.com"}],"readme":"# @api-hooks/dh\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/ElJijuna/api-hooks/main/public/assets/api-hooks.png\" alt=\"api-hooks logo\" width=\"240\" />\n</p>\n\nReact hooks for the [Docker Hub API](https://docs.docker.com/reference/api/hub/latest/), built on [`dockerhub-api-client`](https://www.npmjs.com/package/dockerhub-api-client) and [`@tanstack/react-query`](https://tanstack.com/query).\n\n[![npm](https://img.shields.io/npm/v/@api-hooks/dh)](https://www.npmjs.com/package/@api-hooks/dh)\n[![npm downloads](https://img.shields.io/npm/dm/@api-hooks/dh)](https://www.npmjs.com/package/@api-hooks/dh)\n[![CI](https://github.com/ElJijuna/api-hooks/actions/workflows/ci.yml/badge.svg)](https://github.com/ElJijuna/api-hooks/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n\n## Requirements\n\n| Peer dependency | Version |\n| --------------- | ------- |\n| `react` | `>=19.0.0` |\n| `@tanstack/react-query` | `^5.0.0` |\n\n## Installation\n\n```bash\nnpm install @api-hooks/dh @tanstack/react-query\n```\n\n## Setup\n\nWrap your application with a `QueryClientProvider` once at the root:\n\n```tsx\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { DhClientProvider } from '@api-hooks/dh';\n\nconst queryClient = new QueryClient();\n\nexport default function App() {\n  return (\n    <QueryClientProvider client={queryClient}>\n      <DhClientProvider>\n        <YourApp />\n      </DhClientProvider>\n    </QueryClientProvider>\n  );\n}\n```\n\nFor authenticated requests, obtain a token via `useDockerHubLogin` and pass it through `DhClientProvider`:\n\n```tsx\n<DhClientProvider options={{ token: 'your-jwt-token' }}>\n  <YourApp />\n</DhClientProvider>\n```\n\n## Hooks\n\nQuery hooks return a [`UseQueryResult`](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) — you get the full TanStack Query API: `data`, `isLoading`, `isFetching`, `isError`, `error`, `refetch`, and more.\n\n`useDockerHubLogin` returns a [`UseMutationResult`](https://tanstack.com/query/latest/docs/framework/react/reference/useMutation) since it performs a POST request.\n\n### Repository hooks\n\n| Hook | Description | Returns |\n| ---- | ----------- | ------- |\n| [`useDockerHubRepository(namespace, name)`](#usedockerhubrepositoynamespace-name) | Repository metadata | `DockerHubRepository` |\n| [`useDockerHubRepositoryTags(namespace, name, options?)`](#usedockerhubrepositorytagnamespacename-options) | Image tags for a repository | `DockerHubPagedResponse<DockerHubTag>` |\n| `useDockerHubRepositoryTagsInfinite(namespace, name, options?)` | Infinite-scroll variant of `useDockerHubRepositoryTags` | `InfiniteData<DockerHubPagedResponse<DockerHubTag>>` |\n\n### User hooks\n\n| Hook | Description | Returns |\n| ---- | ----------- | ------- |\n| [`useDockerHubUser(username)`](#usedockerhubuserusername) | Public user profile | `DockerHubUser` |\n| [`useDockerHubUserRepositories(username, options?)`](#usedockerhubuser repositoriesusername-options) | Public repositories of a user | `DockerHubPagedResponse<DockerHubRepository>` |\n| `useDockerHubUserRepositoriesInfinite(username, options?)` | Infinite-scroll variant of `useDockerHubUserRepositories` | `InfiniteData<DockerHubPagedResponse<DockerHubRepository>>` |\n\n### Organization hooks\n\n| Hook | Description | Returns |\n| ---- | ----------- | ------- |\n| [`useDockerHubOrg(orgname)`](#usedockerhuborgorgname) | Organization profile | `DockerHubOrganization` |\n\n### Search hooks\n\n| Hook | Description | Returns |\n| ---- | ----------- | ------- |\n| [`useDockerHubSearch(query, options?)`](#usedockerhuabsearchquery-options) | Search repositories on Docker Hub | `DockerHubPagedResponse<DockerHubSearchResult>` |\n| `useDockerHubSearchInfinite(query, options?)` | Infinite-scroll variant of `useDockerHubSearch` | `InfiniteData<DockerHubPagedResponse<DockerHubSearchResult>>` |\n\n### Auth hooks\n\n| Hook | Description | Returns |\n| ---- | ----------- | ------- |\n| [`useDockerHubLogin()`](#usedockerhublogin) | Authenticate and obtain a JWT token (POST) | `string` |\n\n---\n\n## API Reference\n\n### `useDockerHubRepository(namespace, name)`\n\nFetches metadata for a Docker Hub image repository. For official images use `'library'` as namespace.\n\n```tsx\nimport { useDockerHubRepository } from '@api-hooks/dh';\n\nfunction RepoInfo() {\n  const { data, isLoading, isError } = useDockerHubRepository('library', 'nginx');\n\n  if (isLoading) return <p>Loading…</p>;\n  if (isError) return <p>Not found.</p>;\n\n  return (\n    <div>\n      <h1>{data.name}</h1>\n      <p>Pulls: {data.pull_count.toLocaleString()}</p>\n      <p>Stars: {data.star_count}</p>\n    </div>\n  );\n}\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `enabled` | `boolean` | `true` | Disabled when `namespace` or `name` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubRepositoryTags(namespace, name, options?)`\n\nLists image tags for a Docker Hub repository, with optional filtering by name prefix.\n\n```tsx\nconst { data } = useDockerHubRepositoryTags('library', 'nginx', { page_size: 10 });\n\ndata?.results.forEach(tag => console.log(tag.name, tag.digest));\n\n// Filter by name prefix\nconst { data: stable } = useDockerHubRepositoryTags('library', 'nginx', { name: 'stable' });\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `page` | `number` | — | Page number |\n| `page_size` | `number` | — | Results per page |\n| `name` | `string` | — | Filter tags by name prefix |\n| `ordering` | `string` | — | Sort order |\n| `enabled` | `boolean` | `true` | Disabled when `namespace` or `name` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubRepositoryTagsInfinite(namespace, name, options?)`\n\nInfinite-scroll variant of `useDockerHubRepositoryTags`. Call `fetchNextPage()` to load the next page.\n\n```tsx\nimport { useDockerHubRepositoryTagsInfinite } from '@api-hooks/dh';\n\nfunction TagList({ namespace, name }: { namespace: string; name: string }) {\n  const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =\n    useDockerHubRepositoryTagsInfinite(namespace, name, { page_size: 10 });\n\n  const allTags = data?.pages.flatMap(p => p.results) ?? [];\n\n  return (\n    <>\n      <ul>\n        {allTags.map(tag => (\n          <li key={tag.id}>{tag.name}</li>\n        ))}\n      </ul>\n      {hasNextPage && (\n        <button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>\n          Load more\n        </button>\n      )}\n    </>\n  );\n}\n```\n\n---\n\n### `useDockerHubUser(username)`\n\nFetches the public profile of a Docker Hub user.\n\n```tsx\nconst { data } = useDockerHubUser('johndoe');\n\nconsole.log(data?.full_name);    // 'John Doe'\nconsole.log(data?.gravatar_url); // 'https://...'\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `enabled` | `boolean` | `true` | Disabled when `username` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubUserRepositories(username, options?)`\n\nLists public repositories owned by a Docker Hub user.\n\n```tsx\nconst { data } = useDockerHubUserRepositories('johndoe', { page_size: 25 });\n\ndata?.results.forEach(r => console.log(r.name, r.pull_count));\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `page` | `number` | — | Page number |\n| `page_size` | `number` | — | Results per page |\n| `ordering` | `string` | — | Sort order |\n| `enabled` | `boolean` | `true` | Disabled when `username` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubUserRepositoriesInfinite(username, options?)`\n\nInfinite-scroll variant of `useDockerHubUserRepositories`.\n\n```tsx\nconst { data, hasNextPage, fetchNextPage } =\n  useDockerHubUserRepositoriesInfinite('johndoe', { page_size: 10 });\n\nconst allRepos = data?.pages.flatMap(p => p.results) ?? [];\n```\n\n---\n\n### `useDockerHubOrg(orgname)`\n\nFetches a Docker Hub organization's profile.\n\n```tsx\nconst { data } = useDockerHubOrg('docker');\n\nconsole.log(data?.full_name); // 'Docker'\nconsole.log(data?.type);      // 'Organization'\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `enabled` | `boolean` | `true` | Disabled when `orgname` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubSearch(query, options?)`\n\nSearches for repositories on Docker Hub.\n\n```tsx\nconst { data } = useDockerHubSearch('nginx', { page_size: 10 });\n\ndata?.results.forEach(r => {\n  console.log(r.repo_name, r.pull_count, r.is_official);\n});\n```\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `page` | `number` | — | Page number |\n| `page_size` | `number` | — | Results per page |\n| `type` | `'image'` | — | Filter by content type |\n| `enabled` | `boolean` | `true` | Disabled when `query` is empty |\n| `queryOptions` | `QueryOverrides<TData>` | `undefined` | Override TanStack Query options (`staleTime`, `retry`, `gcTime`, `select`, etc.) |\n\n---\n\n### `useDockerHubSearchInfinite(query, options?)`\n\nInfinite-scroll variant of `useDockerHubSearch`.\n\n```tsx\nimport { useDockerHubSearchInfinite } from '@api-hooks/dh';\n\nfunction InfiniteSearch() {\n  const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =\n    useDockerHubSearchInfinite('nginx', { page_size: 10 });\n\n  const allResults = data?.pages.flatMap(p => p.results) ?? [];\n\n  return (\n    <>\n      <ul>\n        {allResults.map(r => (\n          <li key={r.repo_name}>{r.repo_name}</li>\n        ))}\n      </ul>\n      {hasNextPage && (\n        <button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>\n          Load more\n        </button>\n      )}\n    </>\n  );\n}\n```\n\n---\n\n### `useDockerHubLogin()`\n\nAuthenticates against Docker Hub and returns a JWT token. Pass the token to `DhClientProvider` for subsequent authenticated requests.\n\nReturns a `UseMutationResult` — call `mutate({ username, password })` to trigger.\n\n```tsx\nimport { useState } from 'react';\nimport { useDockerHubLogin } from '@api-hooks/dh';\n\nfunction LoginForm() {\n  const { mutate, isPending, isError } = useDockerHubLogin();\n\n  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {\n    e.preventDefault();\n    const form = new FormData(e.currentTarget);\n    mutate(\n      { username: form.get('username') as string, password: form.get('password') as string },\n      { onSuccess: (token) => console.log('Token:', token) },\n    );\n  }\n\n  return (\n    <form onSubmit={handleSubmit}>\n      <input name=\"username\" />\n      <input name=\"password\" type=\"password\" />\n      <button type=\"submit\" disabled={isPending}>Login</button>\n      {isError && <p>Invalid credentials.</p>}\n    </form>\n  );\n}\n```\n\n---\n\n## License\n\nMIT © [ElJijuna](https://github.com/ElJijuna)\n","readmeFilename":"README.md"}