Keeping Browser Recordings Compatible in IndexedDB A developer building Pianory, a browser-based piano practice app, implemented an IndexedDB recording store that saves audio as an ArrayBuffer and reconstructs a Blob on read while still accepting legacy rows stored as Blobs. The save path converts bytes before opening a single readwrite transaction so metadata and audio commit together, aborting on quota failure rather than leaving a metadata row pointing to missing audio. Mocked-storage tests covering save, read, export and quota rollback passed 11 tests across two files, though the developer notes they do not reproduce a Safari failure or prove behavior in every browser. I build Pianory, a browser-based piano practice app. AI helped draft this article; I checked the claims against the recording-store source and its focused tests. A browser recording can have metadata and audio bytes that need to move together. Our IndexedDB store saves the audio as an ArrayBuffer and reconstructs a Blob when reading it. The code also accepts legacy rows whose audio was stored as a Blob, so an older local recording remains readable through that path. The save path obtains the bytes before opening the transaction. Then it puts metadata and audio in one readwrite transaction. On quota failure, the transaction aborts instead of leaving a metadata row that points to missing audio. This is a practical boundary: asynchronous byte conversion should not stretch the lifetime of an IndexedDB transaction. The tests cover save, read and export behavior, plus a quota failure that leaves no metadata row. pnpm exec vitest run src/lib/recordings/store.spec.ts src/lib/input/detector.spec.ts passed 11 tests in two files on 31 October 2026. These mocked-storage tests support the round-trip and rollback claims; they do not independently reproduce a Safari failure or prove behavior in every browser. The product lesson is to define both the current storage format and the old rows you still need to read. Source: src/lib/recordings/store.ts and src/lib/recordings/store.spec.ts .