Enduring Stash

Simple promise-based client-side persistence that supports multiple storage providers.


Current Version: 0.1.0 (beta)

Contribute on Github

Download now

Multiple providers

IndexedDB, WebSQL, LocalStorage, SessionStorage, Cookies and in-Memory.

Automatic provider selection

Load the providers you want to use, and it will choose the first one that is available on that platform.

Minimal configuration

No schemas to define, sizes to set or settings to tweak.

Simple API

Get, Set, Add, Update, Remove, GetAll and Contains. All values set and retrieved by key.

Many data types

Not just strings, numbers and booleans, but also dates, arrays and complex objects.


Add functions return a promise with the result (if any). Makes it nice and simple to use all the providers in a uniform way.


Can plug in additional providers to make use of other data storage technologies in future.


Full suite of unit tests: run the tests now.


simply handles storage and retrieval so no extra overhead of features you may not need.

Getting Started

  1. Include a promise framework. Currently Q and jQuery are supported (I recommend Q).
  2. Include enduring-stash.js
  3. Include the storage providers you want to use.  Enduring Stash will select the first supported provider it finds, so the order matters.

<script src="q.min.js"></script>
<script src="enduring-stash.min.js"></script>
<script src="WebStorage.provider.js"></script>

Create a new Enduring Stash:

var settings = new enduring.stash();

Or, create a new named Enduring Stash:

var people = new enduring.stashOf('people');


If you want to try out the samples below, you should use Developer Tools to view the values of HTML Local Storage. Don't forget to refresh after a change.

Set a value

Set adds a value if it doesn't exist, updates it if it does

settings.set("Username", username);

var person = { name: "Pat Lee", id: "PL001" };
people.set(person.id, person);

Get a value

Get returns a promise. When the promise is resolved, the value is provided as parameter to the success callback. If the value doesn't exist, the promise will be resolved, but the value will be undefined. The promise will only be rejected if some error condition occurred.

.then(function (result) {
.then(function (person) {

Add a value

Adds a value if it doesn't exist. It returns a promise so you can check the returned value to see whether the add succeeded. If it succeeded, the promise resolves with the value returned as data. If an item with the same key already exists, the promise is rejected.

settings.add("FavouriteColour", "blue");
settings.add("FavouriteColour", "red");
// Favourite colour is blue, adding a second value does not overwrite the first one

Update a value

Update a value if it already exists. It returns a promise, so you can check the return value to see whether the update succeeded. If it succeeded, the promise resolves with the value returned as data. If the item doesn't exist in the store, the promise is rejected.

settings.add("FavouriteColour", "blue");
settings.update("FavouriteColour", "red");
// Favourite colour is now updated to red
settings.update("YearsOfExperience", 2);
// YearsOfExperience is not saved because it was not previously added


Returns true or false indicating whether an item with that key exists or not.

	.then(function(itemExists) {
		if (itemExists) {
			$(".try-contains-message").html("FavouriteColour exists")
		} else {
			$(".try-contains-message").html("FavouriteColour does NOT exist")


Returns an array of ALL values in the stash. Well, technically it doesn't 'return' it. The array of values is available as a parameter in the success callback. .

.then(function (result) {


Removes an item from the stash.

	console.log("FavouriteNumber removed");


Clears out everything in the stash.

.then(function () {
	console.log("Stash emptied");


Does the world really need another client-side persistence library?

Probably not. But I did. Don't get me wrong - there are plenty of good ones out there. If nosql is your thing, try lawnchair. If you need something a bit more industrial-strength, give JayData or Breeze.js a try. Or look around on GitHub, there are plenty of them.

None of them quite did what I needed in a couple of projects, though, so I peekend into their their source code and came up with my own blend that suited exactly what I needed. Maybe it will work for you too.


This project is open source, licenced under GPL v2.


This project is maintained by Sarah Henderson.