Skip to content

Instantly share code, notes, and snippets.

@itsMapleLeaf
Last active April 26, 2024 02:55
Show Gist options
  • Save itsMapleLeaf/cd72cecd741032fefff981ec353d426c to your computer and use it in GitHub Desktop.
Save itsMapleLeaf/cd72cecd741032fefff981ec353d426c to your computer and use it in GitHub Desktop.
Folder structure

✨ My go-to folder structure ✨

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

Folder explanations

  • common: helpers that could theoretically be pasted in any other app without changes

  • common/types.ts: Generic helper types, like DeepPartial. 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 a useToggle hook

  • dom: helpers to work with the DOM, like an async loadImage function

  • react: extensions of react's API, like a <Portal/> component

Other notes

  • 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".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment