Moving Beyond Angular's Style Guide - Part 1: Rule of One
Tags: angular, typescript, javascript, architecture
Published: 2020-03-31 14:59:36

---
title: Moving Beyond Angular's Style Guide - Part 1: Rule of One
published: true
description: Learn why the "Rule of One" might be worth re-thinking for your growing Angular applications.
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/lf3dqovja874gs3d0lc6.jpg
tags: angular, typescript, javascript, architecture
series: Moving Beyond Angular's Style Guide
---

_In this series we look at some of the rules in [Angular's Style Guide](https://angular.io/guide/styleguide) that might need clarification or alteration as we grow our applications and our understanding 🧠 of the framework._

---

## 📐 The Rule in Question: [Rule Of One](https://angular.io/guide/styleguide#rule-of-one)

The Angular Style Guide defines this rule as follows:

> Do define one thing, such as a service or component, per file.

> Consider limiting files to 400 lines of code.

---

## 💡 Positive Observations: A Solid Starting Point

This rule is definitely great advice. It aligns with the [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single-responsibility_principle), and motivates us to think about what purpose a component or service in our application really serves.

Choosing 400 lines, as the maximum length per file, is slightly arbitrary, but we should choose **some** number as a guide post.

Anything that crosses this line is a [code smell](https://en.wikipedia.org/wiki/Code_smell) - not necessarily wrong, but worth further investigation!

Creating multiple components in a single file could make one or both hard to find (at least one class won't match the file name), and as the style guide mentions, the more code in a file, the higher the chance for version control conflicts.

I think this rule is a good starting point, and at the beginning of an application's development there's no reason not to follow it.

---

## 👓 What Needs Clarification: Not Everything in our Apps is Angular

This rule has good intentions and is a great suggestion for services and components.

However, most Angular applications are going to include more types than just services and components.

It's common, in a growing or mature code base, to see the following types of things in addition to components and services:

- [Domain model](https://en.wikipedia.org/wiki/Domain-driven_design#Concepts) classes
- Interface definitions to match API requests / responses
- [Type aliases](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases) of both of the above, to better match the [domain language](https://en.wikipedia.org/wiki/Domain-driven_design#Building_blocks)
- Enum definitions
- Typescript [union types](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions)
- [Custom RxJs operators](https://netbasal.com/creating-custom-operators-in-rxjs-32f052d69457)
- Factory functions for non-class data structures
- Utility functions for validation or transformation
- Classes managed outside Angular's dependency injection system

Do all of these need to be in separate files as well?

---

State management libraries like [Akita](https://netbasal.gitbook.io/akita/core-concepts/store) and [NgRx](https://ngrx.io/guide/store) often have many type definitions to make working with complex and nested state easier.

Since these types are closely related to each other and the state management code that uses them, it makes sense to co-locate them (keep them close in our project).

I think this rule is somewhat influenced by well-known [Object Oriented](https://en.wikipedia.org/wiki/Object-oriented_programming) programming languages, like C# and Java, where the type-per-file pattern is well established.

In functional languages, this isn't the case, since functions tend to be smaller and more composable than classes, there are often multiple per "module". This was also true in JavaScript for a long time, which makes sense given the importance of functions in the language.

I really like this quote from [Kent Beck](https://twitter.com/KentBeck) (as noted by Mark Seemann):

{% twitter 1243836643875999744 %}

---

## ✨ Conclusion

Following the "Rule of One" and seeing an increase in the number of files in a project isn't inherently a bad thing! 

That said, co-location is also a goal that's worth pursuing - especially for code that is closely related.

I think the "Rule of One" should clearly state the it is a recommendation for Angular types (Components, Directives, Injectables, NgModules, ect...), but we should be free to structure our non-Angular code as the project demands.

As always, thanks for reading 🙏!

---

## ❓ Questions

What are your thoughts on the "Rule of One"?

Have any of your apps included the things I listed above, like domain models, Enum definitions, or custom RxJs operators?

Have you ever found the need to move beyond the "Rule of One" for non-Angular code in your Angular application? What about for Angular specific things?

Leave a comment below!

---

<figcaption>Cover photo by <a href="https://unsplash.com/@photos_by_lanty">Photos by Lanty</a> on Unsplash</figcaption>

---

Normally, I'm blogging about [Kentico](https://www.kentico.com/), a content management system I love to use.

We've put together a list over on [Kentico's GitHub account](https://github.com/Kentico/Home/blob/master/RESOURCES.md) of developer resources. Go check it out!

If you are looking for additional Kentico content, checkout the Kentico tag here on DEV:

{% tag kentico %}

Or my Kentico blog series:

- [Kentico 12: Design Patterns](https://dev.to/search?q=Kentico%2012%3A%20Design%20Patterns)
- [Kentico CMS Quick Tips](https://dev.to/search?q=Kentico%20CMS%20Quick%20Tip)
- [Kentico EMS: MVC Widget Experiements](https://dev.to/search?q=Kentico%20EMS%20-%20MVC%20Widget%20Experiments)