LavaLust: a small MVC framework for PHP with a query builder and JWT helpers
LavaLust is a lightweight Web Framework - (using MVC pattern) - for people who are developing web sites using PHP. It helps you write code easily using Object-Oriented Approach. It also provides set of libraries for commonly needed tasks, as well as a helper functions to minimize the amount of time coding.
At a glance
- What is it?
- LavaLust is a PHP framework that gives you routing, controllers, views, an ORM-like query builder and a REST helper with JWT checks, and it does so by staying small enough that you can read the whole thing, which is the argument the project makes explicitly.
- Who is it for?
- LavaLust is the right tool for a PHP developer who wants MVC structure without adopting a framework whose internals they cannot hold in their head, and for a teaching project where the layers should be visible rather than hidden. It is the wrong tool for a team that needs middleware, a code generator, relationship support in the query builder or a mature ecosystem of packages, because the roadmap lists all four as not yet done.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Minimal core, maximum control
LavaLust is described as a lightweight, fast PHP framework built for developers who want clean MVC architecture without unnecessary complexity or performance overhead, and the repository description calls it a lightweight web framework using the MVC pattern for people developing websites in PHP, with an object oriented approach, a set of libraries for commonly needed tasks and helper functions to reduce the time spent coding.
The philosophy section states the principle the project is built on, in a single line: minimal core, maximum control. The reasoning given is that modern frameworks add layers of abstraction that benefit large enterprise teams but get in the way of developers who want to understand exactly what their code is doing, so LavaLust provides structure and utilities without hiding the underlying logic.
That argument is aimed at four audiences, and the readme names them: rapid prototyping, where the point is to have an application running in minutes; learning MVC, where the point is to see how each architectural layer works; lightweight production apps that do not drag in unused dependencies; and teaching PHP development, where clear conventions and readable source matter more than features.
The stated use cases are a simple web application, a REST API, or a teaching project, and the feature table backs that up. MVC architecture with clean separation of models, views and controllers; built-in routing that maps requests to controllers with minimal configuration; reusable libraries and helpers for sessions, forms, validation and database access; a modular design that supports clean organisation as the application grows; first class REST API support using the framework's own conventions; and ORM-like models, described as simplified, readable database interaction without a heavy abstraction layer.
The requirements are correspondingly modest: PHP 7.4 or higher, a web server with URL rewriting support through an Apache .htaccess file or an Nginx configuration, and Composer if you want dependency management.
Getting it: clone, unzip, or run the Docker image
There are three ways to get the code, and the readme gives two of them as commands.
The first is a clone.
git clone https://github.com/ronmarasigan/lavalust.git
cd lavalustThe second is a direct download of the branch archive.
wget https://github.com/ronmarasigan/lavalust/archive/refs/heads/main.zip
unzip main.zipEither way, the next step is the same and it is the step people forget: point the web server at the project root and make sure mod_rewrite is enabled on Apache, or the equivalent on Nginx. Without URL rewriting the router never sees a request, and the symptom is a 404 on every path except the entry point.
The third route is the Dockerfile at the root of the repository, which is the most complete of the three because it encodes the server configuration as well.
FROM php:${PHP_VERSION}-apache
# Install PDO MySQL
RUN docker-php-ext-install pdo pdo_mysql
# Enable Apache mod_rewrite
RUN a2enmod rewrite
# Allow .htaccess overrides
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.confThe base image argument defaults to PHP 8.5, which is worth noticing against the stated requirement of PHP 7.4 or higher, so the container is deliberately on a current PHP. The image installs the PDO and pdo_mysql extensions, enables the rewrite module, flips AllowOverride from None to All so the .htaccess file is honoured, copies the application in, changes ownership to the www-data user, repoints the Apache document root at the public directory, and exposes port 80.
That document root change is the single most important line for a Docker deployment, and it is the one that matches the project structure.
Four files make a first request
The quick start is four steps, one per file, and it is short enough to read in a minute.
Routes live in app/config/routes.php and map a path and a method to a controller and an action.
$router->get('/', 'Welcome::index');
$router->get('/about', 'Welcome::about');
$router->post('/users/store', 'Users::store');The controller extends the framework's Controller class and renders a view, optionally with data.
class Welcome extends Controller
{
public function index()
{
$data['title'] = 'Home';
$this->call->view('welcome', $data);
}
}The view is an ordinary PHP template in app/views, with the data available as variables.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><?= $title ?></title>
</head>
<body>
<h1>Welcome to LavaLust Framework</h1>
</body>
</html>And the model extends Model, declares a table, and uses the query builder.
class User_model extends Model
{
protected $table = 'users';
public function getAll()
{
return $this->db->table($this->table)->get()->getResult();
}
}Two things are visible in that last snippet. The query builder is a fluent chain of table, where, get and a getResult call, which is the ORM-like layer the feature table refers to. And the model has a protected table property, so the table name lives in the model rather than in a global configuration, which is what makes the model layer feel like an ORM without pulling in one.
Note also the naming convention, with the class named User_model in the file app/models/User_model.php, and the controller naming the model explicitly when it is used.
The project structure tells you what is core and what is yours
The directory listing is short, and the annotations in it are the important part.
The app directory holds your code, split into config for application configuration such as the database and the routes, controllers, models, views, and a libraries directory for custom libraries and helpers. The scheme directory is labelled as the core framework files with a do not modify instruction, which is the one thing to know before you start editing. The public directory is the publicly accessible entry point, with index.php in it, and the runtime directory holds the cache, logs and uploads and has to be writable.
The runtime requirement is the operational detail that catches people out. A directory that holds uploads and logs has to be writable by the web server user, and in a container that means the ownership change the Dockerfile performs, and on a shared host it means a permission change that has to be redone after every deployment. It is also the directory that has to be excluded from version control, since it holds the logs and the user uploads.
The top level of the repository adds a few things that the readme's structure listing does not mention. There is a console directory and a lava file, which suggests a command line entry point, and the roadmap lists a CLI tool for generating controllers, models and migrations as an open item, so the console exists but the generator does not. There is a .env.example file, a .htaccess, a changelog.txt and a Dockerfile.
So the split is: your application in app, the framework you must not edit in scheme, the only web reachable directory in public, and the writable state in runtime.
REST endpoints, JWT and the environment file
The REST API support is described as first class, and the implementation follows the same conventions as the rest of the framework.
A controller loads the api library, constrains the HTTP method, requires a JSON web token, calls a model and responds with JSON.
class Api extends Controller
{
$this->call->library('api');
public function users()
{
$this->api->require_method('GET');
$auth = $this->api->require_jwt();
$this->call->model('User_model');
$users = $this->User_model->getAll();
$this->api->respond(['data' => $users]);
}
}The route for it is an ordinary route, which is the point of the conventions claim.
$router->get('/api/users', 'Api::users');The environment file is where the secrets live, and the example file shipped in the repository shows the full set of keys.
APP_NAME=Lavalust
APP_KEY=
APP_ENV=development
DB_DRIVER=
DB_HOST=
DB_PORT=
DB_USER=
DB_PASSWORD=
DB_NAME=
DB_CHARSET=
DB_PREFIX=
# For API
JWT_SECRET=The database configuration in app/config/database.php reads those values through getenv, with a fallback to an empty string, which is what keeps credentials out of the committed file. It is worth noticing that every value defaults to empty rather than to a development value, so a missing environment variable produces an empty string rather than a working default, and the JWT_SECRET and REFRESH_TOKEN_KEY entries for the API have no defaults at all.
The base URL is set separately in app/config/config.php, and the example in the readme points at http://localhost:3000/.
The roadmap is the honest list of what is missing
The most informative section of the readme is the roadmap, because it is the one place where the project says what it does not have.
There are four unchecked items: a CLI tool for generating controllers, models and migrations; middleware support; an improved query builder with relationship support; and enhanced error handling and debugging tools.
Each of those is a real gap for a particular kind of project. Middleware is the one that changes how a framework feels, because without it there is no standard place to put authentication, logging or CORS handling for every route, so that work ends up inside controllers. Relationship support in the query builder is the one that decides whether the ORM-like model layer stays small or starts growing into a full ORM. And the code generator is the item a team notices on day one, when they are creating their twentieth controller by hand.
The documentation site lists the topics that are covered, and they are extensive: installation and server configuration, routing with static, dynamic and grouped routes, controllers and request handling, models and the query builder, views with layouts and partials, the built-in libraries for sessions, form validation and file upload, helper functions, REST API development, and security best practices.
So the framework has depth in the areas it has, and gaps at the edges. For a small application or a teaching project, the shape of the gaps is irrelevant. For a long lived team application, the missing middleware and the missing relationship support are the two you would have to build yourself.
The contributing section is a conventional four step fork, branch, commit and pull request process, and it asks that changes follow the existing style conventions and include relevant documentation or comments.
Licence, release cadence and what the version history says
The licence is MIT, stated in the readme badge and the licence section, so the code can be used, modified and redistributed in commercial projects with the notice kept. The licence paragraph in the readme is cut short mid-sentence, which is a sign of a fast moving readme rather than a gap in the licence itself, and the LICENSE file at the root is the authoritative text. This is not legal advice.
The releases are frequent and the numbers are in the four range. Version 4.5.0 was published on 2026-02-09, 4.6.0 on 2026-10-02 and 4.7.0 on 2026-10-13, and the last push to the default branch was on 2026-10-13. The repository is not archived, and the eight month gap between 4.5.0 and 4.6.0 shows that the cadence is not strictly regular.
The version scheme deserves a note. It is a four series with a zero at the end of the minor part, so 4.6.0 rather than 4.6, and the semver implication is that the minor component is where behaviour can change. A framework at that version, with a roadmap that lists middleware and a code generator as still to do, is a project that is being used and reshaped at the same time.
There are two documentation locations, and they are different things. The homepage of the project is ronmarasigan.github.io, and the full documentation is published at lavalust.netlify.app, with the topics listed in the readme. The repository also carries a changelog.txt, which is where the detail behind those version numbers lives.
For a team weighing adoption, the useful summary is short. LavaLust is small, readable and current, it covers MVC, routing, a query builder, libraries for sessions and validation, and JSON responses with JWT checks, and it is honest in the readme about the four things it does not have yet.
Editorial conclusion
LavaLust is the right tool for a PHP developer who wants MVC structure without adopting a framework whose internals they cannot hold in their head, and for a teaching project where the layers should be visible rather than hidden. It is the wrong tool for a team that needs middleware, a code generator, relationship support in the query builder or a mature ecosystem of packages, because the roadmap lists all four as not yet done. Before adopting, read the runtime and public directories in the project structure and check that the writable paths work in your deployment, and confirm that the JWT and database settings in the environment file are the ones you want in production rather than the development defaults.
Frequently asked questions
What is LavaLust?
It is a lightweight, fast PHP framework that follows the MVC pattern, aimed at developers who want clean architecture without the abstraction layers of heavier frameworks. The stated principles are a minimal core and maximum control, and the intended uses are simple web applications, REST APIs and teaching projects.
What are the requirements for running LavaLust?
PHP 7.4 or higher, a web server with URL rewriting support through an Apache .htaccess file or an Nginx configuration, and Composer if you want dependency management. The Docker image in the repository is built on PHP 8.5 with Apache, with PDO MySQL and the rewrite module enabled.
How does LavaLust handle database access?
Models extend the Model class, declare a table through a protected table property and use a fluent query builder through the db property, for example a table, where and get chain ending in getResult. The database configuration in app/config/database.php reads its values from environment variables through getenv, so credentials stay out of the committed file.
Does LavaLust support REST APIs and authentication?
Yes. A controller loads the api library, restricts the method with require_method, requires a JSON web token with require_jwt and returns data through respond, with the route declared like any other. The environment example includes JWT_SECRET and REFRESH_TOKEN_KEY alongside the database settings.
What features does LavaLust not have yet?
The roadmap lists four open items: a CLI tool for generating controllers, models and migrations, middleware support, an improved query builder with relationship support, and enhanced error handling and debugging tools. The framework also requires the runtime directory to be writable for its cache, logs and uploads.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ronmarasigan-lavalust)Was this useful?