DEV Community

Brandon Collins
Brandon Collins

Posted on

DUCK (file structure) YOU!

The term "Duck" in the Duck File Structure originally comes from the saying "If it looks like a duck and quacks like a duck, it’s probably a duck." This means that each feature folder should contain everything needed to act independently, like a self-contained "duck."

Organizing Code with the Duck File Structure

When managing modern web applications, file organization plays a pivotal role in the maintainability, readability, and scalability of your project. The Duck File Structure, initially popularized in Redux applications, is an approach that’s grown in popularity across JavaScript and Python projects alike. This style of organization groups related components together, making it easier to navigate large codebases without constantly hunting for dependencies or related files.

Why Use Duck File Structure?

Duck File Structure organizes files by feature rather than type, aiming to keep all files that relate to a single feature in the same place. Unlike traditional structures that separate code by file type (e.g., components, actions, reducers, styles), the Duck File Structure places everything a feature needs in one "duck folder." This layout is particularly effective for React projects with Redux but works well in any modular codebase.

Here’s how it works:

  1. Each feature has its own folder: Rather than having all actions, reducers, and components in separate directories, each feature has a dedicated folder that holds its components, styles, tests, and state management logic.
  2. Self-contained and modular: By localizing files by feature, this structure allows you to import entire feature modules into the main project without worrying about breaking other parts of the application. This keeps your project clean and organized.
  3. Easier to scale: As the project grows, the Duck File Structure helps ensure features are easy to add and remove. Each module has everything it needs to function independently.

Structure Breakdown

Here’s what a typical Duck File Structure might look like:

src/
│
├── features/
│   ├── User/
│   │   ├── components/
│   │   │   └── UserProfile.js
│   │   ├── hooks/
│   │   │   └── useUser.js
│   │   ├── services/
│   │   │   └── userService.js
│   │   ├── UserSlice.js
│   │   ├── UserActions.js
│   │   └── User.css
│   │
│   └── Product/
│       ├── components/
│       │   └── ProductCard.js
│       ├── hooks/
│       │   └── useProduct.js
│       ├── services/
│       │   └── productService.js
│       ├── ProductSlice.js
│       ├── ProductActions.js
│       └── Product.css
│
├── shared/
│   ├── utils/
│   │   └── fetchUtils.js
│   └── hooks/
│       └── useFetch.js
│
└── app/
    ├── store.js
    └── rootReducer.js

Enter fullscreen mode Exit fullscreen mode

Let’s break down each folder's purpose:

  1. features/: Each folder in the features directory is a distinct "duck," representing a single feature or module. Inside each duck folder are all the components, hooks, services, and styles required to make that feature function.
  2. UserSlice.js and ProductSlice.js: Each "duck" has its own slice, which holds the state management logic for Redux. This way, all related actions, reducers, and constants are kept close to their feature, instead of scattered throughout different folders.
  3. shared/: The shared folder contains global code used across features, like utility functions, generic hooks, or helpers that aren’t feature-specific.
  4. app/: The app folder holds the central setup files for the project, like store.js and rootReducer.js, which combine the reducers from each feature.

Benefits of the Duck File Structure

  • Improved organization: Each feature’s dependencies are grouped together, so you don’t have to search multiple folders for related files.
  • Easier refactoring: Since all parts of a feature are in one place, you can move, edit, or refactor a feature without needing to hunt down related files.
  • Better reusability: Because features are modular, they’re easy to reuse in other projects or apps.
  • Enhanced readability: Developers new to the project can easily locate the code for each feature and understand how components interact.

When to Use Duck File Structure

The Duck File Structure is beneficial for:

  • Large codebases where features are complex and interdependent.
  • Projects that require modularity for scalability and reuse.
  • Teams with multiple developers working across various features, as it promotes better file organization and collaboration.

However, if your project is small or has minimal features, this file structure might introduce unnecessary complexity.

Final Thoughts

The Duck File Structure helps developers maintain large, modular codebases without the overhead of navigating numerous folders. While this structure has roots in Redux, it’s versatile enough to be adopted in any framework that benefits from modularization, like Vue or even Python applications. By organizing code by feature rather than type, you set a foundation for a scalable and maintainable codebase that’s easy for anyone on the team to understand.

Top comments (0)