---
title: "Library Skeleton"
description: "Skeleton of a Derafu Library"
type: "docs"
category: "doc"
tags: [php]
authors: [Anonymous]
date: "2026-10-08"
last_update: "2026-10-08"
time_minutes: 2
draft: false
unlisted: false
url: "https://www.derafu.dev/docs/core/library-skeleton"
---

# Skeleton of a Derafu Library

[![GitHub](https://img.shields.io/badge/github-derafu%2Flibrary--skeleton-blue?logo=github)](https://github.com/derafu/library-skeleton)

`derafu/library-skeleton` is the starting point of a new Derafu library. Everything is in its repository: there is no installer.

```shell
composer create-project derafu/library-skeleton my-library --stability=dev
```

## What it has

- `composer.json` with the scripts that every Derafu library has: `tests`, `phpcs`, `phpcs-fix`, `phpstan` and `docs`.
- The tools and their configuration: PHP CS Fixer, PHPStan (level 5, over `src` and `tests`) and PHPUnit (strict: a warning, a risky test or a deprecation fails the run, and every test says what it covers). See [Code Quality](https://www.derafu.dev/docs/core/library-skeleton/code-quality).
- The CI (`.github/workflows/ci.yml`), the `.gitignore` and the `LICENSE`.
- An example class with its test, `src/Teapot.php` and `tests/src/TeapotTest.php`. Delete them when the library has code of its own.
- The pattern of the translations: the exceptions are translatable, the Spanish catalogue is in `resources/translations/errors+intl-icu.es.php`, the provider is `src/Translation/ProjectTranslationResourceProvider.php`, the wiring for `symfony/dependency-injection` is in `resources/config/project-services.yaml`, and `tests/src/Translation/ProjectMessagesTest.php` audits that every message has its translation, that the catalogue has nothing unused and that every exception is translatable. See [Translation](https://www.derafu.dev/docs/core/translation).

## To use it

1. Edit `composer.json`: change the name, the description and the namespaces (`Derafu\Project\` and `Derafu\TestsProject\`), and change `"type": "project"` to `"type": "library"`. The skeleton is a `project` so it can be created with `composer create-project`, but the library you write is a `library`. Then change the names in the files of `src` and `tests`.
2. Rename `ProjectTranslationResourceProvider` and its catalogue.
3. Write the library. The message of an exception is a literal in English (the id of the translation) with its parameters, and has its entry in the catalogue.
4. Run `composer tests`, `composer phpstan` and `composer phpcs`.

## A site is not a library

`derafu/library-skeleton` does not depend on [`derafu/foundation`](https://www.derafu.dev/docs/core/foundation), and it has no templates, `public/` or assets. To start a web site use [`derafu/website-skeleton`](https://www.derafu.dev/docs/core/website-skeleton).



---

## Code Quality

Code Quality Tools

# Code Quality Tools

`derafu/library-skeleton` (and `derafu/website-skeleton`, for sites) come with pre-configured code quality tools to ensure consistent code style and identify potential issues early in development. This document explains how to use these tools effectively.

## PHP CS Fixer

PHP CS Fixer is a tool that automatically fixes PHP coding standards issues in your code according to rules you define.

### Configuration

The configuration is defined in `php-cs-fixer.php` at the root of your project. Key features include:

- PSR-12 coding standards by default.
- Strict type declarations enabled.
- Automatic array syntax conversion to short syntax.
- Ordered imports.
- Modern PHP features optimization (e.g., arrow functions).
- PHPUnit strict assertions.

### Usage

Run PHP CS Fixer to check code style issues:

```shell
vendor/bin/php-cs-fixer fix --dry-run --diff
```

Fix code style issues automatically:

```shell
vendor/bin/php-cs-fixer fix
```

## PHPStan

PHPStan is a static analysis tool that finds bugs in your code without running it. It&#039;s focused on finding errors in code logic.

### Configuration

The configuration is defined in `phpstan.neon` at the root of your project. By default, it:

- Sets analysis level to 5 (out of 9)
- Analyzes code in the `src` and `tests` directories
- Allows no exceptions: there is no `ignoreErrors` and no `@phpstan-ignore` in the code. If PHPStan reports something, the code is fixed (a type guard, a better type), not silenced.

### Levels Explained

- Level 1: Basic checks.
- Level 2: Possibly undefined variables.
- Level 3: Return types, phpdocs.
- Level 4: Type hints.
- Level 5: Basic dead code detection.
- Level 6: Detecting unreachable code.
- Level 7: Union types.
- Level 8: More precise analysis
- Level 9: Mixed type detection

### Usage

Run PHPStan analysis:

```shell
vendor/bin/phpstan analyse
```

## PHPUnit

PHPUnit is the standard testing framework for PHP applications.

### Configuration

The configuration is defined in `phpunit.xml` at the root of your project. Key features include:

- Test coverage reporting enabled.
- Strict mode enabled: a warning, a notice, a deprecation or a risky test (one that changes the global state or does not assert anything) fails the run, and the run stops at the first failure.
- Every test class says what it covers (`#[CoversClass]`), and a test that covers something else is reported.
- A test is never skipped, excluded or softened to make the run pass: a failing test stays red until the code or the test is fixed.
- Test results output to `var/tests-coverage.txt` and `var/tests-coverage.xml`.
- Test documentation output to `var/tests-testdox.txt`.

### Directory Structure

- `tests/src/`: Unit tests for your source code.
- `tests/fixtures/`: Test data and fixtures.

### Usage

Run the test suite:

```shell
vendor/bin/phpunit
```

Generate test coverage reports:

```shell
vendor/bin/phpunit --coverage-html var/coverage
```

## Translations

A package whose exceptions or templates show text to people has a test that audits its messages, with the tools of `Derafu\Translation\Lint` and `Derafu\Twig\Lint` (see [Translation](https://www.derafu.dev/docs/core/translation/lint)). The test fails when:

- A message has no translation in the Spanish catalogue.
- The catalogue has a message that nothing uses.
- An exception of the package is not translatable.

`derafu/library-skeleton` has the example in `tests/src/Translation/ProjectMessagesTest.php`, and `derafu/website-skeleton` the one of a site in `tests/src/Translation/WebsiteMessagesTest.php`.

## Lint Code

Some packages include code whose only purpose is to examine other code and report problems: for example, to find the routes that the templates refer to, or the messages that the code builds to be translated, so a test can check that they exist. That code goes in a namespace named `Lint`, with the package as its prefix: `Derafu\Twig\Lint`, `Derafu\Translation\Lint`, `Derafu\Routing\Lint`, `Derafu\Content\Lint`.

`Lint` names a role, like `Contract` or `Exception`, and not a subject of the package, so every package can use the same word. The rule is:

- **It is never part of what the package does when it runs.** The runtime code does not call it. It is for tools and tests.
- **It finds, it does not decide.** A lint class extracts facts (what a template refers to) and leaves the verdict to whoever uses it, because whether something is a problem depends on which files belong together, and only the user knows that.
- **It fails loudly.** If it can not read something (a template that does not parse), it raises an error. Returning nothing would look the same as a clean result.

Its tests go in `tests/src/Lint/`.

## Integration with CI/CD

These tools are integrated into the CI workflow (`.github/workflows/ci.yml`), which automatically runs on each push to the repository. This ensures that code quality standards are maintained throughout development.

## Best Practices

1. **Run tools locally before committing**: This helps catch issues before they enter the codebase.
2. **Gradually increase PHPStan level**: Start with level 5 and work toward higher levels as your project matures.
3. **Aim for high test coverage**: Write tests for all critical code paths.
4. **Update rules as needed**: Customize tool configurations to match your project&#039;s specific requirements.





---
Last updated on 08/10/2026
#php
