Top Related Projects
Quick Overview
NGXS is a state management pattern and library for Angular applications. It provides a simple, modular approach to managing application state, inspired by Redux but designed specifically for Angular's architecture and TypeScript.
Pros
- Strongly typed and Angular-centric, providing excellent integration with Angular's ecosystem
- Simpler boilerplate compared to other state management solutions like NgRx
- Supports plugins for additional functionality (e.g., devtools, logger)
- Offers powerful features like state operators and action handlers
Cons
- Smaller community and ecosystem compared to more established solutions like NgRx
- May introduce unnecessary complexity for smaller applications
- Learning curve for developers new to state management patterns
- Limited documentation and resources compared to more popular alternatives
Code Examples
- Defining a state:
import { State, Action, StateContext } from '@ngxs/store';
export class AddTodo {
static readonly type = '[Todo] Add';
constructor(public payload: string) {}
}
@State<string[]>({
name: 'todos',
defaults: []
})
export class TodoState {
@Action(AddTodo)
add(ctx: StateContext<string[]>, action: AddTodo) {
const state = ctx.getState();
ctx.setState([...state, action.payload]);
}
}
- Dispatching an action:
import { Store } from '@ngxs/store';
import { AddTodo } from './todo.state';
export class TodoComponent {
constructor(private store: Store) {}
addTodo(todo: string) {
this.store.dispatch(new AddTodo(todo));
}
}
- Selecting state in a component:
import { Select } from '@ngxs/store';
import { TodoState } from './todo.state';
import { Observable } from 'rxjs';
export class TodoListComponent {
@Select(TodoState) todos$: Observable<string[]>;
}
Getting Started
-
Install NGXS:
npm install @ngxs/store
-
Add NGXS to your Angular module:
import { NgxsModule } from '@ngxs/store'; import { TodoState } from './todo.state'; @NgModule({ imports: [ NgxsModule.forRoot([TodoState]) ] }) export class AppModule {}
-
Use NGXS in your components:
import { Store } from '@ngxs/store'; import { AddTodo } from './todo.state'; export class TodoComponent { constructor(private store: Store) {} addTodo(todo: string) { this.store.dispatch(new AddTodo(todo)); } }
Competitor Comparisons
Reactive State for Angular
Pros of ngrx/platform
- More mature and widely adopted in the Angular community
- Extensive ecosystem with additional libraries and tools
- Follows Redux pattern closely, beneficial for developers familiar with Redux
Cons of ngrx/platform
- Steeper learning curve, especially for beginners
- More boilerplate code required for setup and implementation
- Can be overkill for smaller applications
Code Comparison
ngrx/platform:
@Effect()
loadBooks$ = this.actions$.pipe(
ofType('[Books] Load Books'),
mergeMap(() => this.booksService.getAll()
.pipe(
map(books => ({ type: '[Books] Load Success', payload: books })),
catchError(() => of({ type: '[Books] Load Error' }))
))
);
ngxs/store:
@Action(LoadBooks)
loadBooks(ctx: StateContext<BooksStateModel>) {
return this.booksService.getAll().pipe(
tap(books => ctx.patchState({ books }))
);
}
The code comparison shows that ngxs/store generally requires less boilerplate and has a more straightforward syntax for defining actions and effects. ngrx/platform, while more verbose, provides a more explicit separation of concerns and follows the Redux pattern more closely.
Simple, scalable state management.
Pros of MobX
- Simpler learning curve and less boilerplate code
- More flexible and unopinionated, allowing for various architectural patterns
- Better performance for complex state updates due to fine-grained reactivity
Cons of MobX
- Less predictable state changes, as mutations are allowed
- Lack of built-in dev tools for time-travel debugging
- Potential for overuse of observables, leading to unnecessary re-renders
Code Comparison
MobX:
import { makeObservable, observable, action } from "mobx";
class TodoStore {
todos = [];
constructor() {
makeObservable(this, {
todos: observable,
addTodo: action
});
}
addTodo(text) {
this.todos.push({ text, completed: false });
}
}
NGXS:
import { State, Action, StateContext } from '@ngxs/store';
export class AddTodo {
static readonly type = '[Todo] Add';
constructor(public payload: string) {}
}
@State<string[]>({
name: 'todos',
defaults: []
})
export class TodoState {
@Action(AddTodo)
add(ctx: StateContext<string[]>, action: AddTodo) {
const state = ctx.getState();
ctx.setState([...state, action.payload]);
}
}
Both MobX and NGXS offer state management solutions, but with different approaches. MobX focuses on simplicity and flexibility, while NGXS provides a more structured, Redux-like pattern with TypeScript support and better integration with Angular applications.
A JS library for predictable global state management
Pros of Redux
- More widely adopted and mature ecosystem
- Framework-agnostic, can be used with any JavaScript application
- Extensive developer tools and middleware support
Cons of Redux
- Steeper learning curve due to its boilerplate and complexity
- Requires more code for simple state management tasks
- Less opinionated, which can lead to inconsistent implementations
Code Comparison
Redux:
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
default:
return state;
}
};
NGXS:
@State<StateModel>({
name: 'counter',
defaults: { count: 0 }
})
@Injectable()
export class CounterState {
@Action(Increment)
increment(ctx: StateContext<StateModel>) {
ctx.patchState({ count: ctx.getState().count + 1 });
}
}
NGXS offers a more declarative and less verbose approach to state management, leveraging TypeScript decorators. Redux, on the other hand, uses pure JavaScript functions and switch statements for reducers, which can be more familiar to developers coming from other ecosystems but may require more boilerplate code.
Business logic with ease ☄️
Pros of Effector
- Lightweight and minimalistic, with a smaller bundle size
- More flexible and less opinionated, allowing for easier integration with existing projects
- Supports TypeScript out of the box with excellent type inference
Cons of Effector
- Less structured approach may lead to inconsistent code organization in large projects
- Smaller community and ecosystem compared to NGXS
- Steeper learning curve for developers used to traditional Redux-like state management
Code Comparison
NGXS:
@State<string[]>({
name: 'todos',
defaults: []
})
@Injectable()
export class TodosState {
@Action(AddTodo)
add({ getState, patchState }: StateContext<string[]>, { payload }: AddTodo) {
patchState([...getState(), payload]);
}
}
Effector:
const todosStore = createStore<string[]>([]);
const addTodo = createEvent<string>();
todosStore.on(addTodo, (state, payload) => [...state, payload]);
The code comparison demonstrates the difference in approach between NGXS and Effector. NGXS uses decorators and classes for state management, while Effector employs a more functional approach with stores and events. Effector's syntax is generally more concise, but NGXS provides a more structured and familiar pattern for Angular developers.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
NGXS is a state management pattern + library for Angular
Quick Links
- ⨠Learn about it on the docs site
- ð¬ Ask a question in our Discord server (we are migrating from our slack server).
- ð See it in action on Stackblitz
- ð Checkout the sample application
- ð§ Scaffolding application using NGXS Schematics
- ð Read the blog posts
- â¡ï¸ Development of NGXS Labs
- ð Learn about updates from the changelog
- â¤ï¸ Give back by becoming a Contributor or a Sponsor
- ð We would love to hear about your experience with NGXS, you can leave your feedback here
The Goal of NGXS
NGXS tries to make things as simple and accessible as possible. There can be a lot of boilerplate code in state management, thus a main goal of NGXS is to reduce boilerplate allowing you to do more things with less. It is also not necessary to be super familiar with RxJs.
The Goal of NGXS Labs
The idea with this github organisation is to provide a place for the community to create libraries that augment the main framework with functionality that does not need to be integrated directly into the framework and therefore can evolve through their initial iterations of experimentation without affecting the main @ngxs/store library.
Getting Started - Local Development
Installation
To get started locally, follow these instructions:
- If you haven't done it already, make a fork of this repo.
- Clone to your local computer using git.
- Make sure that you have installed NodeJS.
- Make sure that you have yarn installed.
- Run
yarn install
. - Run
yarn build:packages
.
Creating new packages or add feature/fix
if you make changes @ngxs/store
- Run development mode
yarn build:packages --package store --watch
- Run serve integration examples
yarn start
- ...development...
- Run tests
yarn test:ci
- Create pull request
if you add a new package @ngxs/my-super-plugin
- Create a new project folder
packages/my-super-plugin
- Create template library with ngPackagr
- Add your project to package.json
- Run development mode
yarn build:packages --package my-super-plugin --watch
- ...development...
- Run build
yarn build:packages --package my-super-plugin
- Run tests
yarn test:ci
- Create pull request
NGXS Labs
If you have ideas for creating unique libraries, you can join us. Email us at ngxs.lead@gmail.com
. Or you can email us on Twitter or Slack.
Packages
Tools
Project | Package | Version | Links |
---|---|---|---|
NGXS CLI | @ngxs/cli | ||
NGXS Schematics | @ngxs/schematics |
Packages
Project | Package | Version | Links |
---|---|---|---|
NGXS Store | @ngxs/store | ||
NGXS Logger-plugin | @ngxs/logger-plugin | ||
NGXS Devtools-plugin | @ngxs/devtools-plugin | ||
NGXS WebSocket-plugin | @ngxs/websocket-plugin | ||
NGXS Form-plugin | @ngxs/form-plugin | ||
NGXS Router-plugin | @ngxs/router-plugin | ||
NGXS Storage-plugin | @ngxs/storage-plugin | ||
NGXS HMR | @ngxs/hmr-plugin |
NGXS Labs
Project | Package | Version | Links |
---|---|---|---|
NGXS Persistence API | @anglar-ru/ngxs | ||
NGXS-labs Emitter | @ngxs-labs/emitter | ||
NGXS-labs Immer adapter | @ngxs-labs/immer-adapter | ||
NGXS-labs Dispatch decorator | @ngxs-labs/dispatch-decorator | ||
NGXS-labs Select snapshot decorator | @ngxs-labs/select-snapshot | ||
NGXS-labs Async storage plugin | @ngxs-labs/async-storage-plugin | ||
NGXS-labs Entity state | @ngxs-labs/entity-state | ||
NGXS-labs Testing tools | @ngxs-labs/testing | ||
NGXS-labs Actions Executing | @ngxs-labs/actions-executing | ||
NGXS-labs Attach Action | @ngxs-labs/attach-action |
Community
Project | Package | Version | Links |
---|---|---|---|
Reset Plugin | ngxs-reset-plugin | ||
NGXS-Loading-plugin | ngxs-loading-plugin | ||
NGXS-History-plugin | ngxs-history-plugin |
Contributors
Thanks to all our contributors!
Top Related Projects
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot