By @isEmilia, front-end developer.
https://github.com/isemilia/task-management
| UI | basic blocks of interface. One UI unit cannot import another UI unit. |
|---|---|
| Components | can be built using UI units. Can have their own state. |
| Features | actions that users can perform. For example, create-task, edit-task. Can be built using both components and UI units. |
| App | anything that is crucial for the entire app to function correctly. |
| Shared | global functions, hooks, styles and other utils. |

This structure may seem repetitive at first, but it's super helpful in development. It avoids redundant imports. If I went with a basic setup, my imports would look like @components/input/input, and I want to avoid that.
On the other hand, renaming files to index.tsx would make my editor tabs messy, and errors would always point to an index.tsx. I'd have to check each error to know which exact index.tsx caused it, which is inefficient.
To fix these issues, I'm using both input.tsx and index.ts. This way, input.tsx has the input component itself, and the index file just imports it. Now, my editor tabs and errors show the real component name, and my imports stay neat and short.
| Styles (styled components or CSS-like objects) | component.styles.ts |
|---|---|
| Storybook | component.stories.ts |
| Typescript types and interfaces | component.model.ts |
| Yup validation schema | component.schema.ts |