{"id":26316631,"url":"https://github.com/h2owater425/node-hitomi","last_synced_at":"2026-04-02T10:35:53.044Z","repository":{"id":43103737,"uuid":"370198451","full_name":"H2Owater425/node-hitomi","owner":"H2Owater425","description":"Hitomi.la api for Node.js","archived":false,"fork":false,"pushed_at":"2024-12-23T08:34:35.000Z","size":396,"stargazers_count":18,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T20:19:25.786Z","etag":null,"topics":["api","hitomi","library","typescript","typescript-library"],"latest_commit_sha":null,"homepage":"https://npm.im/node-hitomi","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/H2Owater425.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}},"created_at":"2021-05-24T01:50:50.000Z","updated_at":"2025-02-18T07:01:58.000Z","dependencies_parsed_at":"2024-01-08T10:46:16.312Z","dependency_job_id":"8467a23d-03e1-44a3-ad8d-8d3492742ab5","html_url":"https://github.com/H2Owater425/node-hitomi","commit_stats":{"total_commits":231,"total_committers":3,"mean_commits":77.0,"dds":"0.017316017316017285","last_synced_commit":"711d38a8f3df64c4523ea6dc84a7cd9ba6e3b3cf"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/H2Owater425%2Fnode-hitomi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/H2Owater425%2Fnode-hitomi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/H2Owater425%2Fnode-hitomi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/H2Owater425%2Fnode-hitomi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/H2Owater425","download_url":"https://codeload.github.com/H2Owater425/node-hitomi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243732277,"owners_count":20338839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","hitomi","library","typescript","typescript-library"],"created_at":"2025-03-15T13:16:22.056Z","updated_at":"2026-04-02T10:35:53.037Z","avatar_url":"https://github.com/H2Owater425.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align='center'\u003e\n\n[![banner](.github/assets/banner.png)](https://github.com/H2Owater425/node-hitomi)\n\n### Hitomi.la API for Node.js\n\n\u003csup\u003eWould you call me a gentleman?\u003c/sup\u003e\n\n[![npm version](https://img.shields.io/npm/v/node-hitomi?style=flat-square)](https://npmjs.org/package/node-hitomi)\n[![npm type definition](https://img.shields.io/npm/types/node-hitomi?style=flat-square)](https://npmjs.org/package/node-hitomi)\n[![license](https://img.shields.io/github/license/H2Owater425/node-hitomi?style=flat-square)](https://github.com/H2Owater425/node-hitomi/blob/main/LICENSE)\n\n\u003c/div\u003e\n\n## Installation\n\n\u003e [!IMPORTANT]\n\u003e \n\u003e Due to frequent changes on Hitomi.la, it is highly recommended to use the latest version.\n\n**Node.js 10.20 or newer is required.**\n\n```sh\nnpm install node-hitomi\nyarn add node-hitomi\npnpm add node-hitomi\nbun add node-hitomi\n```\n\n## Features\n\n- **Gallery Search:** Filter by tags and title, choose sort order, and paginate results.\n- **Gallery Retrieval:** Load full gallery metadata, including title, type, language, artists, and relations.\n- **Tag Management:** Create, parse, search, and list tags. Also list available languages for a tag.\n- **Image Downloads:** Resolve URLs and fetch images in AVIF/WebP/JXL (when available), with optional thumbnail sizes.\n- **Video Downloads:** Fetch gallery videos and poster images.\n\n## Usage\n\nThe package exports a default client instance, but you can also create your own client for custom configuration.\n\n```typescript\nimport { Hitomi } from 'node-hitomi';\nimport { Agent } from 'https';\n\nconst agent = new Agent({\n\tkeepAlive: true,\n\t// Bypass server name indication field blocking\n\tservername: '',\n\trejectUnauthorized: false\n});\n\nconst hitomi = new Hitomi({\n\tagent: agent,\n\tindexMaximumAge: 300000,\n\timageContextMaximumAge: 1800000\n});\n```\n\nIf you use CommonJS module:\n\n```typescript\nconst { hitomi, SortType /* and more... */ } = require('node-hitomi');\n```\n\n---\n\n### Galleries\n\n`GalleryManager` lets you retrieve individual galleries and list matching gallery references.\n\n#### `GalleryManager.retrieve(id)`\n\nRetrieves a full gallery by id and returns a `Gallery` instance.\n\n```typescript\nimport hitomi from 'node-hitomi';\n\n// Retrieve a gallery by id\nconst gallery = await hitomi.galleries.retrieve(123456);\n\nconsole.log(`Title: ${gallery.title.display}`);\nconsole.log(`Type: ${gallery.type}`);\nconsole.log(`Language: ${gallery.language?.name}`);\n```\n\n#### `GalleryManager.list(options?)`\n\nLists galleries that match the given criteria. You can pass tags, a title query, sort options, and paging options. The method returns `GalleryReference[]`.\n\n```typescript\nimport hitomi, { SortType } from 'node-hitomi';\n\n// Parse a search expression into structured tag objects\nconst tags = hitomi.tags.parse('male:sole_male -female:netorare series:blue_archive');\n\n// List matching gallery references\nconst references = await hitomi.galleries.list({\n\ttags: tags,\n\ttitle: 'serina',\n\torderBy: SortType.PopularityMonth\n});\n\n// Resolve the first reference to a full gallery\nif(references.length \u003e 0) {\n\tconst firstGallery = await references[0].retrieve();\n\tconsole.log(firstGallery.title.display);\n}\n```\n\n\u003e [!WARNING]\n\u003e \n\u003e Not every `options.page` usage is valid. It must meet the restrictions below.\n\u003e \n\u003e - Only one non-language tag is allowed (optionally combined with a language tag).\n\u003e - Negative tags and title are not supported.\n\u003e \n\u003e ```typescript\n\u003e const simpleTags = hitomi.tags.parse('type:manga language:english');\n\u003e \n\u003e // List matching gallery references with pagination\n\u003e const pagedReferences = await hitomi.galleries.list({\n\u003e \ttags: simpleTags,\n\u003e \torderBy: SortType.DatePublished,\n\u003e \tpage: {\n\u003e \t\tindex: 0,\n\u003e \t\tsize: 25\n\u003e \t}\n\u003e });\n\u003e \n\u003e console.log(pagedReferences, `(${pagedReferences['length']} galleries)`);\n\u003e ```\n\n---\n\n### Tags\n\n`TagManager` helps you create, parse, search, and list tags.\n\n#### `TagManager.create(type, name, isNegative?)`\n\nCreates a `Tag` instance with a type, name, and optional negation flag.\n\n```typescript\nimport hitomi from 'node-hitomi';\n\n// Create a series tag and list available languages for that tag\nconst tag = hitomi.tags.create('series', 'trickcal_revive', false);\nconst languages = await tag.listLanguages();\n\nconsole.log(languages);\n```\n\n#### `TagManager.parse(expression)`\n\nParses a human-readable expression into unique `Tag` instances. The expected format is `[-]type:name`, where spaces are represented by underscores.\n\n```typescript\nimport hitomi from 'node-hitomi';\n\n// Parse a string expression into Tag instances\nconst parsedTags = hitomi.tags.parse('female:yandere male:sole_male -tag:group');\n\nconsole.log(parsedTags);\n```\n\n#### `TagManager.search(term)`\n\nSearches tags by partial term and returns tuples of `[Tag, count]`, where `count` is the number of galleries associated with each tag.\n\n```typescript\nimport hitomi from 'node-hitomi';\n\n// Search tags and print their gallery counts\nconst tagAndCounts = await hitomi.tags.search('character:agnes');\n\nfor(const [tag, count] of tagAndCounts) {\n\tconsole.log(`${String(tag)} (${count} galleries)`);\n}\n```\n\n#### `TagManager.list(type, startsWith?)`\n\nLists tags of a specific type, optionally filtered by an initial character.\n\n```typescript\nimport hitomi, { NameInitial } from 'node-hitomi';\n\n// List female tags that start with 'a'\nconst femaleATags = await hitomi.tags.list('female', NameInitial.A);\n\nfor(const tag of femaleATags) {\n\tconsole.log(String(tag));\n}\n```\n\n---\n\n### Media\n\n#### `Image.resolveUrl(extension, thumbnailSize?)`\n\nResolves an image URL in the requested format and optional thumbnail size.\n\n\u003e [!WARNING]\n\u003e \n\u003e Not every `extension` and `thumbnailSize` combination is valid. It must meet the restrictions below.\n\u003e \n\u003e | Thumbnail Size | Extension | Requirement (must be true)       |\n\u003e | :------------- | :-------- | :------------------------------- |\n\u003e | *(none)*       | *(all)*   | `has{Extension}`                 |\n\u003e | `Small`        | *(all)*   | `has{Extension}`                 |\n\u003e | `Medium`       | `Avif`    | `hasThumbnail \u0026\u0026 has{Extension}` |\n\u003e | `Big`          | *(all)*   | `hasThumbnail \u0026\u0026 has{Extension}` |\n\n```typescript\nimport hitomi, { Extension, ThumbnailSize } from 'node-hitomi';\n\n// Retrieve a gallery by id and get thumbnail available images\nconst gallery = await hitomi.galleries.retrieve(123456);\nconst thumbnails = gallery.getThumbnails();\n\n// Full-size WebP URL\nconst imageUrl = await thumbnails[0].resolveUrl(Extension.Webp);\nconsole.log(`Image URL: ${imageUrl}`);\n\n// AVIF medium thumbnail URL\nconst thumbnailUrl = await thumbnails[1].resolveUrl(Extension.Avif, ThumbnailSize.Medium);\nconsole.log(`Thumbnail URL: ${thumbnailUrl}`);\n```\n\n#### `Image.fetch(extension, thumbnailSize?)`\n\nFetches an image as a `Buffer`. The same extension and thumbnail constraints as [`Image.resolveUrl`](#imageresolveurlextension-thumbnailsize) apply.\n\n```typescript\nimport hitomi, { Extension, ThumbnailSize } from 'node-hitomi';\nimport { writeFileSync } from 'fs';\n\n// Retrieve a gallery by id and get thumbnail available images\nconst gallery = await hitomi.galleries.retrieve(123456);\nconst thumbnails = gallery.getThumbnails();\n\n// Fetch and save a full-size image\nconst imageBuffer = await thumbnails[0].fetch(Extension.Webp);\nwriteFileSync('image.webp', imageBuffer);\n\n// Fetch and save a medium thumbnail\nconst thumbnailBuffer = await thumbnails[1].fetch(Extension.Avif, ThumbnailSize.Medium);\nwriteFileSync('thumbnail.avif', thumbnailBuffer);\n```\n\n#### `Video.fetch()`\n\nFetches a gallery video as an MP4 `Buffer`.\n\n```typescript\nimport hitomi from 'node-hitomi';\nimport { writeFileSync } from 'fs';\n\nconst gallery = await hitomi.galleries.retrieve(123456);\n\nif(gallery.video) {\n\t// Fetch and store the MP4 video\n\tconst videoBuffer = await gallery.video.fetch();\n\twriteFileSync('video.mp4', videoBuffer);\n}\n```\n\n#### `Video.fetchPoster()`\n\nFetches the video poster as a WebP `Buffer`.\n\n```typescript\nimport hitomi from 'node-hitomi';\nimport { writeFileSync } from 'fs';\n\nconst gallery = await hitomi.galleries.retrieve(123456);\n\nif(gallery.video) {\n\t// Fetch and store the WebP poster image\n\tconst posterBuffer = await gallery.video.fetchPoster();\n\twriteFileSync('poster.webp', posterBuffer);\n}\n```\n\n## Contribution\n\nContributions are welcome. Feel free to open an issue for bugs or submit a pull request with improvements.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2owater425%2Fnode-hitomi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh2owater425%2Fnode-hitomi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2owater425%2Fnode-hitomi/lists"}