{"id":48881080,"url":"https://github.com/papitaconpure/booru-client-js","last_synced_at":"2026-04-24T08:01:12.005Z","repository":{"id":351211968,"uuid":"1209479682","full_name":"PapitaConPure/booru-client-js","owner":"PapitaConPure","description":"An extensible, zero-dependency imageboard client with multi-layer tag caching for Javascript.","archived":false,"fork":false,"pushed_at":"2026-04-16T02:20:15.000Z","size":168,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T03:04:25.240Z","etag":null,"topics":["bun","danbooru","gelbooru","javascript","nodejs","npm","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@papitaconpure/booru-client","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PapitaConPure.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-13T13:21:30.000Z","updated_at":"2026-04-16T02:20:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/PapitaConPure/booru-client-js","commit_stats":null,"previous_names":["papitaconpure/booru-client","papitaconpure/booru-client-js"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/PapitaConPure/booru-client-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PapitaConPure%2Fbooru-client-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PapitaConPure%2Fbooru-client-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PapitaConPure%2Fbooru-client-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PapitaConPure%2Fbooru-client-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PapitaConPure","download_url":"https://codeload.github.com/PapitaConPure/booru-client-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PapitaConPure%2Fbooru-client-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32214420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T03:15:14.334Z","status":"ssl_error","status_checked_at":"2026-04-24T03:15:11.608Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","danbooru","gelbooru","javascript","nodejs","npm","typescript"],"created_at":"2026-04-16T03:01:18.326Z","updated_at":"2026-04-24T08:01:11.998Z","avatar_url":"https://github.com/PapitaConPure.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![GitHub package.json dependency version](https://img.shields.io/node/v/package-json)\n![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/PapitaConPure/booru-client)\n![GitHub repo size](https://img.shields.io/github/repo-size/PapitaConPure/booru-client)\n![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/%40papitaconpure%2Fbooru-client)\n![Twitter Follow](https://img.shields.io/twitter/follow/PapitaPure?label=%40PapitaPure\u0026style=social\u0026link=https://twitter.com/PapitaPure)\n\n\u003ch1 align=\"center\"\u003e\n\tBooru Client JS\n\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\nAn extensible, zero-dependency, optimized imageboard client for Javascript.\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Installation\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003eManager\u003c/td\u003e\n\u003ctd\u003eCommand\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\u003cb\u003enpm\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\n\n```cmd\nnpm install --save @papitaconpure/booru-client\n```\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e\u003cb\u003eBun\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\n\n```cmd\nbun add @papitaconpure/booru-client\n```\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\n\u003ctd\u003e\u003cb\u003eDeno\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\n\n```cmd\ndeno add npm:@papitaconpure/booru-client\n```\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Basic Usage\n**Gelbooru:**\n```ts\nimport { BooruClient, Gelbooru } from '@papitaconpure/booru-client';\n\n//Instance a Booru adapter\nconst gelbooru = new Gelbooru();\n\n//Create a Booru client with the adapter and our credentials\nconst client = new BooruClient(gelbooru, {\n\tapiKey: 'your Gelbooru API key',\n\tuserId: 'your Gelbooru user ID',\n});\n\n//Return 5 random posts containing the tag \"megumin\" and a \"General\" content rating\nconst posts = await client.search('megumin rating:general sort:random', { limit: 5 });\n\n//Log the id, tags, url, and extra Gelbooru metadata of every obtained post\nfor (const post of posts) {\n\tconsole.log({\n\t\tid: post.id,\n\t\ttags: post.tags,\n\t\turl: post.url,\n\t\textra: post.extra,\n\t});\n}\n```\n\n**Danbooru:**\n```ts\nimport { BooruClient, Danbooru } from '@papitaconpure/booru-client';\n\n//Instance a Booru adapter\nconst danbooru = new Danbooru();\n\n//Create a Booru client with the adapter and our credentials\nconst client = new BooruClient(danbooru, {\n\tapiKey: 'your Danbooru API key',\n\tlogin: 'your Danbooru user ID',\n});\n\n//Return the last 3 posts containing the tag \"touhou\" and a \"Sensitive\" content rating\nconst posts = await client.search('touhou rating:sensitive', { limit: 3 });\n\n//Log the id, tags and url of every obtained post\nfor (const post of posts) {\n\tconsole.log({\n\t\tid: post.id,\n\t\ttags: post.tags,\n\t\turl: post.url,\n\t});\n}\n```\n\nFor more advanced usage, please [check out all of the examples](https://github.com/PapitaConPure/booru-client-js/blob/de0400d23ced275016a8b6da36c207b18fc6767d/examples).\n\n## Smart Tag Resolution (Batching + Deduplication)\n\nThis client automatically tries to optimize tag resolution under the hood using:\n* Smart request batching\n* In-flight request deduplication\n* Multi-layer caching\n\nThis means that multiple requests for overlapping tags may automatically merge into a single tag store lookup or API call, whichever comes first.\n\n```ts\n//Fetches the last 4 posts containing the tag 'megumin' from a booru.\nconst posts = await client.search('megumin', { limit: 4 });\n\n//Fetches tags \"in parallel\", batching tag resolution requests across posts\n//and avoiding duplicated requests within a reasonable time window.\nawait Promise.all(\n\tposts.map(async (post) =\u003e {\n\t\tconst tags = await client.fetchPostTags(post);\n\n\t\t//Log each Post's ID and tags after fetching.\n\t\tconsole.log(post.id);\n\t\tconsole.dir(post.tags);\n\t}),\n);\n```\n\n```ts\n//These 24 tag requests are automatically reduced to only 1~8 API calls\n//With default BooruClient settings, usually only 1 API call is required!\nawait Promise.all([\n\tclient.fetchTagsByNames({ names: ['hakurei_reimu'] }),\n\tclient.fetchTagsByNames({ names: ['hakurei_reimu', 'kirisame_marisa'] }),\n\tclient.fetchTagsByNames({ names: ['hakurei_reimu', 'kirisame_marisa', 'alice_margatroid'] }),\n\tclient.fetchTagsByNames({ names: ['kirisame_marisa', 'alice_margatroid', 'ibuki_suika'] }),\n\tclient.fetchTagsByNames({ names: ['alice_margatroid', 'ibuki_suika', 'houraisan_kaguya'] }),\n\tclient.fetchTagsByNames({ names: ['ibuki_suika', 'houraisan_kaguya', 'shameimaru_aya'] }),\n\tclient.fetchTagsByNames({ names: ['houraisan_kaguya', 'shameimaru_aya', 'kochiya_sanae'] }),\n\tclient.fetchTagsByNames({ names: ['shameimaru_aya', 'kochiya_sanae', 'hinanawi_tenshi'] }),\n\tclient.fetchTagsByNames({ names: ['kochiya_sanae', 'hinanawi_tenshi'] }),\n\tclient.fetchTagsByNames({ names: ['hinanawi_tenshi'] }),\n]);\n```\n\nKeep in mind, Post requests are currently executed independently without caching, batching, or request deduplication. These optimizations *are* planned for future releases however.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpapitaconpure%2Fbooru-client-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpapitaconpure%2Fbooru-client-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpapitaconpure%2Fbooru-client-js/lists"}