WaSQL is a database-driven PHP framework built for operational simplicity and developer velocity. While other frameworks require complex deployment pipelines, multiple tools, and specialized knowledge, WaSQL puts everything - code, deployment, monitoring, and ETL - in one place.
Modern web frameworks are powerful, but they come with operational overhead:
WaSQL solves these problems by storing everything in the database - not just your data, but your application code, templates, and configuration. This seemingly unconventional design choice enables powerful capabilities:
Instant Deployment
Export your entire application as a MySQL dump. Import it anywhere. Your code, logic, templates, and data move together as a unit.
Built-in Version Control
Visual diffs show exactly what changed between environments. Built-in sync tools let you push changes from dev to stage to production, or revert from production back to dev. Optional code review workflows require a second developer to approve changes before deployment.
Unified Platform
ETL pipelines, cron job management, user authentication, and application code all live in one system. No need to cobble together separate tools.
Operational Simplicity
Runs on a single server. No distributed systems, no Kubernetes, no specialized expertise required. Any PHP developer can understand and maintain it.
Battle-Tested at Scale
WaSQL runs production systems processing millions of records daily, managing thousands of concurrent cron jobs, and integrating multiple enterprise databases. In one case, it replaced a failed Kafka implementation at a billion-dollar company and was rebuilt from scratch in under two weeks.
In WaSQL, there are no "page files" to upload. Each page is a record in the _pages table with these fields:
/users)This design makes applications portable, version-controllable through the database, and deployable with built-in sync tools.
WaSQL uses the $PASSTHRU array for clean URL routing:
global $PASSTHRU;
switch(strtolower($PASSTHRU[0])){
case 'list':
setView('list',1);
return;
break;
case 'addedit':
$id = $PASSTHRU[1];
setView('addedit',1);
break;
default:
setView('default');
break;
}
No separate routes file needed - routing logic lives right in the controller.
Views are written directly in the body field using named view blocks:
<view:default>
<h1>Hello World</h1>
<a href="#" data-div="main_content" data-nav="/t/1/mypage/list"
onclick="return wacss.nav(this);">
Load Users
</a>
<div id="main_content"></div>
</view:default>
<view:list>
<?=mypageList();?>
</view:list>
<view:addedit>
<div><?=mypageAddedit($id);?></div>
</view:addedit>
<view:addedit_fields>
<div style="display:flex;flex-wrap: wrap;gap:10px;">
<div><label>Firstname</label>[firstname]</div>
<div><label>Lastname</label>[lastname]</div>
</div>
<div><label>Email Address</label>[email]</div>
</view:addedit_fields>
The controller calls setView() to determine which view block to display. WaSQL automatically loads the default view if no explicit setView() is called.
The functions field contains reusable helper functions that are called from controllers or views:
<?php
function mypageList(){
$opts=array(
'-table'=>'_users',
'_id_options'=>array(
'data-div'=>'centerpop',
'data-nav'=>'/t/1/mypage/addedit/%_id%',
'onclick'=>"return wacss.nav(this);"
)
);
return databaseListRecords($opts);
}
function mypageAddedit($id=0){
$opts=array(
'-table'=>'_users',
'-fields'=>getView('addedit_fields')
);
// Go into edit mode if $id is not zero
if($id > 0){
$opts['_id']=$id;
}
return addEditDBForm($opts);
}
?>
WaSQL provides powerful helper functions like databaseListRecords() that generate full list views with sorting, pagination, and actions, and addEditDBForm() that automatically creates forms and handles add/edit operations.
WaSQL abstracts SQL entirely with intuitive helper functions:
// Fetch users with sorting and limit
$users = getDBRecords([
'-table'=>'_users',
'-order'=>'name',
'limit'=>50
]);
// Retrieve a single record by ID
$rec = getDBRecordById('_users', 54);
// Add a new user
$id = addDBRecord([
'-table' => '_users',
'name' => 'John Doe'
]);
// Update a user
$ok = editDBRecordById('_users', $newId, [
'email' => 'john@example.com'
]);
// Generate a complete add/edit form
$opts = ['-table'=>'test'];
return addEditDBForm($opts);
Everything returns associative arrays (not objects), making it easy to pass data into views or convert to JSON for JavaScript.
While your code lives in the database, you can still use your favorite IDE. PostEdit monitors local files and automatically updates database records when files change.
Use the p.bat alias to sync database records to local files, edit them in your IDE, and PostEdit will push changes back to the database. It includes conflict detection - if another developer changed a record after you pulled it, PostEdit prevents your change and alerts you.
WaSQL's built-in sync tools let you:
This replaces Git, CI/CD pipelines, and deployment scripts with a unified, visual workflow.
WaSQL is written in PHP but also supports embedded Python, Perl, Lua, R, Tcl, and Node.js. Global variables like $_REQUEST, $_SESSION, $_SERVER, $CONFIG, and $USER are available to all languages. You can even code in multiple languages on a single page.
WaSQL excels at data integration, supporting:
Built-in cron management with visual monitoring makes it ideal for ETL pipelines. View active jobs, memory usage, execution logs, and scheduling all from the admin interface.
Ideal for:
Not ideal for:
WaSQL's design may seem unconventional, but it's optimized for what matters most: building applications quickly, deploying them reliably, and maintaining them easily over time. The database-centric approach that seems limiting at first becomes liberating once you embrace it.
Everything is in one place. Everything is queryable. Everything is deployable. Everything just works.
Ready to learn more? Check out the Advanced Concepts guide for deployment workflows, scaling strategies, and production best practices.