Organizing your ngrx components using ducks

I started to use ngrx recently, again, but I couldn’t find a way to organize the code following the team recommendations. I noticed that most of the style guide was using a folder-by-type structure, popular amount React projects but discouraged by the Angular Style Guide, that strongly suggests the use of a folder-by-feature structure. They even divide the features of the application in core, shared, and other features, where most of the time, core module should be importing all the core components and services of the application and be loaded by the main module, shared module should use a barrel module for all the shared components and should be imported by the features modules, and they recommend to all others feature modules to be lazy loaded.

The community seems to have a strong opinion of when to use each structure, but most of the time, folder-by-feature is recommended, because it allows to scale easier than folder-by-type.

When I worked with Angular and ngrx, I used folder-by-type, and the projects I have worked with React, our team used folder-by-type, and we tried to implement the ducks proposal often. There is a extension of that proposal to be used in a folder-by-fracture structure, named re-ducks. So, based off the re-ducks proposal, and using the Angular Style Guide, I develop a Tour of Hero app.

I documented the result in ngrx-ducks repository, and I will try to explain it here.

Store

In @ngrx the store have to be configured as a module, using a similar approach that Route Module have. So I took most of the recommendations about the routes in the ASG and applied to the Store in the project.

Ducks

Reducers, Actions, Effects, and Selectors, are called ducks in the proposal with the same name. In that proposal, it assumes that you are using a folder-by-type structure, and suggest to use a ducks file exporting all your ducks. In the re-ducks proposal however, it assumes that you are using a folder-by-feature structure, and suggest to separate each part of the ducks in its own file, and reexport them in a index file, inside a ducks folder.

In this proposal however, I assume that most of your reducers will be related with one component. Assuming that one reducer will handle the state of one component, allow you to put your ducks along with this.

To assume this, I also assume that you are using a folder-by-feature structure, and your are declaring a module for every of your features. This module should have its own store, and should import the state of the reducers and initialize the state of that feature. Also, it should export a feature selector, to be used by the each of that feature components selectors.

A word about this

Obviously, this is not an approach for everybody. If you fell like you can use the current style guide from @ngrx, that’s totally ok. I just need and alternative to use in larger projects. If you have a suggestion or anything, please, leave it in the comments, or better yet, open an issue in the repo.

The complete proposal is quite large to be included here, but you can read it in ngrx-ducks.

I know I did this thinking about me, but I really hope this can help someone else.

Thanks you so much for reading this, and I will really appreciate your thoughts about this. I don’t fell like having so much experience in large projects, but I do fell like thinking in horizontal scaling is a good approach to do so.