How imshihab/esmls works
1. Repository shape
- This is a very small, single-purpose TypeScript library.
- The entire runtime surface appears to live in src/index.ts, with no app, server, or multi-package structure.
- The package is published/consumed as an npm module (esmls).
2. Primary responsibility
- The library is a thin abstraction over the browser’s localStorage API.
- Its job is to provide a safer, more ergonomic key/value store with automatic serialization, deserialization, and change notifications.
3. Public API boundary
- The documented exports are get, set, has, del, and onChange.
- These form the only meaningful external interface; everything else is internal implementation detail.
- Architecturally, this is a utility layer between application code and browser storage.
4. Data flow: write path
- Application code calls set(key, value).
- The library serializes the value into a string form suitable for localStorage.
- The string is written to the browser storage backend under the given key.
5. Data flow: read path
- Application code calls get(key, options?).
- The library reads the raw stored string from localStorage.
- It then deserializes/parses the string back into the original JavaScript type where possible.
- The README shows support for strings, numbers, booleans, dates, arrays, objects, and nested structures.
6. Defaulting and derived state
- get can supply a default value when a key is missing.
- It can also persist that default back into storage when requested.
- The optional withSetter mode returns a value plus a setter closure, which is a convenience boundary for state-like usage.
7. Change propagation
- onChange(key, callback) is the reactive subsystem.
- It listens for storage updates and is explicitly intended to work across browser tabs/windows.
- The cleanup function it returns indicates listener lifecycle management is part of the design.
8. Storage semantics
- has and del are simple key-level utilities around presence checking and removal.
- Together with get/set, they make the library a complete localStorage façade rather than just a serializer.
9. Runtime and environment boundary
- This is a browser-only library because it depends on localStorage and the storage event.
- It is not designed as a server-side component, and SSR would need guarding around access to window/localStorage.
10. Integration style
- The README shows direct vanilla JS usage and a React example, but React is not a dependency of the library itself.
- That means the architecture is framework-agnostic: it can be embedded into any client code that runs in a browser.
11. Build/package tooling
- The presence of tsconfig.json and lockfile indicates a TypeScript-based package build/publish workflow.
- No separate infrastructure, API service, or database is part of the architecture.
12. Diagramming takeaway
- The clean architecture view is:
- App code on one side,
- esmLS library in the middle,
- browser localStorage + storage events as the backing platform on the other side.
- The library’s core value is serialization, typed retrieval, default handling, and cross-tab change observation.
Main entry points: index.ts src/index.ts · README.md README.md · package.json package.json · tsconfig.json tsconfig.json
Components 14
Consumers
Application code that imports and uses the library.
- App code · Any browser-side application using the package.
esmLS
The TypeScript module exposing the storage API and internal helpers.
- src/index.ts · Single runtime entry point for the library.
src/index.ts - get · Reads a key, optionally applying defaults or returning a setter helper.
src/index.ts - set · Serializes and stores a value under a key.
src/index.ts - has/del · Checks presence and removes stored keys.
src/index.ts - onChange · Subscribes to storage updates and returns an unsubscribe cleanup.
src/index.ts - Serialize/parse · Converts between JavaScript values and string storage form.
src/index.ts - Defaults · Applies missing-key defaults and optional persistence/withSetter behavior.
src/index.ts - Storage adapter · Thin boundary around browser storage operations.
src/index.ts
Browser
Browser storage primitives the library wraps.
- localStorage · String key/value persistence backend.
- storage event · Cross-tab/window change notification channel.
Package
Repository metadata and build configuration.
- README.md · Documents the public API and usage patterns.
README.md - package.json · NPM package metadata and entry configuration.
package.json - tsconfig.json · TypeScript compilation settings for the library build.
tsconfig.json
Connections 19
- App code → get: read · Application code requests stored values.
- App code → set: write · Application code persists values.
- App code → has/del: check/remove · Application code inspects or deletes keys.
- App code → onChange: subscribe · Application code listens for updates.
- get → src/index.ts: uses · Public API is implemented in the entry module.
- set → src/index.ts: uses · Public API is implemented in the entry module.
- has/del → src/index.ts: uses · Public API is implemented in the entry module.
- onChange → src/index.ts: uses · Public API is implemented in the entry module.
- src/index.ts → Serialize/parse: calls · Entry module encodes and decodes values.
- src/index.ts → Defaults: calls · Entry module handles missing keys and helper state.
- src/index.ts → Storage adapter: delegates · Entry module delegates storage operations.
- Storage adapter → localStorage: reads/writes · Stores and retrieves string values from browser storage.
- onChange → storage event: listens · Subscribes to browser storage updates.
- storage event → localStorage: reflects · Change notifications correspond to storage mutations.
- README.md → get: documents · README describes read behavior and options.
- README.md → set: documents · README describes write behavior.
- README.md → onChange: documents · README describes cross-tab listeners.
- package.json → src/index.ts: exports · Package entry points to the library module.
- tsconfig.json → src/index.ts: builds · TypeScript compiles the entry module.