|
| 1 | +--- |
| 2 | +title: Slice groups |
| 3 | +sidebar: |
| 4 | + order: 3 |
| 5 | +--- |
| 6 | + |
| 7 | +import { FileTree } from '@astrojs/starlight/components'; |
| 8 | + |
| 9 | +import StaticImage from '../../../../shared/ui/static-image/StaticImage.astro'; |
| 10 | + |
| 11 | +A slice group places related slices close together within the same layer, making the structure easier to navigate. |
| 12 | + |
| 13 | +It is not a required part of FSD. You can introduce slice groups selectively when the number of slices grows large enough that a flat structure becomes hard to browse. |
| 14 | + |
| 15 | +## Overview |
| 16 | + |
| 17 | +It is a structure for making code easier to read and navigate, and does not affect dependency rules between slices. |
| 18 | + |
| 19 | +A slice group is not a slice. It does not have its own segments like `model`, `ui`, or `api`, nor does it have a public API such as `index.ts`. Shared code used across multiple slices should not be placed in a slice group either. |
| 20 | + |
| 21 | +<StaticImage path={['/img/slice-group-not-a-slice-light.svg', '/img/slice-group-not-a-slice-dark.svg']} alt="A slice group does not have segments or a public API" /> |
| 22 | + |
| 23 | +Each slice remains independent even when it belongs to a slice group. The isolation and dependency rules between slices do not change. |
| 24 | + |
| 25 | +## Why it is needed |
| 26 | + |
| 27 | +As the number of slices grows, a flat structure can make it hard to locate related code. When slices that share the same context are scattered across a layer, you end up scanning the entire layer multiple times. |
| 28 | + |
| 29 | +A slice group addresses this by bringing related slices closer together, making the structure easier to navigate. |
| 30 | + |
| 31 | +## When to consider introducing one |
| 32 | + |
| 33 | +Consider introducing a slice group when there is a grouping criterion that feels obvious at a glance, and splitting the structure actually makes it easier to read. |
| 34 | + |
| 35 | +- Several slices sharing the same business context are scattered across a layer. |
| 36 | +- The slice names clearly suggest they belong to the same topic. |
| 37 | +- The number of slices in a layer has grown to the point where it is hard to take in at a glance. |
| 38 | + |
| 39 | +Conversely, it may not be needed yet in the following cases. |
| 40 | + |
| 41 | +- Names alone are enough for quick navigation. |
| 42 | +- There is no natural grouping criterion. |
| 43 | +- Too few slices would end up in the group. |
| 44 | + |
| 45 | +## How to apply it |
| 46 | + |
| 47 | +### entities |
| 48 | + |
| 49 | +You can group slices that are close from a domain model perspective. |
| 50 | + |
| 51 | +For example, suppose the `entities` layer has accumulated many payment-related slices. |
| 52 | + |
| 53 | +**Without a group:** |
| 54 | + |
| 55 | +<FileTree> |
| 56 | +- entities/ |
| 57 | + - invoice/ |
| 58 | + - model/ |
| 59 | + - ui/ |
| 60 | + - receipt/ |
| 61 | + - model/ |
| 62 | + - ui/ |
| 63 | + - transaction/ |
| 64 | + - model/ |
| 65 | + - ui/ |
| 66 | + - user/ |
| 67 | + - model/ |
| 68 | + - ui/ |
| 69 | + - product/ |
| 70 | + - model/ |
| 71 | + - ui/ |
| 72 | + - ... |
| 73 | +</FileTree> |
| 74 | + |
| 75 | +To find the payment-related slices (`invoice`, `receipt`, `transaction`), you would need to scan the entire layer and pick them out one by one. |
| 76 | + |
| 77 | +**With a group:** |
| 78 | + |
| 79 | +<FileTree> |
| 80 | +- entities/ |
| 81 | + - payment/ |
| 82 | + - invoice/ |
| 83 | + - model/ |
| 84 | + - ui/ |
| 85 | + - receipt/ |
| 86 | + - model/ |
| 87 | + - ui/ |
| 88 | + - transaction/ |
| 89 | + - model/ |
| 90 | + - ui/ |
| 91 | + - user/ |
| 92 | + - model/ |
| 93 | + - ui/ |
| 94 | + - product/ |
| 95 | + - model/ |
| 96 | + - ui/ |
| 97 | + - ... |
| 98 | +</FileTree> |
| 99 | + |
| 100 | +Now every payment-related slice can be found directly under `payment/`. |
| 101 | + |
| 102 | +Not every slice needs to belong to a group. A slice like `user/`, whose meaning is clear on its own, can remain ungrouped. |
| 103 | + |
| 104 | +### pages |
| 105 | + |
| 106 | +You can group related pages in the pages layer in a similar way. This is one possible example and does not represent the default structure for the pages layer. |
| 107 | + |
| 108 | +<FileTree> |
| 109 | +- pages/ |
| 110 | + - order/ |
| 111 | + - create/ |
| 112 | + - ui/ |
| 113 | + - detail/ |
| 114 | + - ui/ |
| 115 | + - list/ |
| 116 | + - ui/ |
| 117 | + - customer/ |
| 118 | + - detail/ |
| 119 | + - ui/ |
| 120 | + - list/ |
| 121 | + - ui/ |
| 122 | + - settings/ |
| 123 | + - ui/ |
| 124 | + - ... |
| 125 | +</FileTree> |
| 126 | + |
| 127 | +This structure helps when there are multiple pages on the same topic, such as list, detail, create, and edit. |
| 128 | + |
| 129 | +### Can they be used in features as well? |
| 130 | + |
| 131 | +Yes, slice groups can be applied to the features layer as well. However, a feature often spans multiple entities rather than being tied to a single domain. This makes it harder to find a natural grouping criterion compared to entities. |
| 132 | + |
| 133 | +If you create a group like `features/cart/` without a clear criterion, use cases like `add-to-cart` and `remove-from-cart` will end up there, but cart-related DTOs and mappers may start accumulating as well. At that point the group folder stops serving as a navigational structure and begins acting as a home for the entire cart domain, weakening the principle that features should be split by use case. |
| 134 | + |
| 135 | +To introduce a slice group in features, first check whether there are enough slices to warrant a group. If there are only two or three, a flat structure is likely sufficient. You should also check whether the group contains only feature slices, or whether code that belongs in entities has crept in as well. |
| 136 | + |
| 137 | +## References |
| 138 | + |
| 139 | +- [Russian Telegram FSD community — Discussion on structural grouping, slice groups, and layer extension](https://t.me/c/1216849846/1/2785) |
| 140 | +- [Russian Telegram FSD community — Nested vs. flat structure, forms and boundaries of slice groups](https://t.me/c/1216849846/1/5051) |
| 141 | +- [Russian Telegram FSD community — Why there are fewer grouping examples in features, and whether slice groups work in features](https://t.me/c/1216849846/1/80620) |
| 142 | +- [KakaoPay — A case of applying slice grouping in the pages layer](https://tech.kakaopay.com/post/fsd/#2-slice-grouping-%ED%97%88%EC%9A%A9-%EB%B0%8F-pages-%EB%A0%88%EC%9D%B4%EC%96%B4-%EA%B5%AC%EC%84%B1) |
0 commit comments