memorio
v4.2.1
Published
Memorio, State + Observer, Store and iDB for an easy life - Cross-platform compatible
Maintainers
Readme
memorio
State management that actually makes your life easier. Zero friction. Zero bloat. Single import. Works everywhere JavaScript runs.
Get Started · API Reference · License: MIT
Why memorio?
| | memorio | Redux | Zustand | |---|---|---|---| | Setup | 1 import | Boilerplate hell | Moderate | | Dependencies | Zero | Many | Few | | TypeScript | ✅ Native | ✅ | ✅ | | Binary storage | ✅ Built-in IDB | ❌ Add-on | ❌ | | Observer | ✅ Built-in | ❌ Add-on | ❌ | | DevTools | ✅ Built-in + dphelper-manager extension | ❌ Extension | ❌ | | Running on the edge | ✅ Workers, Deno | ⚠️ Limited | ⚠️ Limited |
If you need a store on the server. A cache in the edge worker.
Session isolation in Next.js. IndexedDB in a Service Worker.
All from one import, zero configuration.
Features
| | |
|---|---|
| state | Reactive, volatile state — listen with useObserver |
| store | localStorage persistence — survives refresh |
| session | sessionStorage — dies with the tab |
| cache | In-memory cache — fastest read possible |
| idb | IndexedDB with typed tables — structured, persistent, async |
| observer | Object watcher — legacy, still works |
| useObserver | React hook with auto-discovery — drops in |
| devtools | memorio.devtools.inspect() — see everything in console |
| logger | Auto-log every state change with timestamps |
| Session Isolation | Every browser tab, every request: isolated namespace |
| Platform Detection | isBrowser, isNode, isDeno, isEdge |
No Zustand. No Redux. No provider boilerplate. Just import it and start storing.
Installation options
# npm
npm i memorio
# pnpm
pnpm add memorio
# yarn
yarn add memorio
# React peer dep (optional, React ≥ 16.8)
npm i react react-domSetup
// memorio/index.ts — import once at your app entry point
import 'memorio'
// Memory
state.user = { name: 'Sara', role: 'admin' }
state.counter++
state.settings = { theme: 'dark', lang: 'it' }
// Call it "a store" but make it observe automatically
useObserver(
() => { console.debug('user changed:', state.user) },
[state.user]
)That is it.
No context providers. No <Store> wrappers. No action creators.
Import → assign → done.
API Reference
state — Volatile reactive state
Global, Proxy-based, reactive. Access anywhere.
// Set
state.user = { name: 'Sara', role: 'admin' }
state.items = [1, 2, 3]
// Get
const name = state.user.name // 'Sara'
// List all keys
console.debug(state.list) // ['user', 'items']
// Remove one key
state.remove('items')
// Clear all — lock/unlock available for frozen objects
state.removeAll()
state.lock() // freeze everything
state.unlock() // unfreezestore — survives refresh
store.set('preferences', { theme: 'dark' })
const prefs = store.get('preferences') // { theme: 'dark' } or null
store.remove('preferences')
store.removeAll()
console.debug(store.size(), 'chars stored')
console.debug(store.isPersistent) // true → real localStoragesession — dies with tab
session.set('token', 'user-abc-123')
const token = session.get('token') // 'user-abc-123' or null
session.removeAll()cache — In-memory, disappears on refresh
cache.set('temp', computeExpensiveResult())
const result = cache.get('temp') // undefined or the value
cache.clear() // empty it allidb — structured & typed
await idb.db.create('my-db')
await idb.table.create('my-db', 'users')
await idb.data.set('my-db', 'users', { id: 1, name: 'Sara' })
const user = await idb.data.get('my-db', 'users', 1)observer — Object watcher (DEPRECATED)
globalThis.observer('state.user', (newVal, oldVal) => {
console.debug('user changed:', newVal, oldVal)
})useObserver — React observer hook
Available globally after import 'memorio'.
import 'memorio'
function Counter() {
const [, forceUpdate] = useReducer(x => x + 1, 0)
useObserver(forceUpdate, [state.counter])
// State path auto-discovered during render — no manual deps needed
return <div>Count: {state.counter}</div>
}devtools — inspect everything in one call
memorio.devtools.inspect() // pretty-prints state, store, session, cache
memorio.devtools.stats() // { stateKeys, storeKeys, sessionKeys, ... }
memorio.devtools.clear('state')
memorio.devtools.exportData() // JSON snapshot
$state // console shortcut — same as globalThis.stateBrowser Extension Integration: When used with dphelper-manager browser extension, memorio's global state namespace is automatically detected and visualized through a dedicated DevTools panel, providing time-travel debugging and structural guardrails.
logger — track every change
memorio.logger.configure({ enabled: true, logToConsole: true })
memorio.logger.getHistory() // [{ timestamp, module, action, path, value }, ...]
memorio.logger.getStats() // { total, state, set, get, ... }
memorio.logger.exportLogs() // JSON string of all historyPlatform detection
Access via memorio.*:
memorio.isBrowser() // true in Chrome, Firefox, Safari
memorio.isNode() // true in Node.js
memorio.isDeno() // true in Deno
memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
const caps = memorio.getCapabilities()
// { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, ... }Context (multi-tenant)
memorio.createContext('tenant-name')
memorio.listContexts()
memorio.deleteContext('context-id')
memorio.isolate('tenant-name')Cross-Platform
Memorio runs in every JavaScript environment, with automatic fallbacks.
| | Browser | Node.js | Deno | Edge / Workers |
|---|---|---|---|---|
| state | ✅ | ✅ | ✅ | ✅ |
| observer / useObserver | ✅ | ✅ | ✅ | ✅ |
| cache | ✅ | ✅ | ✅ | ✅ |
| store | ✅ localStorage | ⚠️ memory | ⚠️ memory | ✅ localStorage |
| session | ✅ sessionStorage | ⚠️ memory | ⚠️ memory | ✅ sessionStorage |
| idb | ✅ IndexedDB | ❌ | ❌ | ⚠️ |
| devtools | ✅ | ❌ | ❌ | ⚠️ |
Why memory fallbacks on the server? There is no browser.
storeandsessiongracefully fall back toMap. You still get the same API. Samestate, samecache, sameuseObserver. No extra config required.
Security
- Zero production dependencies — no supply chain surprises
- NIST & NSA aligned — enterprise-grade security standards
- No
eval, no obfuscation, no hardcoded secrets - All inputs validated, keys sanitized, errors caught
- Secure random session IDs via
crypto.randomUUID - MIT license — full audit trail on
SECURITY.md
License
MIT © Dario Passariello
