Store a Small List


Most applications keep a list the user adds to and edits later, such as todos, notes, saved records or an activity log. The whole list can live in one key-value entry as an array, so you read all of it with a single puter.kv.get() call, without pagination.

Add an Item

To add an item to the end of the list, use the puter.kv.add() method and wrap the item in an array:

await puter.kv.add('todos', [{ text: 'Buy milk', done: false }]);

If the key does not exist yet, it is created as an array. The append is atomic, so two concurrent calls both add their item.

To add several items, put them all in the array. Each element is appended as a separate item:

await puter.kv.add('todos', [
    { text: 'Walk the dog', done: false },
    { text: 'Call mom', done: false },
]);

Show the List

To load the list, use the puter.kv.get() method. One read returns every item in the order it was added, so you don't need an additional field for sorting. A list that was never written comes back as null, so default it to an empty array:

const todos = await puter.kv.get('todos') ?? [];

Edit an Item

To change one field of one item, use the puter.kv.update() method with a path made of the item's index in brackets, then the field name. This marks the first todo as done:

await puter.kv.update('todos', { '[0].done': true });

The index is the item's position in the array you read with puter.kv.get(). To edit an item you know by a field value, find its index first:

const todos = await puter.kv.get('todos') ?? [];
const index = todos.findIndex((todo) => todo.text === 'Buy milk');

await puter.kv.update('todos', { [`[${ index }].done`]: true });

To replace the whole item, use the index on its own:

await puter.kv.update('todos', { [`[${ index }]`]: { text: 'Buy oat milk', done: false } });

Delete an Item

To remove an item, use the puter.kv.remove() method with its index in brackets:

await puter.kv.remove('todos', `[${ index }]`);

Every item after it moves down by one index. To delete several items, pass all their indexes in one call, such as remove('todos', '[0]', '[3]'). The indexes in one call refer to the list as it was before the call.

Because indexes shift, a list edited from two tabs or devices at once can go wrong. After one tab deletes an item, the other tab still has the old indexes and can edit or delete the wrong item. In that case, store items by ID instead, where each item has a fixed ID.

When to Switch

One entry holds up to 400 KB, which is a few thousand small items. If your list holds more than that, or you expect it to, store a large collection instead, which gives you:

← All recipes