I wanted a Simpler PHP Framework, So I Built One
My journey as a backend engineer
I've been a backend developer for years with PHP as core technology. I started PHP at first because my work demanded it. But as I am working, I fell in love with the simplicity of PHP. We can start from nothing and build a complete working web app with PHP. And also, we can integrate any frontend technology and framework with it such as Vue and React.
Laravel has been my goto framework to create web application in PHP. I loved it because it is simple, organized and offers almost everything I need to build an application without having to worry about the underlying infrastructure.
It provides a well-defined structure for organizing an application, along with its features like routing, middleware, database helpers, migrations, artisan command-line tool, frontend scaffolding etc. Laravel also has a very huge community of developers, there are always some package available for everything I need in general. This helps me focus on building the actual application instead of spending time on writing dependencies.
When I first started using Laravel, it was version 5. Today, Laravel has reached version 13, but I still find myself using Laravel 8 for almost all my projects. Part of the reason is simply familiarity. Since version 9, Laravel abandoned Laravel-Mix, my favuorite asset mixing tool and migrated to Vite. I absolutely loved using Laravel Mix. It gave me a simple way to manage my frontend assets without having to think too much about underlying build tooling. Also I started to feel that Laravel had become a little too noisy for the kind of applications I want to build. This doesn't mean newer versions of Laravel are bad. It has continued to evolve, and many of those changes make sense for the ecosystem.
The idea behind a new framework
The problem was that I started using Laravel by default for almost everything simply because of it's convenience.
An e-commerce Platform? Laravel.
A blog? Laravel.
An online learning platform? Laravel.
A personal portfolio website? Laravel.
Laravel became my default choice for building almost anything, big or small. It was familian, well-organized, and gave me almost everything I need out of the box.
Although Laravel is easy to work with, it is definitely not a lightweight framework. It comes with a lot of features, abstractions, and components, and all of that convenience comes with a cost. For a large enterprise application, that trade-off can make perfect sense. But for smaller applications and lightweight websites, that sometimes feel like an overkill.
Using full-featured framework to build a simple website feels like bringing a toolbox full of power tools just to hang a picture on the wall.
That's when a thought came to me. Why can't I build my own micro-framework for PHP?
I had been working with Laravel for years, so I already had a rough idea of how a modern PHP framework is structured and what happens behind the scenes. Laravel does a great job at simplifying all of this, but underneath those abstractions, it is still PHP. It doesn't magically introduce any new concepts, its still built on top of the same language concepts that are already available in the language itself.
So, I wanted to build a much smaller version of that. My goal was not to recreate Laravel. Laravel already has a micro framework called Lumen. Although its similar to Laravel, its more lightweight than Laravel. My idea was to build a small and simple foundation that could handle essentials required by a web application. If the developer need a particular feature for a project, he can write his own or use any third party package.
Meet Lunaris - A New Micro-Framework Built Using PHP
I've named the project Lunaris. Lunaris is a micro-framework built on top of PHP. The idea is to keep things simple while giving the developers complete freedom to extend the framework however they want.
The core philosophy
Lunaris is built around a few simple principles.
1. Keep third party dependencies to a minimum:
Laravel provides a huge ecosystem of features and integrations, which is one of the reasons it is so powerful. However that also means a huge part of the application is built around abstractions and external packages. I wanted to take a different approach with Lunaris.
The goal is to keep the core as self contained as possible and implement the fundamentals internally. This will help developer to understand, modify and extend the framework easily.
2. One Action Per One Route:
Unlike traditional Model-View-Controller pattern, Lunaris use Action based architecture. An Action receives everything it needs to handle the request, including input data, URL parameters and headers. This keeps the logic for a particular operation in one place and avoids additional request classes.
3. Keep it simple, avoid features the application doesn't need:
Lunaris keeps its core focused on essentials. Features such as database, mailers, caching and other integrations can be added externally when the project actually needs them. The goal is not to build a framework that does everything, the goal is to build a small foundation that can become whatever the application needs.
Architecture
my-project
├── system/
├── config/
│ └── vars.php
├── app/
│ └── Actions/
├── routes/
│ ├── web.php
│ └── console.php
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yaml
├── public/
│ ├── css/
│ ├── js/
│ └── index.php
├── storage/
│ ├── logs/
│ └── app/
├── views/
├── .env
├── bootstrap.php
├── composer.json
├── lunar
└── helpers.php
Core
All the core logic of Lunaris is implemented inside the system/ directory. This is where the framework's internal components and core functionality live.
Note: Although Lunaris is designed to give developers the freedom to modify and extend anything they want, the system/ directory should generally be treated as framework internals. Modifying it is not recommended unless you understand how the framework works and what the changes might affect.
Config
The config/ folder contains all the application configuration. System variables and their default values are defined in config/vars.php.
<?php
return [
"app" => [
"key" => fn() => env("APP_KEY", ""),
"version" => fn() => env("APP_VERSION", "1.0.0"),
"name" => fn() => env("APP_NAME", "Lunaris"),
],
"errors" => [
"notfound" => fn() => env("ERROR_NOT_FOUND", null),
"forbidden" => fn() => env("ERROR_FORBIDDEN", null),
"exception" => fn() => env("ERROR_EXCEPTION", null)
]
];
App
The app/ folder contains application specific code. Custom classes, actions, middlewares, models, services, commands, and other application logic can be organized here.
app/
├── Actions/
├── Middlewares/
├── Facades/
├── Models/
├── Commands/
├── Services/
└── ...
Routes
Routes are configured inside the routes/ folder.
routes/web.php- Define the application's web routes.routes/console.php- Register console commands.
Views
All application views are defined inside views/ folder.
Lunaris uses Native PHP Templates instead of introducing an external templating engine. This keeps the view layer simple and allows developers to use PHP directly when building their views.
Info: Developers can change the default templating engine and extend to whatever templating system they want.
Lunar
Lunar is the command line tool for Lunaris, similar to how Artisan works with Laravel.
It provides a convenient way to interact with the framework from the command line and can be used for tasks such as generating application components, running commands and managing the developer workflow.
Conclusion
Lunaris is still actively under development, and there is a lot more to build. This project started as a simple idea, I wanted a lightweight alternative for the smaller applications where using a full-featured framework felt like overkill.
More than anything, building Lunaris has been an interesting way for me to understand what actually happens behind the abstractions of a modern PHP framework. Things that seemed simple from the outside often turned out to have interesting design decisions behind them.
I am not trying to build a replacement for Laravel. Lavarel is still an excellent framework and will probably remain as my first choice for large projects that need it's ecosystem and features. Lunaris is simply my attempt to build something smaller, simpler and more flexible for the projects that starts small and wants complete control over the codebase.
There is still a long way to go, and the architecture will likely continue to evolve as I use it in real projects and discover things that need to be improved.
If you are interested in the project, you can find the source code and follow its development on Codeberg:
Repository: https://codeberg.org/lunarisphp/lunaris
The project is open source, so feel free to explore the code, experiment with it and share your thoughts and ideas.
This is only the beginning of Lunaris.