en	File system organization

en	A component-based approach used in the BEM methodology also determines the way that BEM projects are organized in a file system.

en	In BEM, it's not just the interface that is divided into independent components, i.e.

en	blocks, but the implementation of blocks is also divided into independent parts, namely files.

en	Below on this page you will find:

en	Principles of file system organization#principles-of-file-system-organization-for-bem-projects

en	Example of a file system for a BEM project#file-system-organization-of-a-bem-project

en	Examples of using redefinition levels#examples-of-using-redefinition-levels

en	Principles of file system organization for BEM projects

en	In a BEM project, the code is broken down into small independent parts, to make working with individual blocks easier.

en	Before they are sent to the browser, the files are assembled and optimized.

en	That way we separate the human-manipulated code from the code that is sent to the browser.

en	In the file system, the codebase of BEM project is organized according to the following principles:

en	A block implementation is divided into separate parts#a-block-implementation-is-divided-into-separate-files

en	Optional elements and modifiers are stored in separate files#optional-elements-and-modifiers-are-stored-in-separate-files

en	Files are grouped by meaning and not by type#files-are-grouped-by-meaning-and-not-by-type

en	A project is divided into redefinition levels#a-project-is-divided-into-redefinition-levels

en	A block implementation is divided into separate files

en	A file set for a block (e.g., input.css, input.js) is determined by the technologies../key-concepts/key-concepts.en.md#implementation-technology that make up the implementation of the block.

en	Why?

en	Enhanced project navigation.

en	The project structure is built on a single principle, and the block names are unique.

en	This enables developers to easily identify different parts of the project and to find necessary files quicker.

en	Easier moving of blocks between projects.

en	The implementation of blocks is divided into separate files.

en	To move a block from one project to another, you only need to copy the relevant files or directories.

en	Optional elements and modifiers are stored in separate files

en	Why?

en	Only relevant block implementation is included

en	Only files that are essential to a given block implementation are included in the build.

en	Files are grouped by meaning and not by type

en	Block files are grouped together based on common naming rules../naming-convention/naming-convention.en.md.

en	For convenience, they can be grouped into a block directory.

en	Why?

en	Only necessary blocks are included in the project

en	Blocks are implemented as independent entities.

en	This enables us to configure a build in a way that ensures that only relevant blocks are included in the project.

en	A project is divided into redefinition levels

en	The final implementation of a block can be split into redefinition levels#examples-of-using-redefinition-levels.

en	Why?

en	No code duplication.

en	Storing implementation common to all platforms on a separate level helps avoid code duplication and reduce debugging time.

en	Redefinition and extension of ready-made library blocks.

en	To modify a library block, you don't need to copy it to the project level.

en	You just need to create the necessary file with the changes or new code at another redefinition level and include it in the build.

en	Updating libraries linked to the project.

en	Dividing a project into distinct levels lets us modify blocks without affecting the library source code.

en	If the library gets updated, the block modification is stored at a different level of the project.

en	File system organization of a BEM project

en	For every block, there's a directory in the file system.

en	The directory is named after the block.

en	blocks/ input/ # input block directory button/ # button block directory

en	A block implementation is divided into separate files known as technology files.

en	The files all have the same name as the block.

en	The extension of each file corresponds to its technology.

en	blocks/ input/ input.css # `input` block implementation in CSS input.js # `input` block implementation in JavaScript button/ button.css button.js button.png

en	Names of files and directories for BEM entities../key-concepts/key-concepts.en.md#bem-entity are based on the naming convention../naming-convention/naming-convention.en.md:

en	Element — block__elem.extension (input__box.css).

en	Block modifier — block_mod_val.extension (input_type_search.css) or block_mod.extension (input_disabled.css).

en	Values of boolean modifiers are not included.

en	Element modifier — block__elem_mod_val.extension (input__clear_size_large.css) or block__elem_mod.extension (input__clear_visible.css).

en	Modifiers and elements are stored in separate files and are grouped into accordingly named block subdirectories.

en	blocks/ input/ _type/ # `type` modifier directory input_type_search.css # Implementation of modifier `type` # with value `search` in CSS technology __box/ # `box` element directory input__box.css input.css input.js button/ button.css button.js button.png

en	If there are modifiers that differ in value (e.g., popup_target_anchor.extension and popup_target_position.extension), the shared code can be stored in a separate file (popup_target.extension) with no modifier value included in the name.

en	blocks/ popup/ _target/ popup_target.css # Common code of modifier `target` popup_target_anchor.css # Modifier `target` with value `anchor` popup_target_position.css # Modifier `target` with value `position` _visible/ popup_visible.css # Boolean modifier `visible` popup.css popup.js

en	Real-life examples

en	bem-corehttps://github.com/bem/bem-core/tree/v2/common.blocks/page

en	bem-componentshttps://github.com/bem/bem-components/tree/v2/common.blocks/button

en	Examples of using redefinition levels

en	The implementation of a block can be divided into redefinition levels../key-concepts/key-concepts.en.md#redefinition-level.

en	Let's take a few examples:

en	Linking a library#linking-a-library

en	Dividing a project into platforms#dividing-a-project-into-platforms

en	Linking a library

en	A library can be linked to a project as a separate level.

en	Blocks can be modified (extended or redefined) at another project level.

en	During the build process the original block implementation will be linked from the library level and the redefined one from the project level.

en	Such an arrangement allows us to preserve changes made to the blocks if the library gets updated — the library source code will be updated while the specific implementation of the project blocks will remain the same because it is stored at a different level.

en	library.blocks/ button/ button.css # CSS implementation in the linked library (height 20px) project.blocks/ button/ button.css # Redefinition of CSS implementation (height 24px)

en	Dividing a project into platforms

en	A project is divided into platforms (mobile and desktop) and into respective redefinition levels in the file system.

en	The common level contains the implementation of blocks that is common to both platforms.

en	The desktop and mobile levels contain platform-specific block implementations.

en	Let's look at an example:

en	common.blocks/ button/ button.css # Generic CSS implementation of the button desktop.blocks/ button/ button.css # Desktop platform-specific button features mobile.blocks/ button/ button.css # Mobile platform-specific button features

en	During the build process, all the generic CSS rules for the button will be included in the desktop.css file from the common level, and the redefined rules from the desktop level.

en	Generic CSS rules

en	Desktop platform-specific

en	The mobile.css file will include the generic CSS rules for the button from the common level and the redefined rules from the mobile level.

en	Generic CSS rules

en	Mobile platform-specific