Most "simple" productivity apps want an account before you can write one line. I wanted the opposite: open a page, start typing, close the tab, and find everything still there tomorrow, without a server ever seeing it.
Here's the small pattern I used for a set of free browser apps on Toolverse.
1. Save on every change, debounced
let t;
function save(state){
clearTimeout(t);
t = setTimeout(() => localStorage.setItem('journal-v1', JSON.stringify(state)), 400);
}
A 400 ms debounce keeps typing smooth and still feels instant.
2. Version your key
Using journal-v1 instead of journal means you can migrate the shape later without breaking old saves.
3. Load defensively
function load(){
try { return JSON.parse(localStorage.getItem('journal-v1')) || {entries: []}; }
catch { return {entries: []}; }
}
Corrupted or hand-edited storage should never crash the app.
4. Give people an export button
localStorage is per-browser. A one-click JSON export (a Blob plus a download link) lets people back up or move their data, which matters more than any sync feature.
5. For secrets, encrypt first
For the password manager I used the Web Crypto API (PBKDF2 to derive a key, AES-GCM to encrypt), so only ciphertext ever touches storage.
Try them
- Online journal: https://www.toolverse.world/2026/10/online-journal-free-private-diary-in.html
- Daily planner: https://www.toolverse.world/2026/10/online-planner-free-daily-planner-with.html
- Grocery list: https://www.toolverse.world/2026/10/grocery-list-free-online-shopping-list.html
- Meal planner: https://www.toolverse.world/2026/10/meal-planner-free-weekly-meal-plan-and.html
- Offline password manager: https://www.toolverse.world/2026/10/password-manager-free-offline-encrypted.html
Open one, add something, reload, and it's still there. Feedback on the pattern is welcome.
Top comments (0)