{"id":16328983,"url":"https://github.com/esamattis/deno_karabiner","last_synced_at":"2025-07-30T13:33:08.918Z","repository":{"id":41088196,"uuid":"319037149","full_name":"esamattis/deno_karabiner","owner":"esamattis","description":"Write Complex Modifications for Karabiner-Elements using Typescript and Deno.","archived":false,"fork":false,"pushed_at":"2025-03-12T05:25:54.000Z","size":224,"stargazers_count":19,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-17T10:50:58.890Z","etag":null,"topics":["deno","typescript"],"latest_commit_sha":null,"homepage":"https://deno.land/x/karabiner","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/esamattis.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}},"created_at":"2020-12-06T13:15:28.000Z","updated_at":"2025-02-06T15:05:48.000Z","dependencies_parsed_at":"2024-03-11T08:53:51.543Z","dependency_job_id":"d89d8b8a-9e48-48b7-b2ff-a1d669850951","html_url":"https://github.com/esamattis/deno_karabiner","commit_stats":{"total_commits":107,"total_committers":4,"mean_commits":26.75,"dds":"0.028037383177570097","last_synced_commit":"154c2f7f92d72fb82b4662ff5b0750d9f6b9b500"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/esamattis/deno_karabiner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esamattis%2Fdeno_karabiner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esamattis%2Fdeno_karabiner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esamattis%2Fdeno_karabiner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esamattis%2Fdeno_karabiner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esamattis","download_url":"https://codeload.github.com/esamattis/deno_karabiner/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esamattis%2Fdeno_karabiner/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267875600,"owners_count":24158781,"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-07-30T02:00:09.044Z","response_time":70,"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","typescript"],"created_at":"2024-10-10T23:14:38.163Z","updated_at":"2025-07-30T13:33:08.896Z","avatar_url":"https://github.com/esamattis.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Deno Karabiner\n\nWrite Complex Modifications for\n[Karabiner-Elements](https://karabiner-elements.pqrs.org/) using TypeScript\nand [Deno](https://deno.land/).\n\n## Why?\n\nKarabiner Complex Modifications are in JSON which is not too text editor\nfriendly format. By moving to TypeScript we gain following:\n\n-   Ability write comments\n-   Ability to use variables and any logic we want\n-   Autocomplete via VSCode etc.\n-   Type safety. The key codes etc. are typed\n    -   Although this is not 100% complete. PRs welcome!\n\nWhy Deno? It's the simplest way to run TypeScript code on macOS. No need to\nfiddle with npm and TypeScript configs.\n\n## Usage\n\nCreate `generate.ts`:\n\n```tsx\nimport { KarabinerComplexModifications } from \"https://deno.land/x/karabiner@v0.2.0/karabiner.ts\";\n\nconst mods = new KarabinerComplexModifications();\n\nmods.addRule({\n    description: \"Map Caps Lock to Escape\",\n    manipulators: [\n        {\n            type: \"basic\",\n            from: {\n                key_code: \"caps_lock\",\n            },\n            to: [\n                {\n                    key_code: \"escape\",\n                },\n            ],\n        },\n    ],\n});\n\nmods.writeToProfile(\"Default profile\");\n```\n\nRun it with\n\n```\ndeno run --allow-env --allow-read --allow-write generate.ts\n```\n\nThis will write the rules to the profile name \"Default Profile\" in your\nKarabiner config in `~/.config/karabiner/karabiner.json`. It will not touch\nany other options. The changes will be in effect immediately if you have\nKarabiner running.\n\nIf you want to try it first on a different file you can pass it as the second\narg to `.writeToProfile()`.\n\n```tsx\nmods.writeToProfile(\"Default profile\", \"test.json\");\n```\n\n\u003e `--allow-env` is required so it can find your Karabiner config file using\n\u003e the HOME env which can be removed if you pass an explicit file name here\n\n## Hyper Key Helper\n\nThe lib comes with a helper class for creating Hyper Keys and subsequent\nbindings for them (aka layers).\n\n```tsx\nimport { HyperKey } from \"https://deno.land/x/karabiner@v0.2.0/karabiner.ts\";\n\nconst hyper1 = new HyperKey({\n    id: \"hyper1\",\n    description: \"Caps Lock\",\n    from: {\n        key_code: \"caps_lock\",\n        modifiers: {\n            optional: [\"any\"],\n        },\n    },\n});\n\n// Add the hyper key rules to mods instance\nmods.addRule(hyper1.getRules());\n```\n\nHyper Keys can be used the create whole new \"Layers\" with `.bindKey()`.\n\nFor example in the finnish mac keyboard layout the curly brackets are really\npainful to type (imo 😉) since it needs three keys: `shift + option + 8/9`\nwhich are in awkward positions.\n\nSo here's how to type them with `Caps Lock + d/f`\n\n```tsx\nhyper1.bindKey({\n    // Passed to the Karabiner preferences GUI\n    description: \"Open curly bracket\",\n\n    // Combine the hyper key with key \"d\"\n    key: \"d\",\n\n    // Emit open curly bracket keys\n    to: {\n        key_code: \"8\",\n        modifiers: [\"left_shift\", \"left_alt\"],\n    },\n});\n\nhyper1.bindKey({\n    description: \"Close curly bracket\",\n    key: \"f\",\n    to: {\n        key_code: \"9\",\n        modifiers: [\"left_shift\", \"left_alt\"],\n    },\n});\n```\n\nThe name, id and the descriptions are used to create readable descriptions to\nthe Karabiner preferences view\n\n![image](https://user-images.githubusercontent.com/225712/101291575-8e209980-3812-11eb-93cc-02ad07e4ee01.png)\n\nFor example here's a layer I use\n\n![image](https://user-images.githubusercontent.com/225712/101291309-79430680-3810-11eb-9c57-935b8cc324d0.png)\n\n## Bonus!\n\nGenerate a mapping image like above automatically!\n\n```tsx\nimport { writeHyperKeyImage } from \"https://deno.land/x/karabiner@v0.2.0/svg.ts\";\n\nwriteHyperKeyImage({\n    hyperKeys: [hyper1, hyper2],\n    inputSVGPath: \"./images/layout.svg\",\n    ouputHTMLPath: \"./layout.html\",\n});\n```\n\nThe `layout.svg` can be found from [images/layout.svg](images/layout.svg) and\njust open the generated `layout.html` in a browser.\n\nThe base svg image is quite opinionated. It supports two hyper keys with ids\n`hyper1` and `hyper2`.\n\nYou can find my mapping image here: \u003chttps://esamattis.github.io/deno_karabiner/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesamattis%2Fdeno_karabiner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesamattis%2Fdeno_karabiner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesamattis%2Fdeno_karabiner/lists"}