{"id":17170640,"url":"https://github.com/cawa-93/electron-nano-store","last_synced_at":"2026-03-16T17:35:54.295Z","repository":{"id":65085604,"uuid":"581819232","full_name":"cawa-93/electron-nano-store","owner":"cawa-93","description":"A minimalistic, secure, type-safe data store for Electron ","archived":false,"fork":false,"pushed_at":"2025-08-31T12:36:48.000Z","size":134,"stargazers_count":10,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-31T14:35:10.340Z","etag":null,"topics":["electron","persistent-storage","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/electron-nano-store","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/cawa-93.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":"https://www.buymeacoffee.com/kozack/"}},"created_at":"2022-12-24T13:05:51.000Z","updated_at":"2025-04-22T07:16:53.000Z","dependencies_parsed_at":"2023-11-18T11:23:51.916Z","dependency_job_id":"dea3a169-81cc-4b28-b92b-7cee994c3cb5","html_url":"https://github.com/cawa-93/electron-nano-store","commit_stats":{"total_commits":70,"total_committers":2,"mean_commits":35.0,"dds":"0.11428571428571432","last_synced_commit":"c4a71193a34c5c07de78e332b763257ee0380cce"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/cawa-93/electron-nano-store","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cawa-93%2Felectron-nano-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cawa-93%2Felectron-nano-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cawa-93%2Felectron-nano-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cawa-93%2Felectron-nano-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cawa-93","download_url":"https://codeload.github.com/cawa-93/electron-nano-store/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cawa-93%2Felectron-nano-store/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274929097,"owners_count":25375708,"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-09-13T02:00:10.085Z","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":["electron","persistent-storage","typescript"],"created_at":"2024-10-14T23:31:08.452Z","updated_at":"2026-03-16T17:35:49.259Z","avatar_url":"https://github.com/cawa-93.png","language":"TypeScript","funding_links":["https://www.buymeacoffee.com/kozack/","https://www.buymeacoffee.com/kozack"],"categories":[],"sub_categories":[],"readme":"[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct-single.svg)](https://stand-with-ukraine.pp.ua)\n\n---\n\n# Nano Electron store\n\n\u003ca href=\"https://www.buymeacoffee.com/kozack\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-red.png\" height=\"60\" alt=\"Buy Me A Coffee\"\u003e\u003c/a\u003e\n\nA minimalistic, secure, type-safe data store for Electron. This package is flat wrapper around [fs-nano-store] and\nwith a few strict checks to allow safely use it in renderer.\n\n\u003e **Note**\n\u003e See the full **[fs-nano-store]** documentation for more information about how store works\n\n## Installation\n\n```\nnpm install electron-nano-store\n```\n\nor\n\n```\npnpm add electron-nano-store\n```\n\nor\n\n```\nyarn add electron-nano-store\n```\n\n## Usage\n\n### Simple\n\nJust expose in main world `defineStore` function and use it directly in your renderer anywhere.\n\n```ts\n// In Electron Preload Script\nimport { defineStore } from \"electron-nano-store\"\nimport { contextBridge } from 'electron'\n\ncontextBridge.exposeInMainWorld('defineStore', defineStore)\n```\n\n```ts\n// In Renderer\nconst store = await defineStore('user')\n\nstore.set('role', 'admin')\nconsole.log(store.get('role')) // -\u003e 'admin'\n```\n\n### Recommended\n\nAs an additional safety precaution, you can choose not to expose a `defineStore` function, but instead expose an already\ndefined store.\nThe examples below also show an example of use with TypeScript.\n\n```ts\n// contracts.ts\nexport type UserStore = {\n\trole: 'admin' | 'user'\n}\n```\n\n```ts\n// in Preload Script\nimport { defineStore } from \"electron-nano-store\"\nimport { contextBridge } from 'electron'\nimport type { UserStore } from 'contracts.ts'\n\nconst userStorePromise = defineStore\u003cUserStore\u003e('user')\ncontextBridge.exposeInMainWorld('userStorePromise', userStorePromise)\n```\n\n```ts\n// In Renderer\nimport type { UserStore } from 'contracts.ts'\nimport type { defineStore } from 'electron-nano-store'\n\ndeclare global {\n\tinterface Window {\n\t\tuserStorePromise: ReturnType\u003ctypeof defineStore\u003cUserStore\u003e\u003e\n\t}\n}\nconst store = await window.userStorePromise\nstore.set('role', 'admin')\nconsole.log(store.get('role')) // -\u003e 'admin'\n\nstore.set('role', 'wrong-role') // TS Error: Argument of type '\"wrong-role\"' is not assignable to parameter of type '\"admin\" | \"user\"'\n```\n\n### Recommended with automatic type inference\n\nThe exchange of types between the preload and the renderer can be a little annoying and complicated. So you can\nuse [unplugin-auto-expose](https://github.com/cawa-93/unplugin-auto-expose) for automatic type inference\n\n```ts\n// in Preload Script\nimport { defineStore } from \"electron-nano-store\"\n\ntype UserStore = {\n\trole: 'admin' | 'user'\n}\nexport const userStorePromise = defineStore\u003cUserStore\u003e('user')\n```\n\n```ts\n// In Renderer\nimport { userStorePromise } from '#preload'\n\nconst store = await userStorePromise\n```\n\n### In Main\n\nThis package was intentionally designed with many restrictions for use in preload. If you want to use it in main, or you\nneed more control you should use [fs-nano-store] directly\n\n```ts\n// In Main\nimport { defineStore } from 'fs-nano-store'\nimport { resolveStoreFilepath } from 'electron-nano-store'\nimport { app } from 'electron'\n\nconst store = await defineStore(\n\tresolveStoreFilepath(\n\t\t'store-name',\n\t\tapp.getPath('userData')\n\t)\n)\n```\n\n### Listen store changes in Renderer\n\n[fs-nano-store] automatically tracks all changes to the store, and emit a `changed` event if the store has been changed\nout of context.\n\nHowever, electron does not allow you to expose `EventEmitter` to the main world. This means that even though it defines\nand returns `change` property, you can't add listeners directly.\n\n```ts\nconst { changes } = defineStore('store-name')\nchanges.addListener // undefined\n```\n\nTo do this, you **must** define store in the preload context, add listeners there, and proxy all events to an\nexisting `EventTarget`, such as a `window`\n\n```ts\n// in Preload Script\nconst storePromise = defineStore\u003cStore\u003e('user')\nstorePromise.then(({ changes }) =\u003e {\n\tchanges.addListener(\n\t\t'changed',\n\t\t() =\u003e globalThis.dispatchEvent(new CustomEvent('user:changed')),\n\t)\n})\n```\n\n```ts\n// in Renderer\nglobalThis.addEventListener(\n\t'user:changed',\n\t() =\u003e { /* ... */\n\t}\n)\n```\n\n## Security limitation\n\n1. You can't somehow change where are storage files placed in filesystems.\n   It always in `electron.app.getPath('userData')` directory defined by electron.\n   Since the `defineStore` function may be exposed to a non-secure context, this is done to prevent malicious code from\n   making\n   uncontrolled writes anywhere on the file system.\n    ```ts\n    // 🚫 Harmful use\n    defineStore('.privat-config', { customPath: '/somewhere/in/user/filesystem/' })\n    ```\n   \u003e **Note**\n   \u003e If you need create store in some different location, you should make your own wrapper around [fs-nano-store]. Look\n   how use [In Main](#in-main).\n2. For the same reasons, you cannot use any path fragments in the repository name\n    ```ts\n    // 🚫 Harmful use\n    defineStore('../../somewhere/in/user/filesystem/privat-config')\n    ```\n\n[fs-nano-store]: https://github.com/cawa-93/fs-nano-store\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcawa-93%2Felectron-nano-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcawa-93%2Felectron-nano-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcawa-93%2Felectron-nano-store/lists"}