Skip to content

Quick Start

Three ways to integrate Qualimetrix into your project:

  1. Pre-commit Hook — check before every commit
  2. GitHub Action — automatic checks in CI/CD
  3. Docker — run without installing PHP locally

Your First Analysis

Install

composer require --dev qualimetrix/qualimetrix

Run the analysis

vendor/bin/qmx check src/

Interpret the output

The default output shows a health summary with scores by category:

Qualimetrix — 127 files analyzed, 2.3s

Health ████████████████████░░░░░░░░░░ 67.2% Fair

  Complexity      ██████████████████████████░░░░ 85.1% Excellent
  Cohesion        ████████████░░░░░░░░░░░░░░░░░░ 42.3% Poor
  Coupling        █████████████████░░░░░░░░░░░░░ 55.8% Fair
  Typing          ████████████████████████████░░ 92.0% Excellent
  Maintainability ████████████████████░░░░░░░░░░ 64.5% Good

Worst namespaces
  38 App\Service (12 classes, 28 violations) — low cohesion, high coupling
  42 App\Repository (8 classes, 15 violations) — low cohesion

45 violations (12 errors, 33 warnings) | Tech debt: 2d 4h (8.5 min/kLOC)

Hints: --detail to list violations (up to 200; --detail=all for every one) | --namespace='subtree:App\Service' to drill down | --format=html -o report.html for full report
Docs: https://qualimetrix.dev · AI agents: https://qualimetrix.dev/llms.txt

Each category gets a label: Excellent (top quality), Good (solid), Fair (room for improvement), Poor (needs attention), or Critical (action required). The "Worst namespaces" section highlights where to focus first.

Drill down into a namespace

Investigate a specific namespace to see its classes and violations:

vendor/bin/qmx check src/ --namespace='subtree:App\Service'

See detailed violations

List individual violations with file paths, line numbers, and remediation hints:

vendor/bin/qmx check src/ --detail

Generate an HTML report

For a full interactive report with charts and drill-down navigation:

vendor/bin/qmx check src/ --format=html -o report.html

Open report.html in your browser to explore the results.


1. Pre-commit Hook

Automatic checking of staged files before every commit.

Installation

vendor/bin/qmx hook:install

This writes .git/hooks/pre-commit, naming the binary that installed it. The file is yours: edit it and the hook keeps running, reinstall with --force and your edits are backed up beside it.

If a hook is already there, hook:install refuses until you pass --force, and backs up what it replaces.

Upgrading from 0.27.0 or earlier

Earlier releases installed the hook as a symlink into a script that is no longer shipped, so that link now leads nowhere and git runs nothing. Run vendor/bin/qmx hook:install --force to replace it. hook:status says so too.

Usage

After installation, the hook runs automatically on every git commit:

git add src/MyClass.php
git commit -m "Add new feature"

# Hook will run automatically:
# Running Qualimetrix on staged files...
# Qualimetrix passed.

Bypassing the Hook

# Skip the check for a specific commit
git commit --no-verify -m "WIP: work in progress"

Setting Up Baseline

If the project already contains legacy code with violations:

# Create a baseline for existing issues
vendor/bin/qmx baseline:generate baseline.json src/

# Now the hook will ignore issues from the baseline
git commit -m "Add feature"

Removing the Hook

rm .git/hooks/pre-commit

2. GitHub Action

Automatic analysis on push and pull request. See the GitHub Actions guide for detailed configuration.

Quick Setup

# .github/workflows/quality.yml
name: Code Quality

on: [push, pull_request]

jobs:
  qmx:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: Run Qualimetrix
        uses: qualimetrix/qualimetrix@v0.26.0
        with:
          paths: 'src/'
          baseline: 'baseline.json'

3. Docker

The image caches ASTs below /cache. Mount a persistent volume there, separate for each uid, to retain them across runs. The old checkout .qmx-cache is not read; --clear-cache affects all projects sharing this user cache. Automatic process-worker selection can warn and fall back to sequential after a failed ten-second first-start probe. The image includes pcntl: docker stop interrupts PID 1 with SIGTERM and releases temporary report files and worker startup logs, including runs reporting to stdout.

Run analysis in a container without installing PHP locally.

Building the Image

docker build -t qmx .

Usage

<!-- llms:skip-end -->

# Analyze the current directory
docker run --rm -v $(pwd):/app qmx check src/

# With baseline
docker run --rm -v $(pwd):/app qmx check src/ --baseline=baseline.json

# With configuration
docker run --rm -v $(pwd):/app qmx check src/ --config=qmx.yaml

# JSON output
docker run --rm -v $(pwd):/app qmx check src/ --format=json

Docker Compose

# docker-compose.yml
services:
  qmx:
    # The image built by `docker build -t qmx .` above, in the Qualimetrix
    # checkout. No image is published to a registry yet.
    image: qmx:latest
    volumes:
      - .:/app:ro
      - ./baseline.json:/app/baseline.json
      - qmx-cache:/cache
    command: check src/ --baseline=baseline.json
volumes:
  qmx-cache:
docker-compose run --rm qmx

CI/CD with Docker

# .gitlab-ci.yml
qmx:
  stage: test
  image: qmx:latest
  script:
    - qmx check src/ --baseline=baseline.json
  artifacts:
    when: on_failure
    paths:
      - qmx-results.json
// Jenkinsfile
pipeline {
    agent any
    stages {
        stage('Qualimetrix Analysis') {
            steps {
                script {
                    docker.image('qmx:latest').inside('-v $WORKSPACE:/app') {
                        sh 'qmx check src/ --baseline=baseline.json'
                    }
                }
            }
        }
    }
}

Excluding Paths

Suppress violations with explicit path selectors. Useful for generated code, DTOs, or entity classes.

Note

Excluded files are still analyzed (metrics are collected) — only violations are suppressed.

# qmx.yaml
suppress_paths:
  - subtree: src/Entity
  - subtree: src/DTO
vendor/bin/qmx check src/ --suppress-path='subtree:src/Entity' --suppress-path='regex:.*/DTO/.*'

CLI selectors are merged with those defined in the config file.


Method Comparison

Method When to use Advantages Disadvantages
Pre-commit Hook Local development Fast feedback, prevents bad commits Can be bypassed with --no-verify
GitHub Action CI/CD pipeline Automatic for all PRs, cannot be bypassed Slower than local
Docker Clean environment No local PHP needed, reproducible Requires Docker, slower
  • Small teams (1-5): Pre-commit Hook + GitHub Action
  • Medium teams (5-20): GitHub Action (required) + Pre-commit Hook (optional) + Docker for devs without PHP
  • Large teams (20+): GitHub Action with baseline (required) + Docker

Troubleshooting

Pre-commit Hook Not Working

Hook does not run on commit:

<!-- llms:skip-end -->

# Check that the hook exists and is executable
ls -la .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

qmx binary not found:

composer install
ls -la bin/qmx

Docker Permission Issues

# Linux with SELinux: add :z flag
docker run --rm -v $(pwd):/app:z qmx check src/