Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Yaml Laravel Package

pragmarx/yaml

PragmaRX YAML is a lightweight Laravel and PHP package for parsing and dumping YAML. It wraps Symfony's YAML component with a simple service provider and facade, making it easy to load YAML config or translation files, convert YAML strings to arrays, and export arrays back to YAML.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify it's active

composer require pragmarx/yaml
php artisan config:clear

On Laravel 5.5+ the service provider is auto-discovered. On older apps, register PragmaRX\Yaml\ServiceProvider (check the package's composer.json extra.laravel.providers key for the exact class name in your installed version) in config/app.php.

Where to look first

  1. The package's service provider — it is the whole package. It swaps Laravel's LoadConfiguration bootstrap for one that also scans config/ for *.yaml / *.yml files. Understanding that override is understanding the package.
  2. Its published config (if any) for the file extension and merge behaviour.
  3. vendor/pragmarx/yaml/src/ — it's small; read it end-to-end before relying on it in production.

First use case

Take one static, deeply nested PHP config file and convert it. Good candidates: permission maps, menu trees, feature flags, pricing tables — anything with structure but no closures or env() calls.

# config/permissions.yaml
roles:
  admin:
    - users.create
    - users.delete
  editor:
    - posts.create
    - posts.update
// anywhere
config('permissions.roles.editor'); // ['posts.create', 'posts.update']

Verify with php artisan tinker → config('permissions'). If it returns null, the file wasn't picked up: check the extension, the filename (permissions.yaml must map to the permissions config key), and that the provider is actually registered (php artisan about on newer Laravel, or dump app()->getLoadedProviders()).

Implementation Patterns

Additive, not replacement. The sane production pattern is: PHP files keep anything dynamic (env(), config() calls, class names, closures); YAML files carry static structure. Mixing both in one logical config namespace is fine as long as you know the merge order — verify whether YAML wins over an equally-named .php file, and never ship both.

Structure-heavy config. YAML shines for nested arrays and sequences. Laravel flattens any config array to dot access, so design YAML with the dot path you'll actually type in mind:

# config/features.yaml
billing:
  invoices:
    enabled: true
    providers:
      - stripe
      - paddle

→ config('features.billing.invoices.providers.1').

Config-driven loops. Sequences become zero-indexed arrays, which is the natural fit for foreach over "things to register":

webhooks:
  - event: order.created
    url: https://example.com/hooks/orders

Then a service provider reads config('webhooks') and registers listeners. This keeps the "what" declarative and version-controlled, and the "how" in code.

Manual loading when the loader is too coarse. If you want YAML somewhere other than config/ (e.g. resources/data/), or want environment-specific YAML, skip the package's bootstrap override and parse directly with the underlying symfony/yaml:

$data = \Symfony\Component\Yaml\Yaml::parseFile(
    resource_path("data/pricing.{$env}.yaml"),
    \Symfony\Component\Yaml\Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE
);
config(['pricing' => array_replace_recursive(config('pricing', []), $data)]);

Do this in a service provider's register() so it runs before anything reads the config.

CI/CD and config caching. php artisan config:cache serialises the resolved array, so cached deployments never touch the YAML parser. Treat YAML edits exactly like PHP config edits: rebuild the cache in your deploy step, always. In tests, prefer config()->set() over mutating YAML fixtures — it's faster and keeps the parser out of your test path.

Migration strategy. Convert one file per PR, keep the PHP version in git history, and diff the resolved array:

// before/after
dd(config('permissions'), require config_path('permissions.php'));

That diff is your entire safety net for this package. Use it.

Gotchas and Tips

No PHP execution inside YAML. This is the headline limitation. No env(), no config(), no closures, no ::class. Any config that varies per environment must stay in PHP or be handled by the manual-load pattern above with a filename convention. Do not attempt to fake env substitution with placeholder strings — there's no built-in interpolation here.

YAML 1.1 type coercion bites. Unquoted yes, no, on, off, y, n parse as booleans. Unquoted 1.10 becomes a float 1.1. Leading-zero strings lose their zeros. Dates may parse as DateTime depending on flags. Quote anything that is semantically a string: "yes", "1.10", "0123".

Indentation errors are the whole debugging story. Tabs are forbidden; mixing tabs and spaces throws. Symfony's parser gives you a line number in the ParseException — read it, don't guess. Fast isolated check without booting Laravel:

php -r "var_dump(Symfony\Component\Yaml\Yaml::parseFile('config/app.yaml'));"

Name collisions. A config/foo.yaml and config/foo.php both targeting the foo key will merge in whatever order the loader decides — this is precisely the kind of thing that silently works in dev and inverts in a later Laravel version. Pick one format per config key, always.

Silent failures when cached. With bootstrap/cache/config.php present, a broken YAML file is invisible: nothing parses it. A missing-file or syntax bug will only surface in an uncached environment. Run php artisan config:clear locally before claiming something works, and add a config:cache step to CI to catch it.

Package staleness is your real risk. Last release May 2020, ~114 stars, zero dependents. Expect the service provider to reference framework internals (LoadConfiguration, FileLoader, container bootstrapping) that have shifted since Laravel 8/9. Check composer why-not laravel/framework ^10 / ^11 before adopting, and expect to either constrain your Laravel version, add a Composer replace/fork under a VCS repo, or pin symfony/yaml to a compatible major. Audit the provider against your Laravel version's LoadConfiguration in vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/ — the diff tells you if it will break.

Debugging checklist, in order: is the provider loaded → does the filename map to the expected config key → does the YAML parse in isolation → is the config cache stale → is a same-named .php file winning.

Extension points. The service provider is the seam: extend or replace its loader class if you need a different search path, extra .yml handling, or pre-parse transformation. Because the package is small and unmaintained, subclassing the provider in your own app is usually more durable than waiting for upstream — and cheaper than a hard fork.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource