# I want to know Best Practices for State Management in Aurelia

**URL:** <https://discourse.aurelia.io/t/i-want-to-know-best-practices-for-state-management-in-aurelia/5530>\
**Category:** Framework Knowledge\
**Created:** [August 27, 2024, 10:48am UTC](https://discourse.aurelia.io/t/i-want-to-know-best-practices-for-state-management-in-aurelia/5530 "2024-08-27T10:48:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![gwennadf](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/gwennadf/32/2548_2.png) [@gwennadf](https://discourse.aurelia.io/u/gwennadf)\
**Post date:** [August 27, 2024, 10:48am UTC](https://discourse.aurelia.io/t/i-want-to-know-best-practices-for-state-management-in-aurelia/5530/1 "2024-08-27T10:48:14Z")

</div>

Hello All Community Member,

I am working on a project where effective state management is crucial and I want to ensure that I am using the most efficient and maintainable approach.

What are the recommended strategies for state management in Aurelia? Are there any design patterns or architectural principles that work particularly well with Aurelias ecosystem??

There are any third party libraries or plugins that integrate well with Aurelia for state management? 🤔

Also, I have gone through this resorse/artical; [https://discourse.aurelia.io/t/best-practices-for-aurelia-state-management](https://discourse.aurelia.io/t/best-practices-for-aurelia-state-management/300)[minitab](https://www.igmguru.com/blog/what-is-minitab-features-benefits) which definitely helped me out a lot.

My last question is How do you manage complex or deeply nested states in Aurelia applications? Are there specific techniques or tools that you use to keep state management manageable and performant?

Thank you in advance for your help…!!

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [August 30, 2024, 2:13pm UTC](https://discourse.aurelia.io/t/i-want-to-know-best-practices-for-state-management-in-aurelia/5530/2 "2024-08-30T14:13:40Z")

</div>

This is from what I know, it’s likely lacking and improper in different ways, but I’ll just share, in case it helps motivate someone who knows better feel like rectifying and providing a better perspective. I also assume your app will mostly be dealing with not too sophisticated data, so the example can be kept simple.

* * *

From my experience, which is limited, I can start by asking myself: “do I want to be able to test my state without running any UI related code?”

- If the answer is yes, then it’s likely that I’ll group my state related code in a separate area, almost like a library inside my application so that UI will only be calling to do queries/subscribe to changes/request mutation.

- If the answer is no, then I think I may follow one of the two approaches below:

* * *

Extra: in both of the apollo examples above, the apollo client registration is like this

```ts
const client = (() => {
  const authProvider = resolve(IAuthProvider);
  const authLink = setContext(async (_, { headers, env }) => {
    // get the authentication token from local storage if it exists
    const token = await authProvider.getToken();
    // return the headers to the context so httpLink can read them
    return {
      headers: {
        ...headers,
        // some extra headers depends on needs
        ['x-env']: env ?? '',
        authorization: token ? `Bearer ${token}` : "",
      }
    }
  });

  return new ApolloClient({
    link: authLink.concat(new HttpLink({
      uri: '/graphql',
      credentials: 'same-origin'
    })),
    cache: new InMemoryCache(),
  });
})();

Aurelia.register(
  Regisration.instance(IGraphqlClient, client),
  ...
)

```

I’ve done only simple things, so I’ve only got simple suggestion/usages to share. If it’s of no help, then maybe this will help motivate some more comments.

---

<div class="post-metadata">

**Author:** ![dwaynecharrington](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/dwaynecharrington/32/11_2.png) [@dwaynecharrington](https://discourse.aurelia.io/u/dwaynecharrington)\
**Post date:** [December 17, 2024, 11:58pm UTC](https://discourse.aurelia.io/t/i-want-to-know-best-practices-for-state-management-in-aurelia/5530/3 "2024-12-17T23:58:54Z")

</div>

Throwing my 2c in here as I’ve gone down many paths of state management in Aurelia over the years. While tools like `aurelia-store`, `@aurelia/state` (if you’re using Aurelia 2) and Redux are awesome for some things, I’ve seen them overused, and sometimes they just add a bunch of extra work for not much gain.

Honestly, for a lot of projects, a simple singleton class can handle state just fine. You basically create a class that holds your app’s data, and then you can inject it anywhere you need it.

Here’s a quick example:

```js
export class AppState {
  someValue = 'initial value';
  someOtherValue = 0;

  updateSomeValue(newValue) {
    this.someValue = newValue;
  }

  incrementOtherValue() {
    this.someOtherValue++;
  }
}

```

Super simple, right? You lose things like undo/redo and time-travel debugging, but let’s be real, how often do you _actually_ need those?

If you do want the ability to track state, you can actually write some simple code to do this without additional libs or config:

```js
export class AppState {
  private history: any[] = [];
  private historyIndex: number = -1;
  public someValue: string = 'initial value';

  constructor() {
    this.saveState(); // Save initial state
  }

  updateSomeValue(newValue: string) {
    this.someValue = newValue;
    this.saveState();
  }

  private saveState() {
    // Truncate history if we've undone and then made a new change
    this.history = this.history.slice(0, this.historyIndex + 1);
    this.history.push({ someValue: this.someValue });
    this.historyIndex++;
  }

  canUndo() {
    return this.historyIndex > 0;
  }

  undo() {
    if (this.canUndo()) {
      this.historyIndex--;
      this.someValue = this.history[this.historyIndex].someValue;
    }
  }

  canRedo() {
    return this.historyIndex < this.history.length - 1;
  }

  redo() {
    if (this.canRedo()) {
      this.historyIndex++;
      this.someValue = this.history[this.historyIndex].someValue;
    }
  }
}

```

To use it, you’d just inject it:

```ts
import { inject } from 'aurelia-framework';
import { AppState } from './app-state';

@inject(AppState)
export class MyComponent {
  constructor(private appState: AppState) {}

  updateValue() {
    this.appState.updateSomeValue('new value!');
  }

  undo() {
    this.appState.undo();
  }

  redo() {
    this.appState.redo();
  }

  get canUndo() {
      return this.appState.canUndo();
  }

  get canRedo() {
      return this.appState.canRedo();
  }
}

```

This only tracks one property, but it shows you how to implement these things inside a singleton. If you need advanced state tracking, you could throw in RxJS to make it a bit nicer. The `aurelia-store` plugin in v1 uses RxJS and a `BehaviorSubject` for state. So at that point you’d probably be better off using an Aurelia lib instead of rolling your own.

One HUGE thing: **don’t use state management for temporary stuff** like form data or UI state. Trust me, it’s a nightmare. Aurelia’s built-in data binding is perfect for that kind of thing.

I worked on a big Aurelia project where we went all-in on state management, and it ended up being a huge pain. We spent so much time just dealing with the extra complexity. We eventually ripped it out, and the codebase became way easier to manage. We switched to singletons (one for each data type) and then leveraged localStorage for caching, getters/setters for controlling access to the data and how it’s read and written.

So, before you jump into a full-on state management solution, think about if you really need it. Start simple, and only add the complexity if you absolutely have to. You might be surprised how far a simple singleton can take you.
