Monorepo of PHP (Symfony bundles) + TypeScript/JS (Stimulus controllers) packages.
Each package: src/<Package>/, PHP in src/, JS in assets/.
Package manager: pnpm (v11, via Corepack). Node 22. PHP >= 8.4.
# JS/TS — from repo root
pnpm install
pnpm run build # build all packages (tsdown)
# JS/TS — single package
pnpm run build --filter @symfony/ux-autocomplete
# PHP — per-package
cd src/Autocomplete && composer install# All tests for a package
cd src/Autocomplete
php vendor/bin/phpunit
# Single test file
php vendor/bin/phpunit tests/Unit/SomeTest.php
# Single test method
php vendor/bin/phpunit --filter testMethodName# All packages from root
pnpm run test:unit
# Single package
cd src/Autocomplete/assets
pnpm run test:unit
# Single test file
pnpm exec vitest --run test/unit/some.test.ts# All packages from root
pnpm run test:browser
# Single package
cd src/Autocomplete/assets
pnpm run test:browser
# Single test file
pnpm exec playwright test test/browser/some.test.ts
# Interactive UI mode
pnpm run test:browser:ui# JS/TS lint (oxlint)
pnpm run lint
pnpm run lint:fix
# JS/TS/MD format (oxfmt)
pnpm run fmt
pnpm run fmt:check
# PHP code style (PHP-CS-Fixer, @Symfony ruleset)
php vendor/bin/php-cs-fixer fix
# Twig templates
php vendor/bin/twig-cs-fixer lint- Ruleset:
@Symfony+@Symfony:riskyvia PHP-CS-Fixer (.php-cs-fixer.dist.php) declare(strict_types=1): not enforced globally; follow file conventions- Namespaces: PSR-4, e.g.
Symfony\UX\Autocomplete\... - Classes: prefer
final. PascalCase. Noreadonlyclasses. - Methods: camelCase, typed params + return types
- Properties: typed, constructor promotion +
readonlywhere appropriate - Imports: one
useper line, grouped (classes, traits, interfaces). No aliasing unless conflicts. - File header: every PHP file needs Symfony license header (auto-fixed by CS fixer):
/* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */
- Error handling: throw specific exceptions (InvalidArgumentException, LogicException, RuntimeException). No generic
\Exception. - Doc comments:
@authoron classes. PHPDoc only when types can't express contract (generics, union details). No duplicate type info.
- Formatter: oxfmt (
.oxfmtrc.json) - Linter: oxlint (
.oxlintrc.json), default rules - Module system: ESM (
"type": "module") - Imports: named imports preferred,
typekeyword for type-only (import type { ... }) - Naming: camelCase vars/funcs, PascalCase classes/interfaces/types
- Stimulus controllers: extend
Controllerfrom@hotwired/stimulus,static values = {}pattern,declare readonlyfor value props - Tests: Vitest +
@testing-library/dom+@testing-library/jest-dom. Playwright for browser.
src/
<Package>/
.github/ # CI workflows, PR template, for subtree split
.gitignore
.gitattributes
src/ # PHP source (PSR-4)
tests/ # PHPUnit tests
assets/ # Frontend assets
src/ # TypeScript source
dist/ # Built output (committed!)
test/ # JS tests (unit/ and browser/)
package.json
vitest.config.mjs
playwright.config.ts
config/ # Symfony DI service definitions
composer.json
phpunit.xml.dist
apps/
demo-native/ # Symfony app for manual testing and demos of Symfony UX Native
e2e/ # Symfony app for Playwright browser tests
encore/ # Symfony app for testing Webpack Encore and `npm install` integration
- Dist files committed: after TS source change, run
pnpm run build+ commitdist/. - pnpm workspaces:
src/*/assetsandsrc/*/src/Bridge/*/assets. - Peer dependency matrix: JS unit tests may run against multiple peer dep versions (via
bin/unit_test_package.sh). - PHPStan: only configured for
src/Turbo(phpstan.dist.neon). - Snapshot tests: Toolkit uses PHPUnit snapshots — update with
php vendor/bin/simple-phpunit -d --update-snapshots.
- Write tests for new features/bug fixes; all tests pass locally, when applicable (pure JS change → skip PHP tests).
- Run
oxfmt+oxlint(non-PHP code style/lint clean), - Run
php-cs-fixer(PHP code style clean), - Run
twig-cs-fixer(Twig formatted), - Run all tests for affected package(s) (PHPUnit, Vitest, Playwright):
- JS unit-tests:
package.jsoncan be modified to test against multiple peer dep versions — don't commit temppackage.jsonchanges.
- JS unit-tests: