Skip to main content


Dependency-free state management library

| GitHub | Examples | Awai-React |

This library suggests an architectural approach, where every event is a promise-like (thennable) AwaiEvent with no terminal state.

AwaiEvent is a fundamental part of this library. It can re-resolve infinite amount of times, and if you await it in a loop, you have an event listener replacement.

Awai provides variety of nodes which were design to help with handling complex logics. Every Awai node has its events, which can be mixed into any async logics, or used as trigger for Scenarios.

Scenario is a powerful helper which helps to describe complex logics and events sequences using async functions.

Awai helps with organizing asynchronous logics and handling race conditions with ease, and it's main goal is to completely extract business logics from UI layer.


npm install awai

How AwaiEvent works

You are not likely to use it directly, the code is just for demonstration purposes.

const event = new AwaiEvent();

setTimeout(() => event.emit('hello'), 100);
setTimeout(() => event.emit('awai'), 200);

const value1 = await event;
const value2 = await event;

console.log(`${value1} ${value2}`); // hello awai

Basic example

Todo list state management
import { action, state } from 'awai';
import { getUniqueId } from './utils';

export const tasksState = state([]);

export const createTask = action((title) => {
tasksState.set((tasks) => [
{ id: getUniqueId(), isCompleted: false, title },

export const deleteTask = action((id) => {
tasksState.set((tasks) => tasks.filter((task) => !== id));

export const toggleTaskIsCompleted = action((id) => {
tasksState.set((tasks) => {
return => {
return === id
? { ...task, isCompleted: !task.isCompleted }
: task;


Name meaning

The name comes from a Thai phrase เอาไว้ which means "to keep/save/store for later".