{"id":22856196,"url":"https://github.com/wave-play/stashy","last_synced_at":"2026-02-03T14:32:31.631Z","repository":{"id":60037167,"uuid":"540080978","full_name":"Wave-Play/stashy","owner":"Wave-Play","description":"Storage API for Node, React Native, and the browser","archived":false,"fork":false,"pushed_at":"2023-12-29T08:10:26.000Z","size":2554,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-24T19:57:36.987Z","etag":null,"topics":["async-storage","expo","javascript","nextjs","node","nodejs","react","react-native","reactjs","storage","waveplay"],"latest_commit_sha":null,"homepage":"https://demo.stashy.waveplay.dev","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/Wave-Play.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}},"created_at":"2022-09-22T16:54:18.000Z","updated_at":"2023-01-12T17:57:00.000Z","dependencies_parsed_at":"2023-02-01T05:15:47.933Z","dependency_job_id":null,"html_url":"https://github.com/Wave-Play/stashy","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wave-Play%2Fstashy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wave-Play%2Fstashy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wave-Play%2Fstashy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wave-Play%2Fstashy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wave-Play","download_url":"https://codeload.github.com/Wave-Play/stashy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251729674,"owners_count":21634279,"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","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":["async-storage","expo","javascript","nextjs","node","nodejs","react","react-native","reactjs","storage","waveplay"],"created_at":"2024-12-13T08:07:28.995Z","updated_at":"2026-02-03T14:32:31.585Z","avatar_url":"https://github.com/Wave-Play.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eStashy\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![GitHub license](https://img.shields.io/github/license/Wave-Play/stashy?style=flat)](https://github.com/Wave-Play/stashy/blob/main/LICENSE) [![Tests](https://github.com/Wave-Play/stashy/workflows/CI/badge.svg)](https://github.com/Wave-Play/stashy/actions) ![npm](https://img.shields.io/npm/v/@waveplay/stashy) [![minizipped size](https://badgen.net/bundlephobia/minzip/@waveplay/stashy)](https://bundlephobia.com/result?p=@waveplay/stashy)\n\n**Storage API for Node, React Native, and the browser**\n\nStashy uses the best storage backend for each environment.\n\n\u003ca href=\"https://demo.stashy.waveplay.dev\"\u003e\u003cb\u003eLive demo project for web\u003c/b\u003e\u003c/a\u003e\n\n\u003c/div\u003e\n\n## Getting started\n\nInstall the package:\n\n```bash\nnpm install @waveplay/stashy\n```\n\nUse functions such as `get(key)` or `set(key, value)`. These will be delegated to the correct backend based on the environment your code is running in. \n\n```ts\nimport stashy from '@waveplay/stashy'\n\n// Get a value from storage\nconst displayName = stashy.getString('name')\nconsole.log(`Your username is ${displayName}`)\n\n// Update a value in storage\n// It'll be saved and available when you come back later\nstashy.set('name', 'Pkmmte Xeleon')\n```\n\nSee the [sample project](https://github.com/Wave-Play/stashy/tree/master/examples/basic-example) for more usage examples.\n\n## API reference\n\n| Function          | Description                                              |\n| ----------------- | -------------------------------------------------------- |\n| `clearAll`        | Clears all data from the backend.                        |\n| `delete`          | Deletes the value for the given key.                     |\n| `get`             | Gets the value for the given key.                        |\n| `getAsync`        | Gets the value for the given key asynchronously.         |\n| `getBoolean`      | Gets the boolean value for the given key.                |\n| `getBooleanAsync` | Gets the boolean value for the given key asynchronously. |\n| `getNumber`       | Gets the number value for the given key.                 |\n| `getNumberAsync`  | Gets the number value for the given key asynchronously.  |\n| `getString`       | Gets the string value for the given key.                 |\n| `getStringAsync`  | Gets the string value for the given key asynchronously.  |\n| `set`             | Sets the value for the given key.                        |\n\n## Default instance\n\nWhen you use `import stashy from '@waveplay/stashy'`, you're importing the default instance of Stashy. This instance is created with the default options and will use the best backend for your environment.\n\nThis may be considered unnecessary overhead if you're creating new instances of Stashy in your code instead of using the default instance. Import from `@waveplay/stashy/core` instead to avoid this overhead.\n\n```ts\nimport { Stashy } from '@waveplay/stashy/core'\n\nconst stashy = new Stashy({\n\t// ... your custom options\n})\n```\n\n## Backends\n\nStashy comes with a few backends available out of the box. You can also create your own backend by implementing the `StashyBackend` interface.\n\n```ts\nimport { Stashy } from '@waveplay/stashy'\nimport { StashyBackend } from '@waveplay/stashy/backend'\n\nclass CustomBackend implements StashyBackend {\n  // ... your custom backend implementation\n}\n\nconst stashy = new Stashy({\n  backend: new CustomBackend()\n})\n\n// or with different backends per environment\nconst stashy = new Stashy({\n  backend: {\n    native: new MmkvBackend(),\n    ssr: new CookieBackend(),\n    web: new CustomBackend()\n  }\n})\n```\n\n#### AsyncStorage\n\nThis backend uses [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage) to store data. It is the default backend for native and only works with async functions such as `getStringAsync()`.\n\n```ts\nimport { AsyncStorageBackend } from '@waveplay/stashy/backend/async-storage'\n```\n\n#### Cookie\n\nCookie-backed storage perfect for server-side environments. It is the default backend for SSR and requires a `context` object to be passed with every function call.\n\n```ts\nimport { CookieBackend } from '@waveplay/stashy/backend/cookie'\n```\n\n#### Env\n\nMeant to use `process.env` variables. Supports dot notation for nested objects. \n\n```ts\nimport { EnvBackend } from '@waveplay/stashy/backend/env'\n```\n\n\u003e **Note:** This will not load the `.env` file for you. Use with [dotenv](https://github.com/motdotla/dotenv) if you need to load the `.env` file. Frameworks like [Next.js](https://nextjs.org/) and [Pilot.js](https://github.com/Wave-Play/pilot/) do this automatically.\n\n#### LocalStorage\n\nRelies on `localStorage` to store data. It is the default backend for web.\n\n```ts\nimport { LocalStorageBackend } from '@waveplay/stashy/backend/local-storage'\n```\n\n#### MMKV\n\nExtremely fast and efficient storage for React Native, but requires that you install [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) separately. If you're using Expo, you will also need to generate a new development client build.\n\n```ts\nimport { MmkvBackend } from '@waveplay/stashy/backend/mmkv'\n```\n\n## Debugging\n\nYou can pass your own logger (such as [pino](https://github.com/pinojs/pino)) to Stashy when creating a new instance and it will be used to log events. This is useful for debugging backend and environment issues. \n\nThe `id` property is included in each log message to help you differentiate between multiple instances of Stashy.\n\n```ts\nimport { Stashy } from '@waveplay/stashy'\nimport pino from 'pino'\n\nconst stashy = new Stashy({\n  id: 'my-stash',\n  logger: pino({ level: 'debug' })\n})\n```\n\n## Credits\n\nThis project was originally developed for [WavePlay](https://waveplay.com).\n\n## License\n\nThe MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwave-play%2Fstashy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwave-play%2Fstashy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwave-play%2Fstashy/lists"}