{"id":17609900,"url":"https://github.com/vixalien/muse","last_synced_at":"2025-08-03T14:13:02.384Z","repository":{"id":147529279,"uuid":"614435847","full_name":"vixalien/muse","owner":"vixalien","description":"Youtube Music API (InnerTube) client for Deno, Node and the browser","archived":false,"fork":false,"pushed_at":"2025-07-18T09:59:43.000Z","size":617,"stargazers_count":39,"open_issues_count":7,"forks_count":10,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-07-18T12:07:27.781Z","etag":null,"topics":["deno","innertube","youtube","youtube-music"],"latest_commit_sha":null,"homepage":"https://deno.land/x/muse?doc","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/vixalien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":"vixalien","custom":["https://www.buymeacoffee.com/vixalien"]}},"created_at":"2023-03-15T15:23:05.000Z","updated_at":"2025-07-18T09:57:30.000Z","dependencies_parsed_at":"2024-03-06T03:25:44.491Z","dependency_job_id":"51796594-5a6c-4ed7-ad8b-fbef9d477e13","html_url":"https://github.com/vixalien/muse","commit_stats":{"total_commits":350,"total_committers":3,"mean_commits":"116.66666666666667","dds":0.005714285714285672,"last_synced_commit":"50c05475dae9ef0af6111c197655e18b6edc8230"},"previous_names":[],"tags_count":107,"template":false,"template_full_name":null,"purl":"pkg:github/vixalien/muse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixalien%2Fmuse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixalien%2Fmuse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixalien%2Fmuse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixalien%2Fmuse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vixalien","download_url":"https://codeload.github.com/vixalien/muse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixalien%2Fmuse/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268554913,"owners_count":24269064,"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","status":"online","status_checked_at":"2025-08-03T02:00:12.545Z","response_time":2577,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["deno","innertube","youtube","youtube-music"],"created_at":"2024-10-22T17:24:00.948Z","updated_at":"2025-08-03T14:13:02.347Z","avatar_url":"https://github.com/vixalien.png","language":"TypeScript","funding_links":["https://github.com/sponsors/vixalien","https://www.buymeacoffee.com/vixalien"],"categories":[],"sub_categories":[],"readme":"# muse\n\nA library to interact with the YouTube Music (InnerTube) api.\n\n\u003e Note: This library is still in development, and is not ready for production\n\u003e use.\n\n## Usage\n\nmuse works on Deno, Node.js, the browser and any javascript environment that\nsupports ES modules and fetch.\n\nYou can read [the docs](https://deno.land/x/muse?doc) for more information about\nthe usage of each function.\n\nDon't forget to replace `VERSION` with the\n[latest version](https://github.com/vixalien/muse/tags)\n\n### Deno\n\n```ts\nimport * as muse from \"https://deno.land/x/muse@VERSION/mod.ts\";\n\n// you can also use the latest version (not recommended) with\n// import * as muse from \"https://deno.land/x/muse/mod.ts\";\n\n// you can also import directly from github\n// import * as muse from \"https://raw.githubusercontent.com/vixalien/muse/VERSION/mod.ts\";\n\nconst search_results = await muse.search(\"drake\");\nconst rickroll = await muse.get_song(\"dQw4w9WgXcQ\");\n```\n\n### Browser\n\nYou'll need to use a CDN that supports ES modules, such as\n[esm.sh](https://esm.sh/), [jspm.io](https://jspm.io/) or\n[skypack.dev](https://skypack.dev/).\n\n#### Proxy\n\nYou'll also need to use a proxy server to get around CORS errors. It's a good\nidea to self host the proxy server\n([cors-anywhere](https://github.com/Rob--W/cors-anywhere) and\n[deno_deploy_cors_proxy](https://github.com/justjavac/deno_deploy_cors_proxy/)\nare good options).\n\n```js\nimport * as muse from \"https://esm.sh/libmuse@VERSION\";\n\n// import * as muse from \"https://jspm.dev/npm:libmuse@VERSION\";\n// import * as muse from \"https://cdn.skypack.dev/libmuse@VERSION\";\n\n// setting up our proxy\nmuse.set_option(\"fetch\", (url, options) =\u003e {\n  return fetch(`https://proxy.example.com/${url}`, options);\n});\n\nconst search_results = await muse.search(\"top radio\");\n```\n\n### Node\n\nFirst install using your preferred package manager (npm, yarn, pnpm etc.)\n\n```bash\nnpm install libmuse\n```\n\nThen use it in by importing `libmuse`. The Node version has the exact same\nfeatures as the Deno version.\n\n```js\nimport * as muse from \"libmuse\";\n// commonjs: const muse = require(\"libmuse\");\n\nconst artist = await muse.get_artist(\"UCvyjk7zKlaFyNIPZ-Pyvkng\");\n```\n\nFor the complete list of operations, see\n[the docs](https://deno.land/x/muse/mod.ts?doc).\n\n## Auth\n\nCurrently, muse supports oauth authentication by posing as the YouTube TV app.\n\nHere's the flow:\n\n1. Get a login code\n2. Go to the given login url, and type in the login code on a device that is\n   logged into a google account\n3. Get the OAuth token \u0026 refresh tokens\n\n```ts\nimport * as muse from \"https://deno.land/x/muse@VERSION/mod.ts\";\n\nconst auth = muse.get_option(\"auth\");\n\nmuse.setup({\n  // make sure to persist the token\n  store: new DenoFileStore(\"store/muse-store.json\"),\n  debug: true,\n});\n\n// this is the authentication flow\nconst auth_flow = async () =\u003e {\n  if (auth.has_token()) return;\n  console.log(\"Getting login code...\");\n\n  const loginCode = await auth.get_login_code();\n\n  console.log(\n    `Go to ${loginCode.verification_url} and enter the code: ${loginCode.user_code}`,\n  );\n\n  // not necessary, but saves some requests\n  alert(\"Press enter when you have logged in\");\n\n  console.log(\"Loading token...\");\n\n  await auth.load_token_with_code(\n    loginCode.device_code,\n    loginCode.interval,\n  );\n\n  console.log(\"Logged in!\", auth._token);\n};\n\n// listen to the `requires-login` event, then resolve pass on a function that\n// returns a promise that will resolve when the auth flow is complete\nauth.addEventListener(\"requires-login\", (event) =\u003e {\n  const resolve = event.detail;\n\n  resolve(auth_flow);\n});\n```\n\nIn the future, I plan to add support for other auth methods, such as cookies and\nYoutube TV login codes.\n\n## Storage\n\nYou can pass in a storage object to the client to persist the auth token.\n\n```ts\nimport * as muse from \"https://deno.land/x/muse@VERSION/mod.ts\";\n\n// you can use the \"best\" store, which is DenoFileStore if available, then LocalStorageStore, then MemoryStore\nconst client = muse.setup({ store: muse.get_best_store() });\n\n// or you can use any of the built-in stores\nconst client = muse.setup({ store: new muse.DenoFileStore(\"/path/to/file.json\") });\nconst client = muse.setup({ store: new muse.LocalStorageStore() });\nconst client = muse.setup({ store: new muse.MemoryStore() });\n\n// or you can implement your own store\n// by extending the Store abstract class\nclass MyStore extends muse.Store {\n  get\u003cT\u003e(key: string): T | null;\n  set(key: string, value: unknown): void;\n  delete(key: string): void;\n}\n\n// then use it accordingly\nconst client = muse.setup({ store: new MyStore() });\n\n// Do note that setup() can be called multiple times, but it's not recommended. \n// this is because setup overrides the global store, so if you call setup()\n// multiple times, other options set before will be ignored. example:\n\nmuse.setup({ auth: { /* custom auth options */ } });\nmuse.setup({ store: /* custom store */ });\n\n// the above will only use the custom store, and ignore the custom auth options\n\n// if you need to configure options many times use `muse.set_option`\nmuse.set_option(\"store\", /* custom store */)\n```\n\n## Operations\n\nI'm currently targetting to match the [ytmusicapi]'s capabilities.\n\n### search\n\n- [x] search\n- [x] search suggestions\n\n### browsing\n\n- [x] home\n- [x] get artist\n- [x] get artist albums\n- [x] get album\n- [x] get album browse id\n- [x] get user\n- [x] get user playlists\n- [x] get song\n- [x] get song related\n- [x] get lyrics\n- [ ] get tasteprofile\n- [ ] set tasteprofile\n\n### explore\n\n- [x] get explore\n- [x] get mood categories\n- [x] get mood playlists\n- [x] get charts\n- [x] get new releases\n\n### watch\n\n- [x] get queue ~~get watch playlist~~\n\n### library\n\n- [x] get library\n- [x] get library playlists\n- [x] get library songs\n- [x] get library albums\n- [x] get library artists\n- [x] get library subscriptions\n- [x] get liked songs\n- [x] get history\n- [x] add history item\n- [x] remove history items\n- [x] rate song\n- [x] edit song library status\n- [x] rate playlist\n- [x] subscribe artists\n- [x] unsubscribe artists\n\n### playlists\n\n- [x] get playlist\n- [x] create playlist\n- [x] edit playlist\n- [x] delete playlist\n- [x] add playlist items\n- [x] remove playlist items\n\n### uploads\n\n- [x] get library uploads\n- [x] get library upload songs\n- [x] get library upload artists\n- [x] get library upload albums\n- [x] get library upload artist\n- [x] get library upload album\n- [x] upload song (doesn't currectly work because the TV client can't do\n      uploads)\n- [x] delete upload entity\n\n## Acknowledgements\n\n- [ytmusicapi] - The inspiration for this library\n- [Youtube Internal Clients][internal-clients] - The source of the client names\n  and versions\n- many random gists and blog posts whose links I've lost\n\n[ytmusicapi]: https://ytmusicapi.readthedocs.io/en/stable/reference.html\n[internal-clients]: https://github.com/zerodytrash/YouTube-Internal-Clients\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvixalien%2Fmuse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvixalien%2Fmuse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvixalien%2Fmuse/lists"}