Creating Custom Filesystem Adapters in Laravel

March 20th, 2025 • 3 minutes read time

Laravel provides a bunch of filesystem drivers, but what if you need to create your own to support another service, or even overide the way storage works?

Luckily, it's super easy to create your own filesystem drivers in Laravel. This step-by-step guide will walk you through the entire process.

First, create an adapter class that extends the FilesystemAdapter interface. In this example, I'm creating a Dropbox adapter.

namespace App\Filesystem;

use League\Flysystem\FilesystemAdapter;

class DropboxAdapter implements FilesystemAdapter
{
    //
}

You'll then need to implement every method of the FilesystemAdapter interface. Your adapter class should end up looking like this:

namespace App\Filesystem;

use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;

class DropboxAdapter implements FilesystemAdapter
{
    public function fileExists(string $path): bool
    {
        // TODO: Implement fileExists() method.
    }

    public function directoryExists(string $path): bool
    {
        // TODO: Implement directoryExists() method.
    }

    public function write(string $path, string $contents, Config $config): void
    {
        // TODO: Implement write() method.
    }

    public function writeStream(string $path, $contents, Config $config): void
    {
        // TODO: Implement writeStream() method.
    }

    public function read(string $path): string
    {
        // TODO: Implement read() method.
    }

    public function readStream(string $path)
    {
        // TODO: Implement readStream() method.
    }

    public function delete(string $path): void
    {
        // TODO: Implement delete() method.
    }

    public function deleteDirectory(string $path): void
    {
        // TODO: Implement deleteDirectory() method.
    }

    public function createDirectory(string $path, Config $config): void
    {
        // TODO: Implement createDirectory() method.
    }

    public function setVisibility(string $path, string $visibility): void
    {
        // TODO: Implement setVisibility() method.
    }

    public function visibility(string $path): FileAttributes
    {
        // TODO: Implement visibility() method.
    }

    public function mimeType(string $path): FileAttributes
    {
        // TODO: Implement mimeType() method.
    }

    public function lastModified(string $path): FileAttributes
    {
        // TODO: Implement lastModified() method.
    }

    public function fileSize(string $path): FileAttributes
    {
        // TODO: Implement fileSize() method.
    }

    public function listContents(string $path, bool $deep): iterable
    {
        // TODO: Implement listContents() method.
    }

    public function move(string $source, string $destination, Config $config): void
    {
        // TODO: Implement move() method.
    }

    public function copy(string $source, string $destination, Config $config): void
    {
        // TODO: Implement copy() method.
    }
}

The hardest part? Actually filling in all of these methods to connect up to the storage solution you're building for. I'll leave that up to you!

Now you have your custom adapter, you'll need to add it by extending Laravel's storage.

In the AppServiceProvider boot method, do the following:

use App\Filesystem\DropboxAdapter;

class AppServiceProvider extends ServiceProvider
{
    //...

    public function boot(): void
    {
        Storage::extend('dropbox', function (Application $app, array $config) {
            return new FilesystemAdapter(
                new Filesystem($adapter = new DropboxAdapter(), $config),
                $adapter,
                $config
            );
        });
    }
}

Lastly, in config/filesystem.php, register your new adapter under the disks section of the config.

'disks' => [
    'user' => [
        'driver' => 'dropbox'
    ],
]

Great, now we're ready to use this when dealing with files. Let's take a look.

Depending on how you're storing/accessing files, there are a few ways to specify our new disk.

If you're uploading files directly from Laravel's Request, you may do this, specifying your new disk:

$request->file('file')->store('files', ['disk' => 'dropbox']);

Or, if you're directly working with the Storage facade, you can use the disk method to choose the disk ahead of any action you're about to take:

return Storage::disk('dropbox')->download($file->path);

Now that you've created your own filesystem adapter and have it registered as a disk, choose that disk before taking any action!

As I mentioned earlier, the most difficult part about creating a custom filesystem adapter with Laravel is actually implementing all the methods required by the FilesystemAdapter.

Now you know how to create a custom filesystem adapter in Laravel though, I'll leave you to build your own implementation. Good luck!

If you found this article helpful, you'll love our practical screencasts.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first!