# \[Feedback Wanted\]: Save change history to session storage

**URL:** <https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542>\
**Category:** Core Development\
**Tags:** editor\
**Created:** [30 October 2025 15:32 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542 "2025-10-30T15:32:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [30 October 2025 15:32 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/1 "2025-10-30T15:32:27Z")

</div>

Hi all,

I would like your opinion on the possibility of integrating a mechanism into NR that saves the change state (history).

The goal is to avoid losing or having to deploy work in progress.

If you're working and you refresh the editor, you lose your change history. I'd like to make it persistent. It will be possible to restore the history or not.

The API could be opened to plugins to add their state to the storage.

The storage would be configurable in the settings.

Thank you for your feedback.

cc @AllanOricil

---

<div class="post-metadata">

**Author:** ![AllanOricil](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/allanoricil/32/106911_2.png) [@AllanOricil](https://discourse.nodered.org/u/AllanOricil)\
**Post date:** [30 October 2025 15:37 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/2 "2025-10-30T15:37:28Z")

</div>

Definitely a must have feature. Grid outages happen quite often in my city and i dont want to lose my undeployed work due it

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [30 October 2025 15:55 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/3 "2025-10-30T15:55:37Z")

</div>

Sounds like an interesting idea.

Personally, I would prefer such a feature to use the existing context storage library for sure, not have yet another one. You would maybe want to think about controlling how many versions are retained (should be user selectable with a sensible default).

As an alternative though, why not just extend the current flow backup feature to allow more than a single backup file? A setting in settings.js could be used to restrict the number with the default at 1 in line with the current feature.

---

<div class="post-metadata">

**Author:** ![AllanOricil](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/allanoricil/32/106911_2.png) [@AllanOricil](https://discourse.nodered.org/u/AllanOricil)\
**Post date:** [30 October 2025 15:59 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/4 "2025-10-30T15:59:24Z")

</div>

This feature is about client-side state management.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [30 October 2025 16:02 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/5 "2025-10-30T16:02:13Z")

</div>

Yes, I know. EDITOR client.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [30 October 2025 18:01 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/6 "2025-10-30T18:01:50Z")

</div>

I very often find that I have broken something and not noticed, so I end up pressing ctrl-z many times.  
It's an excellent idea to improve this 'backup stack', relying on the browser's cache is distinctly iffy.  
.  
Some ideas I've considered:

- More flow backup files as Julian says. I'd want to retain these for a configurable duration, up to a day.
- A backup should include the entire tab which is marked dirty but not the entire flow file? **Edit** - one backup file per dirty tab
- An option on Deploy to give the deployment a name to which one might want to revert.
- Backups would have a sequential id, timestamp and [optional] name. **Edit** - and the name of the tab backed up.
- Some method to choose a backup to revert to.
- Reverting to a backup should be reversible if it turns out not to be the one where I broke the code.

ps When one does a ctrl-z to undo a change, the Deploy button correctly lights up but the nodes rolled back do not acquire a blue dot. It would be helpful if they did.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [31 October 2025 09:21 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/7 "2025-10-31T09:21:31Z")

</div>

Hehe - that's why I use - yes my own creation - [flowhub.org](http://flowhub.org) so that I can push out progress to github. The flowhub plugin works by sending my in-browser flow to a github repository without having to deploy the flow. (I guess I could add "save automatically every X mins" feature to get it do that automagically.)

But that's not a solution to the automatic storage of any changes in the client, it's more an approach that I take. I regularly send my in-browser changes to github (via flowhub). So github acts as storage and not a "this code is complete and working" tool.

Plus working on a laptop, I have plenty of time to react to power outages.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [31 October 2025 11:01 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/8 "2025-10-31T11:01:16Z")

</div>

I think this could actually be automated using a _flow_ even without other changes. A watch node to look for changes to the flows json file, a delay node to debounce since filing system changes can be a bit noisy, then an exec node to do a git update (or you could simply do a file copy).

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [31 October 2025 11:15 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/9 "2025-10-31T11:15:15Z")

</div>

> [@TotallyInformation](#):
>
> I think this could actually be automated using a _flow_ even without other changes.

Not really since we're talking about in-browser flows - the on the server side flows, certainly, that could be automated using a change node.

Which reminds me that my backup-flow flow uses crontab an is triggered every 15 mins! Ok, perhaps a change node would be better!

---

<div class="post-metadata">

**Author:** ![AllanOricil](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/allanoricil/32/106911_2.png) [@AllanOricil](https://discourse.nodered.org/u/AllanOricil)\
**Post date:** [31 October 2025 11:51 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/10 "2025-10-31T11:51:33Z")

</div>

@GogoVega

Storing the history in Session Storage is not aligned with the goal of persisting the "undeployed state" locally. Session Storage is cleared as soon as the browser tab closes or the system restarts, meaning users would lose in-progress work during crashes or power outages. Instead, the undeployed state must be stored in persistent local storage (e.g., IndexedDB or Local Storage).  
We do not need to persist the entire history locally — only the latest in-progress state, since that’s what users expect to recover if their environment unexpectedly shuts down.  
This persistence should also be keyboard-driven (e.g., Ctrl+S), consistent with common productivity software behaviors, reinforcing a sense of control and reliability.

#### Definition — Undeployed Flow State

Represents work-in-progress that is not yet finalized or ready for deployment/versioning. Its purpose is to ensure users can safely resume editing after browser crashes, OS failures, or power outages, without risking data loss.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [31 October 2025 12:47 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/11 "2025-10-31T12:47:31Z")

</div>

> [@AllanOricil](#):
>
> This persistence should also be keyboard-driven (e.g., Ctrl+S),

I remapped Ctrl-D to Ctrl-S because for me, deploying was/is like saving 😉

> [@AllanOricil](#):
>
> persistent local storage (e.g., IndexedDB or Local Storage).

How hard is it for a web-page inside a browser to write to disk? Sure I can do Ctrl-S and save the web-page as a web-page but can I write a file to disk based on a user action? I ask since I am not up-to-date with browser technology.

You would probably end up using something like a download triggered via a user action. I.e. like the "Download" button on the export flow overlay - to have this feature work across all browsers and all OSes.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [31 October 2025 12:47 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/12 "2025-10-31T12:47:32Z")

</div>

> [@gregorius](#):
>
> Not really since we're talking about in-browser flows - the on the server side flows, certainly, that could be automated using a change node.

Ah, I see. Personally, I'm only interested in what happens when `deploy` is used as that is the direct equivalent of a "save". Since most things in Node-RED don't actually change _until_ you've done a deploy, I don't see much value in creating something complex to try and capture in-flight changes. You can always do ctrl-z a few times anyway. Or reload the Editor page to reset.

> [@AllanOricil](#):
>
> We do not need to persist the entire history locally

But surely, that is actually what most people DO want! As mentioned, changes between `deploy` being used are no different to changes to a document between saves.

In-flight, un-deployed changes typically are not very many anyway since Node-RED doesn't change process until deployed.

While it might be nice to have un-deployed changes recorded, I would think that such a feature wouldn't often be used.

I'm not necessarily against that idea but I worry about added complexity.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [31 October 2025 12:48 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/13 "2025-10-31T12:48:43Z")

</div>

> [@gregorius](#):
>
> How hard is it for a web-page inside a browser to write to disk

very hard! Deliberately so as it is a potential security nightmare.

However, the browser does, of course, have its own storage - though you do have to watch out for size limitations.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [31 October 2025 12:55 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/14 "2025-10-31T12:55:14Z")

</div>

> [@TotallyInformation](#):
>
> However, the browser does, of course, have its own storage - though you do have to watch out for size limitations.

But as @AllanOricil said, that storage is wiped upon restart.

> [@TotallyInformation](#):
>
> In-flight, un-deployed changes typically are not very many anyway since Node-RED doesn't change process until deployed

This use-case is specifically for folks who make large changes (e.g.. refactorings) but want to save these _without_ deploying and changing the server.

I and probably you, don't work that way. I deploy my changes fairly rapidly or - as I described above - push them off to github. But others are stuck between leaving the browser open or deploying and hoping nothing breaks.

This use-case is a particular one to developers of large and complex flows that are required to work and can't just break. How do you address the problem of making changes that take several days to complete, i.e. your browser has to stay open and the deploy button isn't allowed to be pressed.

EDIT: P.s. this use-case is specifically why I created [flowhub.org](http://flowhub.org) and also the [flow compare](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-flowcompare) plugin - to be able to track changes, _without_ deploying and changing the server.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [31 October 2025 13:02 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/15 "2025-10-31T13:02:21Z")

</div>

By session, I meant per user.

The concept is as follows:

Each time the history changes, its state is saved to a storage. This storage maintains the individual state for each logged-in user. The storage is persistent and modifiable in the settings.

If a user leaves a dirty workspace for any reason, his state will be restored, if the user agrees, at the next session.

Optionally, the user can choose to automatically restore the history, in this case a clean workspace containing a history will also be restored. Which means that undo will do its job.

History = CTRL-Z and CTRL-Y.

I don't see the point of using CTRL-S; if your app crashes, a recovery mode opens.

> [@TotallyInformation](#):
>
> context storage library

This is the fastest way to approach the functionality, but I'm not sure it's the most optimal. As a reminder, the history state changes with each manipulation.

---

<div class="post-metadata">

**Author:** ![AllanOricil](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/allanoricil/32/106911_2.png) [@AllanOricil](https://discourse.nodered.org/u/AllanOricil)\
**Post date:** [31 October 2025 13:14 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/16 "2025-10-31T13:14:56Z")

</div>

Users don’t version every small change they make to their flows in Git — they only commit meaningful milestones. Node-RED already supports this by allowing users to Deploy when they want to save a new milestone to the server’s data storage. That’s a reliable safety net after the user explicitly decides the work is ready.  
But there’s a gap: users often have **work in progress** — messy, experimental, not-ready-to-deploy changes. If something goes wrong (browser crash, tab closed, laptop dies), that work is gone. No deployment means no persistence.  
This is why we need a local history backup feature in the client.  
It continuously stores the latest working state in the browser (like VS Code autosave). It’s not a full version control system. It’s not undo/redo history. It’s just a “break glass if needed” backup so users don’t lose unfinished work.

To make it painfully simple:

| Feature | What it does | When it helps | What it does _not_ do |
| --- | --- | --- | --- |
| ✅ Deploy (existing) | Saves a _milestone_ to the server | When the change is ready and intentional | Doesn’t protect draft changes |
| ✅ Local history backup (new) | Saves the most recent draft locally | When the browser or session crashes | Doesn’t allow stepping back through history (Ctrl+Z) |
| ❌ Full history snapshots | Stores every action for revert | Not needed here | Too heavy, not the goal |

Bottom line:  
**Deploy protects progress you meant to keep. Local backup protects progress you didn’t expect to lose.**

No illusions. No over-engineering. Just resilience where it’s actually needed.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [31 October 2025 13:22 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/17 "2025-10-31T13:22:46Z")

</div>

Sorry, I can't actually tell from @GogoVega's clarification what will be stored and where.  
As shown by my post before, I'm very enthusiastic about improving the process of rolling back deploys.

> [@GogoVega](#):
>
> The goal is to avoid losing or having to deploy work in progress.
> 
> If you're working and you refresh the editor, you lose your change history. I'd like to make it persistent.

> [@AllanOricil](#):
>
> #### Definition — Undeployed Flow State
> 
> Represents work-in-progress that is not yet finalized or ready for deployment/versioning. Its purpose is to ensure users can safely resume editing after browser crashes,

Ah. Saving undeployed changes if the browser crashes: totally useless for me (but I agree, not useless for Allan in a land of powercuts)

Still, knock yourself out if it's something users expect. Maybe it's more important for someone working on a cloud based Flowfuse instance?

---

<div class="post-metadata">

**Author:** ![AllanOricil](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/allanoricil/32/106911_2.png) [@AllanOricil](https://discourse.nodered.org/u/AllanOricil)\
**Post date:** [31 October 2025 13:52 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/18 "2025-10-31T13:52:36Z")

</div>

> [@jbudd](#):
>
> but I agree, not useless for Allan in a land of powercut

It is not only in power outages. Browser can crash, app can crash, OS can crash, NR server could he unavailable. Vscode has a restoring mechanism for unexpected crashes. Node-RED does not. All modern webapps has some state managent for this exact scenario

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [31 October 2025 14:33 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/19 "2025-10-31T14:33:39Z")

</div>

Sorry,

I'll use an example to explain better.

Let's say you open a clean editor and add an inject node, then a debug node, then wire nodes, and finally edit the inject node.

The history will be: [add, add, add, edit] (add inject, add debug, add link, edit node)

The goal of this is to store this history so that a user can restore it, whether because the editor was closed abruptly or the user switched sessions... I don't care.

In short, to restore the editor from the previous session.

Whether the choice of storage, the choice to restore automatically, or the choice to restore across multiple sessions and the history depth will all be configurable.

Technically, the full history since the last deployed version must be kept to accurately restore the editor from the previous session.

We won't discuss snapshots (like FF does) here; that's not the purpose.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [31 October 2025 14:34 UTC](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542/20 "2025-10-31T14:34:13Z")

</div>

> [@gregorius](#):
>
> > [@TotallyInformation](#):
> >
> > However, the browser does, of course, have its own storage - though you do have to watch out for size limitations.
> 
> But as @AllanOricil said, that storage is wiped upon restart.

Not so. There are several types of browser storage and some certainly persists across browser restarts. For the feature we are now talking about (in-flight, un-deployed changes in the Editor), this would be my preferred approach.

The browser `navigator.storage.persist()` API method asks the user if they will allow the page to persist storage.

[Next page](https://discourse.nodered.org/t/feedback-wanted-save-change-history-to-session-storage/99542.md?page=2)
