{"id":15017195,"url":"https://github.com/kitschpatrol/yanki-connect","last_synced_at":"2026-05-16T21:17:33.897Z","repository":{"id":242999091,"uuid":"808022444","full_name":"kitschpatrol/yanki-connect","owner":"kitschpatrol","description":"A fully-typed Anki-Connect API client.","archived":false,"fork":false,"pushed_at":"2026-01-21T02:41:45.000Z","size":1920,"stargazers_count":47,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-21T13:52:23.668Z","etag":null,"topics":["anki","anki-connect","api","client","flashcards","npm-package","spaced-repetition","yanki"],"latest_commit_sha":null,"homepage":"","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/kitschpatrol.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","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":"2024-05-30T08:23:19.000Z","updated_at":"2026-01-21T02:41:48.000Z","dependencies_parsed_at":"2024-06-06T06:31:39.460Z","dependency_job_id":"d1c9a55d-525a-4dd2-aa5d-adc72bf74d75","html_url":"https://github.com/kitschpatrol/yanki-connect","commit_stats":{"total_commits":94,"total_committers":1,"mean_commits":94.0,"dds":0.0,"last_synced_commit":"7690548e13a35dd616ec97ced1c04cb759cd7e3c"},"previous_names":["kitschpatrol/yanki-connect"],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/kitschpatrol/yanki-connect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fyanki-connect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fyanki-connect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fyanki-connect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fyanki-connect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kitschpatrol","download_url":"https://codeload.github.com/kitschpatrol/yanki-connect/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitschpatrol%2Fyanki-connect/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29601499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T02:50:40.506Z","status":"ssl_error","status_checked_at":"2026-02-19T02:50:26.316Z","response_time":117,"last_error":"SSL_read: 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":["anki","anki-connect","api","client","flashcards","npm-package","spaced-repetition","yanki"],"created_at":"2024-09-24T19:50:01.448Z","updated_at":"2026-05-16T21:17:33.869Z","avatar_url":"https://github.com/kitschpatrol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- title --\u003e\n\n# yanki-connect\n\n\u003c!-- /title --\u003e\n\n\u003c!-- badges --\u003e\n\n[![NPM Package yanki-connect](https://img.shields.io/npm/v/yanki-connect.svg)](https://npmjs.com/package/yanki-connect)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit/)\n[![CI](https://github.com/kitschpatrol/yanki-connect/actions/workflows/ci.yml/badge.svg)](https://github.com/kitschpatrol/yanki-connect/actions/workflows/ci.yml)\n\n\u003c!-- /badges --\u003e\n\n\u003c!-- short-description --\u003e\n\n**A fully-typed AnkiConnect API client.**\n\n\u003c!-- /short-description --\u003e\n\n## Overview\n\nYanki Connect exists to streamline development of JavaScript and TypeScript applications that use Alex Yatskov's [AnkiConnect](https://ankiweb.net/shared/info/2055492159) add-on to interface with the [Anki](https://apps.ankiweb.net) spaced repetition flashcard software. The library provides extensive type annotations for the AnkiConnect API, and includes a turn-key client implementation.\n\nThe \"Y\" prefix in \"Yanki\" is in the \"Yet another\" naming tradition; a nod to Anki's robust and occasionally duplicative ecosystem of third-party tools. (Also, appropriately, Yankī are a variety of [truant youth](https://en.wikipedia.org/wiki/Yankee#/media/File:ヤンキー.jpg).)\n\nThis library is used in the [`yanki`](https://github.com/kitschpatrol/yanki) CLI tool, which in turn powers the [`yanki-obsidian`](https://github.com/kitschpatrol/yanki-obsidian) [Obsidian](https://obsidian.md/) plugin.\n\n## Features\n\n- **Action method organization + convenience methods**\\\n  Instead of putting all \u003c!-- actionCount --\u003e116\u003c!-- /actionCount --\u003e methods in a single namespace, action convenience methods are organized into the same groups used in the [AnkiConnect documentation](https://git.sr.ht/~foosoft/anki-connect/tree/25.11.9.0/item/README.md#supported-actions), to simplify auto-complete discoverability.\n\n- **Low-level access through the provided `invoke` method**\\\n  If you don't want to use the convenience methods, an `invoke(action, params)` method is also exposed on the YankiConnect class for direct interaction with the AnkiConnect API.\n\n- **Inline documentation and full type annotations**\\\n  The action method types are annotated with JSDoc-style comments to provide documentation and links in your IDE's auto-complete pop-over.\n\n- **Errors from the API are thrown**\\\n  Instead of returning an object with `result` and `error` keys, Yanki Connect's convenience methods checks for errors in responses from the AnkiConnect API, and throws them as errors. This gives more convenient access to the result, but means you'll need to do your own error handling.\n\n  _Note that this only applies to the convenience methods (`client.card.*`, etc.) the `invoke(action, params)` method returns the AnkiConnect API's raw `{\"result\": ..., \"error\": null}` responses._\n\n- **Anki desktop app auto-launch**\\\n  Perhaps the most precarious aspect of the AnkiConnect add-on is that the Anki desktop application _must_ be running for any of the API calls to work. Yanki Connect tries to sand down this rough edge by (optionally) automatically launching the Anki desktop app if it's not running already.\n\n  You can enable this behavior by passing a configuration option when the class is instantiated:\n\n  ```ts\n  const client = new YankiConnect({ autoLaunch: true })\n  ```\n\n  _Warning: This feature is experimental, and is currently only supported in a Node environment on macOS._\n\n## Getting started\n\n### Dependencies\n\nYanki Connect is universal / isomorphic: it runs in the browser and Node 20.11+ compatible environments. The exported APIs are ESM-only. It's implemented in TypeScript and bundles extensive type definitions.\n\nThe Anki desktop app (\u003e=2.1.45, released 2021-07-30) with the AnkiConnect add-on installed and configured is also required to do anything useful with the library.\n\nThe API calls are written against version [25.11.9.0](https://git.sr.ht/~foosoft/anki-connect/tree/25.11.9.0/item/README.md) of the AnkiConnect add-on, released 2025-11-02. You must use either this or a newer version of the AnkiConnect add-on for compatibility with all available calls. A majority of the calls are compatible with older version of the AnkiConnect add-on, but this is at your own risk.\n\n### Installation\n\nAdd the library to your project:\n\n```sh\nnpm install yanki-connect\n```\n\nOr, a bundled and minified ES module is available on CDNs:\n\n```ts\nimport { YankiConnect } from 'https://cdn.jsdelivr.net/npm/yanki-connect'\n```\n\nor\n\n```ts\nimport { YankiConnect } from 'https://unpkg.com/yanki-connect'\n```\n\n## Usage\n\nYanki Connect aims to be discoverable and self-documenting when used in an environment with a robust autocompletion / language service implementation. (VS Code, for example.)\n\nThe library exports the `YankiConnect` class, which groups methods into the same structure of \"supported actions\" used in the official [AnkiConnect documentation](https://git.sr.ht/~foosoft/anki-connect/tree/25.11.9.0/item/README.md#supported-actions).\n\nHere's a simple example:\n\n```ts\nimport { YankiConnect } from 'yanki-connect'\n\nconst client = new YankiConnect()\n\nconst decks = await client.deck.deckNames()\n\nconsole.log(decks) // [\"Your\", \"Deck\", \"Names\", \"Here\"]\n```\n\nAll \u003c!-- actionCount --\u003e116\u003c!-- /actionCount --\u003e AnkiConnect actions are exposed under their respective groups, with type data for both parameters and return types:\n\n\u003c!-- actionList --\u003e\n\n```ts\nclient.card.answerCards\nclient.card.areDue\nclient.card.areSuspended\nclient.card.cardsInfo\nclient.card.cardsModTime\nclient.card.cardsToNotes\nclient.card.findCards\nclient.card.forgetCards\nclient.card.getEaseFactors\nclient.card.getIntervals\nclient.card.relearnCards\nclient.card.setDueDate\nclient.card.setEaseFactors\nclient.card.setSpecificValueOfCard\nclient.card.suspend\nclient.card.suspended\nclient.card.unsuspend\n\nclient.deck.changeDeck\nclient.deck.cloneDeckConfigId\nclient.deck.createDeck\nclient.deck.deckNames\nclient.deck.deckNamesAndIds\nclient.deck.deleteDecks\nclient.deck.getDeckConfig\nclient.deck.getDeckStats\nclient.deck.getDecks\nclient.deck.removeDeckConfigId\nclient.deck.saveDeckConfig\nclient.deck.setDeckConfigId\n\nclient.graphical.guiAddCards\nclient.graphical.guiAnswerCard\nclient.graphical.guiBrowse\nclient.graphical.guiCheckDatabase\nclient.graphical.guiCurrentCard\nclient.graphical.guiDeckBrowser\nclient.graphical.guiDeckOverview\nclient.graphical.guiDeckReview\nclient.graphical.guiEditNote\nclient.graphical.guiExitAnki\nclient.graphical.guiImportFile\nclient.graphical.guiPlayAudio\nclient.graphical.guiSelectCard\nclient.graphical.guiSelectNote\nclient.graphical.guiSelectedNotes\nclient.graphical.guiShowAnswer\nclient.graphical.guiShowQuestion\nclient.graphical.guiStartCardTimer\nclient.graphical.guiUndo\n\nclient.media.deleteMediaFile\nclient.media.getMediaDirPath\nclient.media.getMediaFilesNames\nclient.media.retrieveMediaFile\nclient.media.storeMediaFile\n\nclient.miscellaneous.apiReflect\nclient.miscellaneous.exportPackage\nclient.miscellaneous.getActiveProfile\nclient.miscellaneous.getProfiles\nclient.miscellaneous.importPackage\nclient.miscellaneous.loadProfile\nclient.miscellaneous.multi\nclient.miscellaneous.reloadCollection\nclient.miscellaneous.requestPermission\nclient.miscellaneous.sync\nclient.miscellaneous.version\n\nclient.model.createModel\nclient.model.findAndReplaceInModels\nclient.model.findModelsById\nclient.model.findModelsByName\nclient.model.modelFieldAdd\nclient.model.modelFieldDescriptions\nclient.model.modelFieldFonts\nclient.model.modelFieldNames\nclient.model.modelFieldRemove\nclient.model.modelFieldRename\nclient.model.modelFieldReposition\nclient.model.modelFieldSetDescription\nclient.model.modelFieldSetFont\nclient.model.modelFieldSetFontSize\nclient.model.modelFieldsOnTemplates\nclient.model.modelNames\nclient.model.modelNamesAndIds\nclient.model.modelStyling\nclient.model.modelTemplateAdd\nclient.model.modelTemplateRemove\nclient.model.modelTemplateRename\nclient.model.modelTemplateReposition\nclient.model.modelTemplates\nclient.model.updateModelStyling\nclient.model.updateModelTemplates\n\nclient.note.addNote\nclient.note.addNotes\nclient.note.addTags\nclient.note.canAddNotes\nclient.note.canAddNotesWithErrorDetail\nclient.note.clearUnusedTags\nclient.note.deleteNotes\nclient.note.findNotes\nclient.note.getNoteTags\nclient.note.getTags\nclient.note.notesInfo\nclient.note.notesModTime\nclient.note.removeEmptyNotes\nclient.note.removeTags\nclient.note.replaceTags\nclient.note.replaceTagsInAllNotes\nclient.note.updateNote\nclient.note.updateNoteFields\nclient.note.updateNoteModel\nclient.note.updateNoteTags\n\nclient.statistic.cardReviews\nclient.statistic.getCollectionStatsHTML\nclient.statistic.getLatestReviewID\nclient.statistic.getNumCardsReviewedByDay\nclient.statistic.getNumCardsReviewedToday\nclient.statistic.getReviewsOfCards\nclient.statistic.insertReviews\n```\n\n\u003c!-- /actionList --\u003e\n\nNote that at the moment, only the latest AnkiConnect API version 6 is supported, and AnkiConnect release \u003e=25.11.9.0 is required for compatibility with all features.\n\n### API\n\n#### Configuration\n\nThe `YankiConnect` class features sensible defaults that should work fine for most configurations of AnkiConnect, but if you'd like to customize the client, you can pass an argument of type `YankiConnectOptions` with any of the following:\n\n| Key          | Type                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Default              |\n| ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |\n| `host`       | `string`                   | Host where the AnkiConnect service is running.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `'http://127.0.0.1'` |\n| `port`       | `number`                   | Port where the AnkiConnect service is running.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `8765`               |\n| `version`    | `AnkiConnectVersion`       | AnkiConnect API version. Only API version 6 is supported.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `6`                  |\n| `key`        | `string`                   | AnkiConnect security key. Usually not required.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `undefined`          |\n| `autoLaunch` | `boolean \\| 'immediately'` | Attempt to launch the Anki desktop application if it's not already running.\u003cbr\u003e\u003cul\u003e\u003cli\u003e`true` will always attempt to open Anki _when a request is made_. This might introduce significant latency on the first launch.\u003c/li\u003e\u003cli\u003e`false` will never attempt to open Anki. Requests will fail until something or someone opens the Anki app.\u003c/li\u003e\u003cli\u003e`'immediately'` is a special option that will open Anki when the client is instantiated.\u003c/li\u003e\u003c/ul\u003eThe Anki desktop app must be running for the client and the underlying AnkiConnect service to work.\u003cbr\u003e\u003cbr\u003eCurrently supported on macOS only. | `false`              |\n\n### Bundling for the browser\n\nIf you're using a build tool like [Vite](https://vite.dev/) to include Yanki Connect in your browser-based project, you'll need to externalize Node-specific dependencies.\n\nAdd the following to your Vite config:\n\n```ts\nimport { defineConfig } from 'vite'\n\nexport default defineConfig({\n  build: {\n    minify: false,\n    rollupOptions: {\n      external: ['open'],\n    },\n  },\n})\n```\n\n### Examples\n\n#### Creating a note\n\n```ts\nimport { YankiConnect } from 'yanki-connect'\n\nconst client = new YankiConnect()\n\n// Assumes 'Default' deck and 'Basic' model exist!\nconst note = {\n  note: {\n    deckName: 'Default',\n    fields: {\n      Back: \"\u003cp\u003eI'm the back of the card\u003c/p\u003e\\n\",\n      Front: \"\u003cp\u003eI'm the front of the card\u003c/p\u003e\\n\",\n    },\n    modelName: 'Basic',\n    tags: ['yanki'],\n  },\n}\n\nconst noteId = await client.note.addNote(note)\n\nconsole.log(noteId) // E.g. 1716968687679\n```\n\n#### Listing decks\n\n```ts\nimport { YankiConnect } from 'yanki-connect'\n\nconst client = new YankiConnect()\nconst decks = await client.deck.deckNames()\nconsole.log(decks) // [\"Your\", \"Deck\", \"Names\", \"Here\"]\n```\n\n#### Direct invocation\n\n```ts\nimport { YankiConnect } from 'yanki-connect'\n\nconst client = new YankiConnect()\nconst decks = await client.invoke('deckNames')\nconsole.log(decks) // [\"Your\", \"Deck\", \"Names\", \"Here\"]\n```\n\n## Background\n\n### Similar projects\n\nChen Lijun's [autoanki](https://github.com/chenlijun99/autoanki) also implements a nicely typed AnkiConnect wrapper.\n\n## Maintainers\n\n[kitschpatrol](https://github.com/kitschpatrol)\n\n## Acknowledgments\n\nThanks to [Alex Yatskov](https://foosoft.net/) for creating [AnkiConnect](https://ankiweb.net/shared/info/2055492159).\n\nAll of the embedded action descriptions in Yanki Connect are taken directly from the [AnkiConnect project readme](https://git.sr.ht/~foosoft/anki-connect/tree/25.11.9.0/item/README.md).\n\n\u003c!-- contributing --\u003e\n\n## Contributing\n\n[Issues](https://github.com/kitschpatrol/yanki-connect/issues) are welcome and appreciated.\n\nPlease open an issue to discuss changes before submitting a pull request. Unsolicited PRs (especially AI-generated ones) are unlikely to be merged.\n\nThis repository uses [@kitschpatrol/shared-config](https://github.com/kitschpatrol/shared-config) (via its `ksc` CLI) for linting and formatting, plus [MDAT](https://github.com/kitschpatrol/mdat) for readme placeholder expansion.\n\n\u003c!-- /contributing --\u003e\n\n\u003c!-- license --\u003e\n\n## License\n\n[MIT](license.txt) © [Eric Mika](https://ericmika.com)\n\n\u003c!-- /license --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitschpatrol%2Fyanki-connect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkitschpatrol%2Fyanki-connect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitschpatrol%2Fyanki-connect/lists"}