Attention: The recommendations on
CoreModule (and modules in general) has changed a bit but this blog post will be left as it was since it still contains pretty good information.
If you're new to Angular, you might get confused between these two commonly used modules. So what do you put in either components?
What goes in
CoreModule contains code that will be used to instantiate your app and load some core functionality.
The clearest and most important use of the
CoreModule is the place to put your global/HTTP services. The idea is to make sure only one instance of those services will be created across the entire app. The
CoreModule, by convention, is only included in your entire app once in
AppModule (only in the
import property of the
@NgModule() decorator inside your main
app.module.ts, not in any other module's
import) and this will ensure services inside it will be only created once in the entire app. This is especially important if you intend to lazy-load your feature modules. Since lazy-loaded modules are loaded on demand (eg when you access the route using the lazy-loaded feature), you could end up creating new instances of supposedly singleton services if you don't put them in
Important single use components/classes can also go in the
CoreModule. Good candidates are global components that go in your main
AppComponent. For example, if your app has one global header component, you can add the code for
CoreModule (and then put the
HeaderComponent class in the
exports property of
@NgModule() decorator so
AppModule which imports
CoreModule can use it). This allows you to keep this global component in one spot and make sure there's only have one copy of it across the app.
CoreModule could also be used to export any third party module that is required in the
AppModule. The idea is to keep
AppModule as lean as possible. Examples are
BrowserAnimationsModule (as of time of this writing, this should only be imported once throughout the whole app),
What goes in
SharedModule similarly contains code that will be used across your app and Feature Modules. But the difference is that you will import this
SharedModule into the specific Feature Modules as needed. You DO NOT import the
SharedModule into your main
Common templates components should also go in the
SharedModule. An example would be a global button component, eg
ButtonComponent. These template components should be "dumb components" in that they should not expect or interact with any specific form of data. You should define a template, style, an
@Output() event property, and maybe a
@Input() string property for text inside the button so you can pass in whatever event you want to fire when a user clicks the button. Now all your buttons can look uniform across the app! Of course, this is an architectural decision left up to your discretion. It will make for easier unit testing and separation-of-concerns to follow the pattern though.
Commonly used pipes (ie filters) and directives should go in your
SharedModule, too. Prime examples would be custom string/date filters.
SharedModule's main file (eg
shared.module.ts), you might also export the commonly used Angular modules (eg
@angular/common for the
*ngIf structure directive or the
@angular/forms for the
[(ngModel)] directive) so they can be easily used across your app, without importing them in every Feature Module. Note, this might be introduce unnecessary loading speed if you don't use those modules/directives a lot; if that's the case, you might want to do it the old fashioned way and import these Angular modules only in the Feature Modules that use them.
To summarize, your
CoreModule should definitely contain your singleton services, single-instance components, and export any third-party modules needed in
SharedModule should contain common components/pipes/directives and also export commonly used Angular modules (like
*ngIf directive). You should have "dumb components" in
For further clarification, reference Angular's tutorials on modules or their style guide.