تطوير الويب 10 Jun 2026 · 6 min read

Laravel Paper: A Flat-File Eloquent Driver for Files Instead of a Database

The Laravel Paper package lets you use the Eloquent interface to treat Markdown and JSON files as database records, with no migrations or separate connection. A practical guide with code examples.

Laravel Paper: A Flat-File Eloquent Driver for Files Instead of a Database

What if you could use Laravel's familiar Eloquent interface to work with Markdown and JSON files on disk, with no database, no migrations, and no separate connection? That is exactly what the Laravel Paper package, by Jacob Jørgensen, offers, adding flat-file driver support to Eloquent. The idea is to treat your files as if they were database records, which is ideal for documentation, product catalogs, and small content management systems where a traditional database would be unnecessary overhead.

The package requires PHP 8.4 or newer and Laravel 12 or 13, relies on modern PHP 8 features, and focuses on type safety. The elegant part is that it needs only a single trait and two attributes to turn any model into a file-backed one.

Installation

The package is installed via Composer with a single command:

composer require jacobjoergensen/laravel-paper

Turning Files Into Models

You start by placing Markdown files in a directory, say content/posts/, with metadata in the file's YAML frontmatter:

---
title: Building a Blog with Flat Files
slug: flat-file-blog
published: true
date: 2024-03-15
tags: [laravel, markdown]
---

Your Markdown content goes here...

Then you create a regular model and add the Paper trait along with the Driver and ContentPath attributes to specify the driver type and the file path:

use Illuminate\Database\Eloquent\Model;
use JacobJoergensen\LaravelPaper\Attributes\ContentPath;
use JacobJoergensen\LaravelPaper\Attributes\Driver;
use JacobJoergensen\LaravelPaper\Paper;

#[Driver('markdown')]
#[ContentPath('content/posts')]
class Post extends Model
{
    use Paper;
}

That is all. No database connection, no schema, no migrations.

Querying the Data

Because the driver implements the Eloquent interface, you can use the standard Query Builder methods to filter and sort exactly like any other model:

// Get all published posts ordered by date descending
$posts = Post::where('published', true)
    ->orderBy('date', 'desc')
    ->get();

// Find by slug
$post = Post::where('slug', 'flat-file-blog')->first();

// Filter by a tag within an array
$laravelPosts = Post::whereContains('tags', 'laravel')->get();

Additional query methods useful for textual content are also available, such as whereLike to match a substring within a field, and whereAny to search a value across several fields at once.

Working With JSON Files

The same logic applies to JSON files; you simply change the driver type to json. Suppose a team member file:

{
    "name": "Jacob Jørgensen",
    "role": "Developer",
    "github": "jacobjoergensen"
}
#[Driver('json')]
#[ContentPath('content/team')]
class TeamMember extends Model
{
    use Paper;
}

Then you query it as usual:

$team = TeamMember::all();
$devs = TeamMember::where('role', 'Developer')->get();

File Naming and the Primary Key

The rule is simple and clever: the filename (without extension) becomes the model's primary identifier. So the following posts directory:

content/posts/
├── hello-world.md        → id: "hello-world"
├── my-second-post.md     → id: "my-second-post"
└── draft-post.md         → id: "draft-post"

lets you fetch any post directly by its identifier:

$post = Post::find('hello-world');

To change the identifier, you just rename the file. And if you want a URL that differs from the filename, you add a field in the frontmatter and route based on it.

Displaying Content in the View

In Blade files, you treat the models like any Eloquent collection, converting Markdown content to HTML via Laravel's standard helper:

@foreach($posts as $post)
    <article>
        <h2>{{ $post->title }}</h2>
        <time>{{ $post->date }}</time>
        <div>{!! Str::markdown($post->content) !!}</div>
    </article>
@endforeach

When to Use It and When to Avoid It

Laravel Paper is an excellent choice when content is relatively static and version-controllable through Git: a blog, documentation, marketing pages, or a small catalog. Its advantage is that you edit content as simple text files and track its changes in your repository without needing a control panel or a database. But if your project requires heavy concurrent writes, complex relationships across thousands of records, or high-performance queries over large, constantly changing data, a traditional database remains the better choice; the filesystem was not designed for heavy concurrent read-write loads.

Conclusion

Laravel Paper offers an elegant, Laravel-idiomatic solution to a common problem: managing lightweight content without the burden of a full database. Thanks to its reliance on the familiar Eloquent interface, the learning curve is nearly nonexistent for any Laravel developer. As a young package (with active releases in 2026), it is best to try it in a side project first and read its official documentation to follow newly added features such as file relationships and write operations.

Was this article helpful?

Share this article

1 share

Tags: #Laravel#Eloquent#PHP#Laravel Paper#Markdown#Flat-file

More articles