Skip to content

Codebase metrics

A measured snapshot of the Domain codebase and its submodules, counted with cloc. Charts show code lines (blank and comment lines excluded) unless stated otherwise.

Snapshot

Measured on the 3.x branch, 2026-10-21, with cloc 2.08. 492 files, 35,477 lines of code, 15,293 comment lines, 7,468 blank (58,238 lines in total). See Methodology to reproduce.

At a glance

Code Comment Blank Files Production Test
35,477 15,293 7,468 492 22,481 12,996

Production vs test

Domain ships 12,996 lines of test code backing 22,481 lines of production code, a 58% test-to-production ratio.

Lines by language

Language Code Comment Blank Files
PHP 23,347 15,087 5,179 322
Markdown 6,555 0 2,129 42
YAML 5,133 58 77 119
CSS 236 69 69 1
JavaScript 122 65 14 4
Text 41 0 0 2
JSON 25 0 0 1
Twig 18 14 0 1

Composition

Across all languages, code is 61% of the lines, comments 26%, and blank lines 13%. The comment share reflects Drupal's docblock conventions.

By submodule

Production (brass) and test (steel) code per submodule, largest first.

Submodule Production Test Total
domain 5,106 4,220 9,326
(project root) 6,763 1 6,764
domain_access 2,064 1,819 3,883
domain_alias 1,729 1,769 3,498
domain_source 1,427 1,910 3,337
domain_content 3,003 263 3,266
domain_config_ui 1,270 932 2,202
domain_config 519 866 1,385
domain_config_language 429 496 925
domain_config_language_ui 171 720 891

Test suite

Domain ships 124 automated test classes (311 test methods), counted by type below.

Test type Classes Methods
Functional 83 107
Kernel 34 196
FunctionalJavascript 6 6
Unit 1 2
Total 124 311

Architecture surface

What the module contains, counted across Domain and its submodules: the Drupal building blocks (services, plugins, hooks, routes, entities) that make up its public and internal API.

Element Count
Services 61
Event subscribers 0
Hook implementations 56
Routes 19
Permissions 24
Forms 9
Controllers 5
Content entity types 0
Config entity types 2
Config schema types 40
Plugins 49

Plugins break down by type as follows, largest first:

Methodology

Counts are produced with cloc, run from the project root over the files git ls-files reports, so a checkout that has installed vendor/, previewed the docs into site/ or pulled a node_modules/ counts the same as the archive a release ships. The Tugboat preview scaffolding in .tugboat/ is left out, and so are this page and its translations, because a page that counts itself changes the tree it just measured. The snapshot above names the cloc version, because cloc counts differently from one version to the next.

git ls-files | grep -v -e '^docs/metrics' -e '^\.tugboat/' > files.txt
cloc --list-file=files.txt

Each file is attributed to the nearest enclosing module (a directory with a *.info.yml); test-support modules under a tests/ path count as their parent's test code. A file is test code when its path contains a tests/ segment, production otherwise. Files outside every module, such as the README, this documentation and the CI and tooling configuration, are listed as the project root.

Test classes are counted by their directory under tests/src (Unit, Kernel, Functional, FunctionalJavascript); the method column counts each test-prefixed method, and each further one annotated @test or #[Test]. The architecture surface counts service definitions in *.services.yml (excluding aliases), route and permission keys in *.routing.yml and *.permissions.yml, #[Hook] attributes, plugin classes under src/Plugin/, forms and controllers under src/Form and src/Controller, entity-type attributes in src/Entity, and top-level types in config/schema/*.yml, all summed across the module and its submodules.

The charts are static inline SVG generated from the measured data, so they need no JavaScript or charting plugin. They are decorative and marked aria-hidden: every figure one of them draws is also in the table or the sentence beside it, so a screen reader gets the numbers rather than an image with no name. An img role carrying no accessible name is worse than no role at all, because it hides the labels inside the chart as well.