Skip to main content
Media OS can run directly in your PHP application. A controller, service, command or job can store files, create image variants and use staging without rendering FlexFileUpload or a Filament form. The shipped AI skill includes a dedicated references/media-os.md guide for this workflow. Component discovery describes rendered controls; it is not the service API reference.

Choose the right entry point

Minimal service-level storage

This example uses a trusted, existing local file and a configured private Laravel disk. It can run inside your application service; it creates no form field.
Permanent storage inspects the actual content against the policy. Your application still authorizes the operation and persists its own record reference. The receipt does not automatically create a gallery row or grant permission to read the file. For a normal HTTP request, validate the UploadedFile and use its valid local path with MediaSource::path(). MediaSource::upload() specifically accepts a Livewire temporary upload. See the HTTP request example.

Give the assistant a complete task

Images and Spatie

For disk-backed images, define named ImageConversion variants and choose synchronous or queued processing. Retain the returned bundle/receipt information needed by your application. A queued variant may not exist yet; configure a fallback and a worker with supported encoders. For Spatie, use the adapter with a persisted HasMedia model and SpatieOptions. Keep Spatie’s collections, conversions and queue configuration. An extra table for every conversion is not normally required. The Spatie guide shows direct service storage as well as field integration.

When storage happens before the record save

Use staging when the workflow needs it. Stage, promote and confirm are distinct operations; confirmation belongs after the durable record reference commits. A database rollback does not roll back disk/S3 writes. Derive lease ownership from trusted server context and follow the documented recovery contract for ambiguous outcomes. Read temporary uploads and recovery before implementing this flow. Do not copy an upload field’s completion hook into a service that does not mount that field. Pure server-side storage needs no browser asset initialization. A custom capture interface has a separate browser lifecycle and still needs server validation. For ordinary same-connection hasMany galleries, inspect HasManyMediaCollection, MediaRelationColumns and MediaRelationSnapshot. The related gallery guide covers explicit model columns, authorization and new-file admission, unique disk/path ownership, locked revision baselines, transaction/rollback, order and detach. sync() maps originals into SQL; it does not upload files, accept stages, convert or delete physical objects. Keep the mounted field’s native/custom commit-aware acceptance contract. Spatie remains a separate integration. Do not invent a disk uploader relationship() option or treat a revision as authorization.

Check the deployment configuration

Ask the assistant to run fff:media:doctor with the profile matching the actual workflow. Use --queued with the selected connection, queue and job timeout for native background conversions, and --custom-encoder when the application supplies its own encoder. The diagnostic report does not execute extension factories or modify storage. Treat unverified findings as checks still required; a valid configuration is not proof of a running worker or a successful upload/save/reopen workflow. For explicitly approved infrastructure checks, fff:media:probe --write can exercise a named --disk, named --lock-store and requested --format values. It creates synthetic diagnostic data and invokes the selected backend adapters. Do not run it as a read-only inspection or select production targets without the operator’s authorization. Its active probe report states what was exercised, any failed cleanup and the remaining deployment checks.
Last modified on October 20, 2026