{"id":41441180,"url":"https://github.com/michaldoda/search-buddy","last_synced_at":"2026-01-23T14:56:25.623Z","repository":{"id":57688805,"uuid":"492027476","full_name":"michaldoda/search-buddy","owner":"michaldoda","description":"🍭 search-buddy ultra lightweight javascript plugin that can help you create instant search and/or facilitate navigation between pages.","archived":false,"fork":false,"pushed_at":"2023-07-11T11:38:20.000Z","size":1514,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-18T01:16:50.941Z","etag":null,"topics":["javascript","navigation-component","search","searching"],"latest_commit_sha":null,"homepage":"https://michaldoda.github.io/search-buddy/","language":"JavaScript","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/michaldoda.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}},"created_at":"2022-05-13T20:08:00.000Z","updated_at":"2023-04-29T09:20:29.000Z","dependencies_parsed_at":"2024-01-12T10:27:06.376Z","dependency_job_id":"9278c862-73ae-407c-94cb-67cd4b00cc0b","html_url":"https://github.com/michaldoda/search-buddy","commit_stats":{"total_commits":84,"total_committers":2,"mean_commits":42.0,"dds":0.0357142857142857,"last_synced_commit":"49a3afbdfb07aeee5ad91711336736c9cfa99023"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/michaldoda/search-buddy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldoda%2Fsearch-buddy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldoda%2Fsearch-buddy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldoda%2Fsearch-buddy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldoda%2Fsearch-buddy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaldoda","download_url":"https://codeload.github.com/michaldoda/search-buddy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldoda%2Fsearch-buddy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28694458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T14:15:13.573Z","status":"ssl_error","status_checked_at":"2026-01-23T14:09:05.534Z","response_time":59,"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":["javascript","navigation-component","search","searching"],"created_at":"2026-01-23T14:56:25.379Z","updated_at":"2026-01-23T14:56:25.606Z","avatar_url":"https://github.com/michaldoda.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n🍭 search-buddy\n\u003c/h1\u003e  \n\n\u003cp align=\"center\"\u003e\n \u003cimg width=\"\" src=\"https://github.com/michaldoda/search-buddy/blob/main/docs/images/logo.png?raw=true\" alt=\"search-buddy js plugin\"\u003e\n\u003c/p\u003e\n\n\u003cp\u003e\n    \u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/michaldoda/search-buddy/actions/workflows/build-n-test.yml/badge.svg\"\u003e\u003cimg src=\"https://github.com/michaldoda/search-buddy/actions/workflows/build-n-test.yml/badge.svg\" alt=\"release workflow result\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n \u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/search-buddy\"\u003e\u003cimg src=\"https://flat.badgen.net/npm/dt/search-buddy\" alt=\"search-buddy total downloads\" /\u003e\u003c/a\u003e   \n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/search-buddy\"\u003e\u003cimg src=\"https://flat.badgen.net/npm/v/search-buddy\" alt=\"search-buddy version\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/search-buddy\"\u003e\u003cimg src=\"https://flat.badgen.net/npm/license/search-buddy\" alt=\"search-buddy license\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n**search-buddy** is an open‑source ultra lightweight javascript plugin (* **\u003c1kb**). It can help you create instant search and/or facilitate navigation between pages. It was written in pure JS without any dependencies, those make it ultra lightweight. * *~0.2kb after gzip*.\n\nIt is especially useful in projects that are stuck in complex navigation structures (e.g. admin panel). It will surely make your users' everyday things more enjoyable.\n\n## Features\n- key shortcut (e.g. `doubleShiftLeft`, `ControlLeft+Slash`, `doubleEscape` and so on)\n- arrow navigation\n- cache mechanism (sessionStorage)\n- built-in search algorithm, you just pass the items to be searched\n- dynamic mode - you can pass an array of items or an async function where you can call your API to fetch items.\n- responsive design\n- and more, please check \u003ca href=\"https://michaldoda.github.io/search-buddy/\" target=\"_blank\"\u003eLive demo\u003c/a\u003e!\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"460\" src=\"https://github.com/michaldoda/search-buddy/blob/main/docs/images/search-buddy.png?raw=true\" alt=\"search-buddy js plugin\"\u003e\n\u003c/p\u003e\n\n\n## Installation\n\n\n```bash\nnpm i search-buddy\n```\n\n## Usage\n\n```js\nimport { SearchBuddy } from 'search-buddy';\n\nlet searchBuddy = SearchBuddy({\n    items: [\n        { title: \"Settings\", path: \"/settings\", icon: \"🛠️\" },\n        { title: \"Users\", path: \"/users\", icon: \"👥️\" }\n    ],\n    keyShortcut: \"doubleShiftLeft\",\n});\n\n// optionally: you can also bind click events to searchBuddy.show\ndocument.querySelector(\"#search-btn\").addEventListener(\"click\", searchBuddy.show);\n\n```\n\nYou also need to load styles, you can import styles in scss\n```scss\n@import 'search-buddy';\n```\nor via javascript (you may need a css loader)\n```js\nimport 'search-buddy/dist/esm/index.css'\n```\n\n\n## Installation via CDN (jsDelivr)\nThis script **contains all** javascript and css styles, there is no need to load any additional file.\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/search-buddy@latest/dist/standalone.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  let searchBuddy = SearchBuddy({\n    items: [\n      { title: \"Settings\", path: \"/settings\", icon: \"🛠️\" },\n      { title: \"Users\", path: \"/users\", icon: \"👥️\" }\n    ],\n    keyShortcut: \"doubleShiftLeft\",\n  });\n\u003c/script\u003e\n```\n\n## Configuration\n### Options with default values\n```js\nSearchBuddy({\n  /**\n   * The URL the user will be redirected to if there are no results\n   * and the user clicks Enter. The search value will be appended to this URL.\n   * \n   * @example: \"/search?query=\"\n   */\n  fallbackSearchUrl: null,\n\n  /**\n   * It can be an array or an async function. \n   * \n   * @example [ {title: \"Page\", path: \"/page\", } ]\n   * or\n   * @example async () =\u003e {\n            return new Promise((resolve, reject) =\u003e {\n                // call your API\n            })\n        }\n   */\n  items: [],\n  /**\n   * Key shortcut used to activate search-buddy.\n   * There is a naming convention. If you want to listen for a double click,\n   * then use \"double[keyCode]\" where [keyCode] is the code of the key.\n   * In case you want to use two key press event,\n   * use the key code separated by a plus sign.\n   *\n   * Key codes: https://w3c.github.io/uievents/#dom-keyboardevent-code\n   *\n   * @example \"doubleShiftLeft\"\n   * @example \"doubleEscape\"\n   * @example \"ControlLeft+Slash\"\n   */\n  keyShortcut: null,\n  /**\n   * The maximum number of items rendered in search box.\n   */\n  maxResults: 25,\n  /**\n   * The placeholder for search input.\n   */\n  placeholder: \"Start typing...\",\n  /**\n   * Flag to enable saving results to sessionStorage.\n   * It is especially useful when loading items via API.\n   */\n  stateSave: false,\n  /**\n   * The time threshold (ms) for double clicks.\n   * It is used only if keyShortcut is passed.\n   */\n  threshold: 1000,\n  /**\n   * Show/hide emojis.\n   */\n  withIcons: true,\n})\n```\n\n### Instance\nWhenever you run `SearchBuddy(options)` the new instance will be created. The instance contains some public attributes and methods. You should avoid creating multiple instances, the idea is to have one instance per entire app.\n\nUsually there is no need to manually interact with the instance, but if you want to use it anyway then here you have a little docs:\n```js\n// Let's create an instance\nconst searchBuddy = SearchBuddy(options);\n\n/**\n * Reference to DOM element\n */\nsearchBuddy.container\n\n/**\n * Manually opens a container\n */\nsearchBuddy.show()\n\n/**\n * Manually hides a container\n */\nsearchBuddy.hide()\n\n/**\n * Manually destroys DOM elements and removes all event listeners \n */\nsearchBuddy.destroy()\n```\n\n## Digging Deeper\n\n### fetch `items` with async\n\nAs you know, it may happen that you have much more URLs, then the recommended solution is to pass an async function for items parameter and enable the session storage cache.\n\nInstead of passing array you can simply pass an async function, this function will be resolved by `search-buddy`. This function MUST return just an array of items.\n```js\nSearchBuddy({\n    items: async () =\u003e { /* ... */ },\n    stateSave: true, // \u003c-- enable cache with sessionStorage\n    keyShortcut: \"doubleShiftLeft\",\n});\n\n```\n\n#### async example\n```js\nSearchBuddy({\n    keyShortcut: \"doubleShiftLeft\",\n    stateSave: true,\n    items: async () =\u003e {\n        const getData = () =\u003e {\n            return fetch('/api/search-buddy-items.json')\n                .then(response =\u003e response.json())\n                .then(data =\u003e data);\n        };\n        return new Promise((resolve, reject) =\u003e {\n            resolve(getData());\n        });\n    },\n});\n```\n\n\n## Contributing\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n## License\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaldoda%2Fsearch-buddy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaldoda%2Fsearch-buddy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaldoda%2Fsearch-buddy/lists"}