dotsystems / dotapp
DotApp PHP framework - a complete, scalable and efficient tool for web applications.
Requires
- php: >=7.4
This package is not auto-updated.
Last update: 2026-08-18 23:21:55 UTC
README
Full documentation is available at:
DotApp PHP Framework 2.0 is released — and it is fully AI READY. After a long stretch of demanding real-world use, the framework is ready for production: internals are tighter, bugs found under heavy load are gone, and the AI rulebook (AIRULES/ + AIRULES-DACORE/) was stress-tested in Cursor with Grok 4.5 and Grok 4.6. The apps those sessions produced are secure, snappy, and ready to ship — even though these models stay cheap to run. Documentation is being prepared on dotapp.dev — that remains the official site.
DotApp is an ultra-fast, powerful, and scalable PHP framework for modern web applications. It stays lean yet handles very large apps, with clean structure that's easy for humans, vibe coders, and AI assistants to read, learn, and build on. It ships with a built-in Bridge for seamless PHP↔JS calls and an ultra-light reactive frontend library, alongside fast routing and templating.
DACore, the official administration module, is available free — login, 2FA, rights, menus, and an admin shell that your own modules plug into. Details stay on dotapp.dev.
Proudly made in Slovakia 🇸🇰
🔹 Minimal and efficient
🔹 PSR-4 autoloading support
🔹 Modular architecture
🔹 Flexible templating system
🔹 Fully AI READY — AIRULES/ battle-tested in Cursor with Grok 4.5 and 4.6; generated apps stay secure and fast
🔹 Callable strings — trailing ! skips DI; # = middleware; * = model:
Router::get('/', 'Shop:Home@index!'); // controller, no DI Router::post('/save', 'Shop:Home@save!') ->before('#Shop:AuthGate@check!'); // # middleware $item = DotApp::call('*Shop:Item@find!', $id); // * model
🔹 DACore admin module — official admin UI, free
Support DotApp’s development! Be among the first 100 sponsors to earn permanent recognition on dotapp.dev. Sponsor Now
Getting Started
The DotApp instance is globally accessible. Work through facades. Controllers are public static methods. A trailing ! on a callable turns the DI container off for that call — the preferred path for hot routes. Prefix # targets middleware, * targets a model.
// Static route (exact URL, no pattern matching) + controller, no DI Router::get('/', 'Shop:Home@index!', Router::STATIC_ROUTE); // Dynamic param + integer constraint Router::get('/item/{id:i}', 'Shop:Home@item!'); // POST + middleware gate (# = Middleware class, ! = skip DI) Router::post('/save', 'Shop:Home@save!') ->before('#Shop:AuthGate@check!'); // Closures still work when you want them Router::get(['/', '/home'], fn($request) => 'Welcome!'); // Call a model (*) or another controller from PHP $item = DotApp::call('*Shop:Item@find!', $id); $html = DotApp::call('Shop:Home@helper!', $request);
Hot-path controller (no injected services — you construct what you need):
public static function index($request) { $renderer = \Dotsystems\App\Parts\Renderer::new(); return $renderer->module('Shop') ->setView('home') ->setViewVar('title', 'Hello') ->renderView(); }
Route: 'Shop:Home@index!'. Omit the ! only when the method should receive DI parameters.
What's New ✨
Version 2.0 Released (NEW – 2026-08-18)
This is not a coat of paint. 2.0 is the result of heavy production use plus a hard rewrite of how agents are allowed to touch the stack. The rulebook was driven in Cursor with Grok 4.5 and Grok 4.6. Apps that came out of those sessions are secure, snappy, and shippable — on models that stay cheap to run.
- Fully AI READY: First-class support for AI agents.
AIRULES/(framework) andAIRULES-DACORE/(with DACore) tell Cursor / Grok exactly how to write DotApp. !skips DI:'Shop:Home@index!'turns the container off for that controller method. Fast, explicit, no mystery injection on hot paths.- Callable prefixes:
#Shop:Gate@check!= middleware,*Shop:Item@find!= model,Shop:Home@index!= controller. Same string form on routes,->before(), andDotApp::call(). - Secure forms by default:
<fo-rm>+{{ formName(handler) }}+ CRC — stronger than a plain CSRF token. Row actions (toggle, delete, paginate) use$dotapp().load(), not a<fo-rm>per button. - Encrypted IDs in the browser: no raw
data-id="7".{{ enc(Shop.item.id): $id }}on the way out, decrypt + rights check on the way in. - Lists that can grow must paginate:
paginate()+ AJAX pager on first ship. No->all()dumps, no?page=full reload of the admin shell. - DSM, not
$_SESSION:DSM::use('Shop')->set/get/deletefor app session state. $dotapp()frontend: live DOM patch + overlay + toast after save. Nolocation.reload(). File uploads go through$dotapp().uploadFile.- DB the DotApp way:
DB::module('RAW')->q(function ($qb) { ... })->all()|first()|execute(). Module tables are{lowercase_modulename}_*(Shop→shop_items). - DACore admin — free: login, 2FA, rights, DB-driven menu, page shell, optional AI chat with tools. Your module plugs in via
DotApp::call('DACore:…'). See dotapp.dev. - Production hardening: bugs found under real load are gone; ORM, QueryBuilder, routing, and the JS stack were cleaned up because they had to survive daily use — not a demo.
AI READY (2.0)
- Shipped rulebook: drop
AIRULES/next toindex.php(start atAIRULES/00-AGENT-CONTRACT.md). If DACore is installed, copyAIRULES-DACORE/asAIRULES/. - Cursor + Grok 4.5 / 4.6: stress-tested until generated admin and public UI stayed secure and fast.
- Cheap models, serious apps: you do not need the most expensive model in the catalog. Affordable agents follow the rules and still emit real DotApp code.
- Hard boundaries for agents: they may edit
app/config.phpandapp/modules/<YourModule>/— not the kernel, not DACore. That is why the output stays maintainable.
👥 Installation
There are three ways to install dotApp:
-
Using Composer (New!):
Install dotApp directly into your current directory using Composer:
composer create-project dotsystems/dotapp ./
This will download the latest version of dotApp and set up the project structure in your current directory.
-
Using DotApper CLI (Recommended):
Obtain the
dotapper.phpfile and run it to install dotApp. You can either:-
Download it manually: Visit https://install.dotapp.dev/dotapper.php, download the file, and place it in your project directory.
-
Use
wget: Run the following command to downloaddotapper.phpdirectly:wget https://install.dotapp.dev/dotapper.php
Then, execute the installer:
php dotapper.php --install
-
-
Using Git Clone:
Clone the repository to your project directory:
git clone https://github.com/dotsystems-sk/dotapp.git ./
✅ After installation, you can freely use composer require to install additional libraries as needed.
🚀 Usage
Simple "Hello World" example using dotApp:
// index.php define('__ROOTDIR__', "/path/to/your/dotapp"); require_once __ROOTDIR__ . '/app/config.php'; Router::get('/', fn($request) => 'Hello World'); DotApp::DotApp()->run();
Route callbacks receive a locked Request object; you can return a string (it becomes the response body) or work with
$request->responseif you need full control.
⚙️ Configuration
Main settings are located in app/config.php. Example:
use \Dotsystems\App\DotApp; use \Dotsystems\App\SessionDriverRedis; use \Dotsystems\App\Config; $dotApp = new \Dotsystems\App\DotApp(); // Set encryption key Config::set("app", "c_enc_key", md5('SECURE_KEY')); // Configure databases Config::addDatabase("main", "127.0.0.1", "dotsystems", "dotsystems", "dotsystems", "UTF8", "MYSQL", "mysqli"); // Configure session driver Config::session("lifetime", 30 * 24 * 3600); Config::session("redis_host", "127.0.0.1"); Config::session("redis_port", 6379); Config::session("redis_prefix", "session:"); Config::sessionDriver("redis", SessionDriverRedis::driver()); $dotApp->load_modules();
🛠️ DotApper CLI Tool
DotApper is a command-line utility for managing your dotApp application. Basic usage:
# Install dotApp php dotapper.php --install # Update dotApp core php dotapper.php --update # Install a module from Git or registry php dotapper.php --install-module=https://github.com/vendor/module.git # Create a new module php dotapper.php --create-module=Blog # List all routes php dotapper.php --list-routes # Regenerate .htaccess php dotapper.php --create-htaccess # Run tests php dotapper.php --test # All tests (core) php dotapper.php --test-modules # Module tests only php dotapper.php --module=Blog --test # Tests for Blog module
All Available Options
Usage: php dotapper.php [options]
Options:
--install Install a fresh copy of the dotApp PHP framework
--update Update dotApp core to the latest version
--create-module=<name> Create a new module
--modules List all modules
--install-module=<url|name[:ver]> Install a module (Git URL or name, optional version)
--prepare-database[=<prefix>] Prepare database structure (optional table prefix)
--module=<module_name> --create-controller=<ControllerName> Create a new controller
--module=<module_name> --create-middleware=<MiddlewareName> Create a new middleware
--module=<module_name> --create-model=<ModelName> Create a new model
--list-routes List all defined routes
--list-route=<route> List callbacks for a specific route (e.g., /)
--create-htaccess Create or recreate a new .htaccess file
--optimize-modules Optimize module loading
--test Run all core tests
--test-modules Run all module tests (no core tests)
--module=<module_name> --test Run tests for a specific module
🧪 Version Note
This is DotApp PHP Framework 2.0: production-ready, fully AI READY, with a real agent rulebook, ! to skip DI, # / * callables, hardened forms and lists, and the DACore admin module available free. The AIRULES pack was stress-tested in Cursor with Grok 4.5 and Grok 4.6 — generated apps stay secure and fast, even on inexpensive models. Full documentation lives at https://dotapp.dev/.
Older versions may have duplicate function names (lowercase and PascalCase) due to the transition to PascalCase for naming, maintaining backward compatibility. This has minimal impact on performance.
📚 Documentation
Full documentation is available at:
💎 Contact
📧 Email: dotapp@dotapp.dev
🌐 Web: https://dotapp.dev
🌐 Company Web: https://dotsystems.sk
📝 License
DotApp PHP Framework 2.0 is licensed under the MIT License. You must retain the author's name in all library headers.
Additional Permission: The Software may be used for training AI models, provided the copyright notice is retained.