Skip to content

Tooling Choices

Context

This project is a challenge that mirrors a DAM (Digital Asset Management) stack using PHP, GraphQL and MySQL with no framework. We need a consistent set of tools for quality, safety and CI.

Decisions

webonyx/graphql-php

The de facto PHP GraphQL server library. Lets us build a schema without pulling in a framework. Matches the kind of stack we want to match.

monolog/monolog

Structured logging library for PHP. Used to emit JSON log lines to stdout/stderr, making logs consumable by any log aggregator (Loki, CloudWatch, etc.) without coupling to a specific platform.

vlucas/phpdotenv

Standard way to load .env files into PHP's $_ENV/getenv(). Keeps credentials out of source code and makes the app configurable across environments with no extra infrastructure.

phpstan/phpstan

Static analyser for PHP. Fast and integrates well with CI.

phpunit/phpunit

The PHP testing standard. Integrates with coverage reporting, mutation testing and CI natively. No learning overhead for reviewers.

friendsofphp/php-cs-fixer

Automatically enforces a consistent code style (PSR-12 by default). Running in --dry-run mode in CI blocks style regressions without requiring opinion from reviewers.

vimeo/psalm

Adds taint analysis on top of static analysis, catching SQL injection and XSS paths that phpstan alone does not cover. Used as a secondary security-focused analysis pass.

squizlabs/php_codesniffer

Complements php-cs-fixer by enforcing project-specific standards (doc blocks, naming conventions) that a formatter alone cannot check.

infection/infection

Mutation testing tool that measures test quality, not just coverage. Introduces small code mutations and checks that at least one test fails, ensuring tests actually guard against regressions.

GitHub CodeQL

Free SAST built into GitHub Actions. Scans for OWASP Top 10 patterns (SQL injection, XSS, SSRF, etc.) in PHP without requiring a separate external service.

composer audit

Built-in Composer command that checks installed packages against the PHP Security Advisories database.

Docker / docker-compose

Provide a reproducible local development stack using docker-compose that includes MySQL and Redis. Local developers and reviewers can boot the same services the CI uses, lowering configuration friction and avoiding environment-specific bugs.

This decision directly supports the project's TTFHW (Time To First Hello World) principle: a developer must be able to go from a fresh clone to a running API with exactly two commands:

cp .env.example .env
docker compose up

Consequences

Local development and TTFHW

Local development is supported by docker-compose.yaml, which brings up app, nginx, db (MySQL), and redis. This enables the repository's CI and local checks to run without external services.

  • Mutation testing (infection) may be slow on large suites — run on schedule, not every push.