Features is a Rust-based Web and CLI tool to explore the features in your projects, visualize their metrics and understand the ownership of each of these features.
It is technology agnostic and can be used with any programming language or framework.
You can:
- list all the features in a project
- find the team 'owning' a specific feature
- get the history of a feature (git log)
- find the documentation related to the feature
- list the test coverage by feature
- check the technical debt by feature
- see statistics about the features like the repartition of feature, fix and refactor commits, lines of code, and files
- generate CODEOWNERS file
- list the feature flags and other feature dependencies
If you see an other use case, feel free to contribute to this repository.
It also provides a UI to explore the feature. Check a live demo.
features-cli provides a Web Dashboard and also a CLI to generate json reports.
npx features-cli@latest /path/to/project --project-dir ./repository --serve
# or with installation
npm install -g features-cli
# or
cargo binstall features-cli
# then
features /path/to/project --project-dir ./repository --serveCommands and their descriptions are listed below:
| Command | Description |
|---|---|
--json |
Output features as JSON |
--flat |
Output features as a flat array instead of nested structure |
--description |
Include feature descriptions in the output (automatically enabled for --serve, --build, and --json) |
--coverage |
Include coverage information in the output (automatically enabled for --serve, --build, and --json) |
--list-owners |
Display only unique list of owners |
--find-owner <path> |
Find the owner of a specific file or folder |
--check |
Run validation checks on features (e.g., duplicate names) |
--skip-changes |
Skip computing git commit history (faster for large repos) |
--serve |
Start an HTTP server to serve features and the web dashboard UI |
--port <port> |
Change the port (default: 3000). Should be used with --serve |
--build |
Build a static version of the web dashboard UI |
--build-dir <path> |
Output directory for the static build (default: build) |
--coverage-dir <path> |
Specify a custom coverage directory (overrides automatic search) |
--generate-codeowners |
Generate or update a CODEOWNERS file with feature ownership information |
--project-dir <path> |
Project directory for CODEOWNERS generation and additional coverage search locations |
--codeowners-path <path> |
Custom path and filename for CODEOWNERS file (default: CODEOWNERS in project directory) |
--codeowners-prefix <prefix> |
Custom prefix for owner names in CODEOWNERS file (default: @) |
By following specific guidelines and conventions, it becomes easier for features to find your feature:
Features can be organized in two ways:
Place your features folder in a dedicated features folder:
src/
├── features
│ ├── saveUser
│ │ ├── components/
│ │ │ ├── UserForm.ts
│ │ │ └── EmailInput.ts
│ │ ├── utils/
│ │ │ ├── useSaveUser.ts
│ │ │ ├── useFetchUser.ts
│ │ │ └── transformUser.ts
│ │ └── README.md # a README.md file for large features helps
│ └── feature-2
│ └── ... # ...
├── components # common components used across features
├── utils # common utils/hooks used across features
└── ... # other source codeYou can read the detailed guidelines or just jump into trying the CLI with the
--serveoptions. The UI will guide you through the methodology.
Mark any folder as a feature by adding feature: true in its README frontmatter:
---
feature: true
owner: backend-team
---This allows features to be organized anywhere in your codebase while still being discoverable by the tools.
You can annotate your code with feature metadata using special comments. These annotations can be placed anywhere in your codebase and will be automatically associated with the matching feature:
// --feature-flag feature: feature-1, name: feature-flag1, type: experiment, owner: team-a, introduced_on: 2025-01-01
export function experimentalLoginFlow() {
// implementation
}The syntax is: --feature-<metadata-key> feature:<feature-folder-basename>, property: value, ...
feature:property is optional if the comment is inside a feature folder - it will automatically link to that feature<metadata-key>becomes a tab in the web UI (e.g.,flag,experiment)- Properties are flexible - add any key-value pairs you need
This works in any programming language:
# --feature-flag name: feature-flag1, type: processing, language: python// --feature-flag name: feature-flag1, type: core, status: stable# --feature-flag name: feature-flag1, environment: production, region: us-west-2This project is licensed under the MIT License - see the LICENSE file for details.
We welcome contributions to this project! If you have any ideas or suggestions, please feel free to open an issue or submit a pull request.
Check here.
Feature based architecture shouldn't be confused with feature-based design.