In a nutshell, flat feature folders:
src/
app/
home.tsx
app-header.tsx
app-sidebar.tsx
common/
debounce.ts
errors.ts
pick.ts
types.ts
user/
user-profile-view.tsx
user-edit-profile-view.tsx
use-user.ts
get-user-full-name.ts
types.tsx
post/
post-details.tsx
post-card.tsx
ui/
button.tsx
text-input.tsx
With Remix, and frameworks that have required folders like pages
, I'll make a modules
folder for all of the features:
app/
modules/
app/
home.tsx
app-header.tsx
app-sidebar.tsx
common/
debounce.ts
errors.ts
pick.ts
types.ts
pages/
index.tsx
profile.tsx
-
common
: helpers that could theoretically be pasted in any other app without changes -
common/types.ts
: Generic helper types, likeDeepPartial
. I put these all in one file, because they're usually not very big or complex -
ui
: core UI components, and other things like stylesheets and color constants -
app
: app-specific stuff that doesn't fit in any other folder. You can think of this as the "backbone" folder of core stuff, like<AppLayout/>
,<AppHeader/>
,<PrimaryNav/>
, etc. -
state
: stuff relating to state management, like auseToggle
hook -
dom
: helpers to work with the DOM, like an asyncloadImage
function -
react
: extensions of react's API, like a<Portal/>
component
-
I never go any deeper than a single level.
-
If a feature folder has a lot of files in it, I might try to split it up into different folders
-
I use
kebab-case
for case-insensitive operating systems -
Aside from
common/types
, I keep types in the file that's most related to them. e.g. component prop types, I put them in the component file. -
If I'm using a third-party API, I make a feature folder for that:
src/ anigreen/ api.ts media-data.ts media-card.tsx
-
Sometimes, I'll group related things together in single files to keep from having too many files.
// common/math.ts export const clamp = (num: number, min: number, max: number) => ... export const lerp = (a: number, b: number, t: number) => ...
-
As a general rule, if it's hard to figure out what feature folder a thing goes in, it helps to ask "why does it exist", "what causes this to exist", or "what is this most related to".