Hey HN! Wanted to share a new library and server I've recently been working on called remoteStorage.<p>When building frontends with Javascript, the native localStorage API is super useful for keeping track of state between sessions in the same browser, but it's not as good a solution when your data needs to be shared across multiple devices or browsers.<p>For instance, let's say you want to show a welcome modal to all new users that sign up for your product. If you use localStorage to track if a user has already seen this modal, your users will end up getting the experience repeatedly every time they switch devices or browsers, or whenever Chrome decides to nuke your data.<p>I built remoteStorage to help fix that. Using the same API as localStorage, remoteStorage allows you to easily read and write data on the fly while maintaining state across browsers and devices in order to provide a better user experience.<p>The project is built as a monorepo in Typescript and contains a JS library that works across any Javascript stack (including Node.js and React Native) and is lightweight (~1 kb minified). The server is built with Nest.js with a disk-persisted Redis Database. It can be deployed in a few minutes using Docker.<p>One of the biggest challenges when building this was coming up with a secure scheme for handling authentication while still keeping the API dead simple for frontend devs to use. While the project is intended to store non-sensitive data like impression events/preferences, I still wanted to make sure data couldn’t easily leak or be tampered with.<p>One solution has been to generate a unique secret UUID per user on your own backend to identify the user. Alternatively, you could create a simple wrapper/proxy API around remoteStorage that uses your own authentication method to verify the user's identity before allowing them to access the data (this is super simple to build with React Server Components). Then, you could pick a secure and secret Instance ID that is not publicly available to ensure that only your application can access the data.<p>Has anyone felt the same pain points with localStorage before? Is this solution useful? Let me know what you think or ideas for how I can improve it :)
Your landing page at <a href="https://remote.storage/" rel="nofollow">https://remote.storage/</a> is so good, I love the minimalism. Six lines of code tell me exactly what it does.
The bit about finding a unique ID for the user is the whole pain point though. The only way to do that really is for the user to create an account on some service that I host. And if I have that, I probably have my own hosted data storage anyway.
Very cool overall but the sync->async change means you can't always use it as a drop-in replacement. I assume it's making network calls in those cases which will take significantly longer that local writes. I wonder if something could be done so that it write the data locally and kicks off something async in the background to sync it up to the backend. Maybe with just a timestamp in case you go offline to handle conflicts (or even way to register a callback if there is a conflict so you can decide how to handle it). I know that all makes this more complicated but I'd be worried about adding waiting for a network call where I currently do localStorage calls.<p>But still a very cool project, thank you for sharing!
At first I got confused, because i thought this was a refreshed version of <a href="https://remotestorage.io" rel="nofollow">https://remotestorage.io</a> ....but, i see now that its different/separate.
On the authentication front - JWTs would be a great fit here!<p>The developer's backend could issue a JWT, which is validated by the remoteStorage backend. Then, use the `sub` field as the user ID. JWTs are pretty ubiquitous in frontend applications, so many people would be able to reuse their existing auth setup.
> Has anyone felt the same pain points with localStorage before?<p>For Sandstorm, we've always want to make sure app data is stored on a server, but an increasing number of web apps love to use localStorage as a cheap hack to avoid writing a backend. I recall a bunch of attempts back in the day, but we were always looking for a simple way to include something with an app written to use localStorage which could store the data on a server backend instead.
How are the conflicts resolved?<p>Machine A is online and sets "x" to 1.<p>Machine B is offline and sets "x" to 2.<p>Machine B goes online.<p>What the resulting state on A and on B?<p>What if initially A was offline and B was online?
I love the simplicity and kinda wish that was actually built into Chrome.<p>I know it would probably break things but if Google could automatically sync local storage and IndexedDB when I'm signed into Chrome on all my devices then a lot browser of apps wouldn't require making an account or even a server for that matter.
What if you assigned each user a unique ID, used this to determine the user session data and persisted this data in a server that was accessible by both web browsers. You could authenticate yourself against this user id by means of a secret only this user knows<p>It sounds a bit radical but it may work!
If you rewrite the server in Deno you can remoteStorage the data in localStorage!<p><a href="https://docs.deno.com/runtime/manual/runtime/web_storage_api" rel="nofollow">https://docs.deno.com/runtime/manual/runtime/web_storage_api</a>
Cookies or passkeys? Seems very complex when you can use something simply to track state and identity. Passkeys sync across cloud storage, for example, even if you’re using a uuid as the username.
I think you should give an API specification so that people don’t bother using public API or hosting another service could implement it directly in the existing backend.
> let's say you want to show a welcome modal to all new users that sign up for your product.<p>Not sure if this is a good example; how many users sign up for the same product multiple times?