mardev / starter-kit
Starter Kit β PHP MVC Boilerplate
Package info
github.com/rodrigomarcelo643/vanilla-php-mvc-starterkit
Type:project
pkg:composer/mardev/starter-kit
Requires
- phpmailer/phpmailer: ^7.1
Requires (Dev)
- phpunit/phpunit: ^11
- dev-master
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- dev-feature/middleware-system
- dev-docs/readme-cli-instructions
- dev-feature/command-tinker
- dev-feature/command-optimize-clear
- dev-feature/command-logs-clear
- dev-feature/command-cache-clear
- dev-feature/command-serve
- dev-feature/command-route-list
- dev-feature/command-make-view
- dev-feature/command-make-model
- dev-feature/command-make-migration
- dev-feature/command-make-middleware
- dev-feature/command-make-controller
- dev-feature/command-make-auth
- dev-feature/command-key-generate
- dev-feature/command-db-seed
- dev-feature/command-db-rollback
- dev-feature/command-db-migrate
- dev-feature/command-db-fresh
- dev-feature/command-help
- dev-feature/kit-output-support
- dev-feature/kit-windows-wrapper
- dev-feature/kit-cli-entrypoint
- dev-feature/server-router
- dev-feature/composer-update
- dev-feature/router-dynamic-uri-parsing
- dev-feat/skeleton-loaders
- dev-feature/skeleton-loader-ui
- dev-feature/superadmin-panel
- dev-refactor/file-structuring
- dev-feat/dark-mode-support
This package is auto-updated.
Last update: 2026-05-25 14:17:09 UTC
README
π Vanilla PHP MVC Starter Kit
A clean PHP 8+ MVC boilerplate with a structured js/ layer, split route files, super admin + admin panels, session auth with live password strength validation, role-based routing, OAuth (Google + GitHub), flash toast system, AJAX fetch helpers, Alpine.js reactive UI, Tailwind CSS, and PHPUnit β zero frameworks, zero fluff.
β Star on GitHub Β· π Docs Β· π§ͺ Tests
π About
Vanilla PHP MVC Starter Kit is a lightweight, zero-framework boilerplate for developers who want a clean starting point without the overhead of Laravel or Symfony. Built on pure PHP 8+, it ships with a hand-rolled MVC architecture, session-based authentication, role-based routing, and a full admin panel β all wired up and ready to go.
The frontend uses Tailwind CSS and Alpine.js via CDN, so there's no build pipeline to configure. AJAX helpers, avatar uploads, password reset flow, and a responsive multi-panel layout (super admin, admin, app, client) are included out of the box.
Backed by PHPUnit with 77 tests across unit and feature suites, GitHub Actions workflows for linting, quality checks, and deployment, and a single SQL file to get your database running in minutes.
Start building in minutes, not hours.
What's included
- Multi-panel layout β Super Admin, Admin, App (authenticated users), and Client (public) views
- Session authentication β Login, registration, logout, and password reset out of the box
- OAuth login β Google and GitHub sign-in with auto-prefill registration for new accounts
- Role-based routing β Segregated routes for super admin, admin, app, client, and AJAX calls
- Super admin panel β Highest-privilege panel with admin management, full user CRUD, purple-accented UI
- Full admin panel β Collapsible sidebar, topbar, user management, and data tables
- Flash toast system β
Session::flash()sets one-time toasts, auto-fired on next page load - AJAX helpers β Lightweight fetch wrappers for POST/GET with JSON responses
- Avatar uploads β Image preview, crop, and AJAX upload built in
- Environment config β
.env-driven configuration, no hardcoded credentials - Tailwind CSS + Alpine.js β Modern UI via CDN, no build step required
- Composer managed β PHPMailer, PHPUnit, and more via a clean
composer.json - 77 PHPUnit tests β Unit and feature suites with automatic cleanup
π€ Why This Over Laravel?
This starter kit is intentionally built without Laravel β and that's the point.
π Built for Students
If you are learning PHP for the first time or studying MVC architecture, Laravel's abstractions (Eloquent, Facades, Service Containers) can hide what's actually happening under the hood. This kit exposes everything β the router, the auth system, the database layer β in plain, readable PHP so you can see exactly how it works.
Start here. Understand MVC fundamentals. Then move to Laravel with confidence.
π’ Built for Small to Medium Projects
Not every project needs the full weight of a framework. This kit is:
- Lightweight β no 30MB+ vendor folder, no service provider bootstrapping on every request
- Shared-hosting friendly β runs on basic Apache/XAMPP/Laragon setups without special server config
- Fast to deploy β one SQL import, one
.envfile, and you're live
π A Natural Laravel On-ramp
| This Kit | Laravel Equivalent |
|---|---|
Router::get() |
Route::get() |
php kit make:controller |
php artisan make:controller |
php kit db:seed |
php artisan db:seed |
php kit migrate |
php artisan migrate |
.env config |
.env config |
| Middleware classes | Middleware classes |
| MVC structure | MVC structure |
The patterns here are intentionally Laravel-inspired β so once you understand this kit, transitioning to Laravel feels familiar, not foreign.
β‘ When to Use This vs Laravel
| Scenario | Use This Kit | Use Laravel |
|---|---|---|
| Learning MVC from scratch | β | β Too much magic |
| Small business site / portfolio | β | β |
| Shared hosting (cPanel) | β | β οΈ Can be tricky |
| Large enterprise SaaS | β οΈ | β |
| Understanding routing internals | β | β Hidden behind framework |
| Rapid API with auth/queues/etc | β οΈ | β |
πΌοΈ UI Visuals
See the full visual walkthrough in VISUALS.md
π Project Structure
starterkit/
βββ app/
β βββ config/ # App, database, mail & OAuth config (reads from .env)
β βββ controllers/ # MVC controllers
β β βββ auth/ # AuthController, OAuthController, PasswordController, ProfileController
β β βββ superadmin/ # SuperAdminDashboardController, SuperAdminAdminController
β βββ core/ # Router, Model, Auth, Session (+ flash), Database, Mailer
β βββ helpers/ # Global helper functions
β βββ models/ # Data models (User, Admin, SuperAdmin, PasswordReset)
β βββ views/ # Layouts, components & pages (superadmin/admin/app/client/auth)
βββ assets/ # CSS & fonts
βββ database/
β βββ starter.sql # Database schema + seed data
βββ js/
β βββ admin/ # Admin-specific JS (admin.js, users.js)
β βββ ajax.js # Fetch wrapper (Ajax.post / Ajax.get)
β βββ app.js # Global utilities (toast, alert, setLoading)
β βββ auth.js # Auth form handlers + strength meter
β βββ avatar.js # Avatar upload with drag & drop + XHR progress
β βββ logout.js # Logout confirmation modal
β βββ profile.js # Profile edit + change password handlers
β βββ settings.js # Settings page theme sync
β βββ sidebar.js # Sidebar keyboard shortcut (Ctrl+B)
β βββ theme.js # Dark/light mode toggle
βββ routes/
β βββ web.php # Entry point β loads all route files
β βββ web/
β βββ superadmin/ # Super admin page + AJAX routes
β βββ admin/ # Admin page + AJAX routes
β βββ app/ # Authenticated user page + AJAX routes
β βββ auth/ # Auth page + AJAX + OAuth routes
β βββ client/ # Public/client page routes
βββ storage/ # Uploads
βββ tests/ # PHPUnit unit & feature suites
βββ .agent/ # AI coding assistant context & prompt templates
βββ .claude/ # Claude/Cursor context file
βββ .github/workflows/ # CI/CD workflows
βββ .env.example # Environment template
βββ .htaccess # URL rewriting
βββ composer.json # Dependencies
βββ index.php # Application entry point
βοΈ Installation
Requirements
- PHP 8.0+
- MySQL 5.7+
- Apache with mod_rewrite enabled (XAMPP / Laragon / WAMP)
- Composer
Steps
1. Clone the repository
git clone https://github.com/rodrigomarcelo643/php-vanilla-mvc-starterkit.git
Place it inside your server's web root (e.g. htdocs/ or www/).
2. Install dependencies
composer install
3. Set up the database
- Open phpMyAdmin
- Go to Import and select
database/starter.sql - This creates the
starterdatabase with tables and seed data
4. Configure environment
cp .env.example .env
Edit .env with your values:
APP_NAME="Starter Kit" BASE_URL="/your-folder-path" DB_HOST=localhost DB_NAME=starter DB_USER=root DB_PASS=
5. Visit the app
http://localhost/your-folder-path
Default Credentials
| Role | Password | |
|---|---|---|
| Super Admin | superadmin@starter.com | password |
| Admin | admin@starter.com | password |
| User | alice@example.com | password |
π§© Installer Presets
When you run composer install, the setup wizard automatically launches and asks you to pick an installation mode:
====================================================
Welcome to Vanilla PHP MVC Starter Kit
====================================================
Which preset would you like to install?
[1] Full Stack (Alpine.js + AJAX Monolith) - Default
[2] REST API (Full Stack with JS)
[3] Backend Only (REST API, No UI)
Select an option [1]:
Option 1 β Full Stack (Alpine.js + AJAX Monolith) (default)
The classic MVC full stack mode. All views are rendered server-side. AJAX calls use the /ajax/ route prefix and return JSON. The /api/ routes are also registered and available for external consumers alongside the HTML interface.
- β All HTML views intact (client, admin, superadmin, app panels)
- β Session-based auth with login/register pages
- β
AJAX endpoints under
/ajax/ - β
REST API endpoints under
/api/(JSON) - β
http://localhost/yourapp/β renders HTML homepage
Option 2 β REST API (Full Stack with JS)
Identical to Option 1 but injects the smart Controller which auto-detects /api/ prefixed requests and switches them to JSON output mode. All HTML views remain intact. The frontend JS layer drives data via /api/ fetch calls.
- β All HTML views intact
- β
Smart
Controllerβ/api/routes return JSON, page routes return HTML - β Session cookie reused for both browser and API requests
- β
http://localhost/yourapp/β renders HTML homepage - β
http://localhost/yourapp/api/admin/usersβ returns JSON user list
Option 3 β Backend Only (REST API, No UI)
Pure JSON API mode. All frontend assets (views, JS, CSS, client routes) are removed. Every request returns JSON. Use this when building a decoupled frontend (React, Vue, mobile app) that communicates with this backend via the /api/ endpoints.
- β All HTML views removed
- β
Only
routes/api.phpis loaded β pure JSON responses - β
Smart
Controllerauth guard returns JSON401/403(no HTML redirects) - β
http://localhost/yourapp/β returns JSON welcome message - β
http://localhost/yourapp/api/admin/usersβ returns JSON user list
Comparison
| Feature | Option 1 | Option 2 | Option 3 |
|---|---|---|---|
| HTML Views | β | β | β |
| Session Auth (Browser) | β | β | β |
/ajax/ AJAX endpoints |
β | β | β |
/api/ REST endpoints (JSON) |
β | β | β |
| Smart JSON/HTML auto-switch | β | β | β |
Root / returns HTML |
β | β | β |
Root / returns JSON |
β | β | β |
You can re-run the installer at any time with:
php kit env:setup
π οΈ Kit CLI Developer Tool
The starter kit comes with Kit (a custom PHP command-line interface helper) to streamline database setup, route inspection, scaffolding, cache management, and server management.
You can run commands using:
# On Windows/Unix php kit [command] [arguments] [options] # On Windows (shortcut) kit.bat [command] [arguments] [options]
Available Commands
ποΈ Database Management
php kit db:freshβ Drops all tables and re-imports the initial schema.php kit db:seedβ Imports the baseline schema and seed data fromdatabase/starter.sql.php kit migrateβ Runs all pending database migrations.php kit migrate:rollbackβ Rolls back the last batch of migrations.
ποΈ Code Scaffolding
php kit make:controller [Name]β Generates a new Controller class.- Options:
--admin(places in admin folder),--resource(adds boilerplate CRUD methods).
- Options:
php kit make:model [Name]β Generates a new Model class.- Options:
--resource(adds CRUD helper methods).
- Options:
php kit make:view [folder/name]β Generates a new View template file.- Options:
--resource(creates standard list/show/create/edit views).
- Options:
php kit make:middleware [Name]β Generates a new Middleware class.php kit make:migration [Name]β Generates a new Migration template file.php kit make:authβ Generates full Authentication scaffolding (Controllers, Views, and Routes).
πΊοΈ Routing
php kit route:listβ Lists all registered application routes, organized by request method, URI path, and handler.php kit route:testβ Launches an interactive API endpoint tester directly in your terminal. Categorizes all registered/api/routes by group (Auth, Admin, Superadmin, Profile, App), sends real HTTP requests via cURL (including session cookies), and displays colorized JSON responses. Press[ENTER]to return to the menu after each request. Exit withXorCtrl+C.
π» System & Development Utilities
php kit serve [host?] [port?]β Starts the local PHP built-in development server with custom routing support.php kit tinkerβ Starts an interactive PHP REPL (Read-Eval-Print Loop) session to play with your models and databases.php kit key:generateβ Generates a secureAPP_KEYand updates it in your.envfile.php kit cache:clearβ Clears application cache files.php kit logs:clearβ Clears application log files.php kit optimize:clearβ Clears all compiled caches and logs at once.
βοΈ Environment & Routing Intelligence
- Environment-Aware Server Router (
server.php): Dynamically parses theBASE_URLfrom.envto strip any path prefix when serving requests using PHP's built-in development server (php kit serve). - Dynamic URI Parsing (
app/core/Router.php): Fully decoupled from hardcoded subdirectory dependencies, allowing routing to work seamlessly whether served from an Apache alias (e.g.,http://localhost/starterkit) or the built-in server (e.g.,http://localhost:8000).
πΊοΈ Routes Overview
| File | Prefix | Description |
|---|---|---|
client/pages.php |
/ |
Public pages (home, about, blogβ¦) |
superadmin/pages.php |
superadmin/ |
Super admin dashboard, admins, users |
superadmin/ajax.php |
ajax/admins/ |
Admin CRUD AJAX endpoints |
admin/pages.php |
admin/ |
Admin dashboard, users, settings |
app/pages.php |
app/ |
Authenticated user pages |
auth/ajax.php |
ajax/ |
Login, register + AJAX endpoints |
auth/oauth.php |
oauth/ |
Google + GitHub OAuth redirect/callback |
routes/api.php |
api/ |
Unified REST API β JSON-only endpoints for all roles |
REST API Endpoints (routes/api.php)
All /api/ routes return JSON only, regardless of installation mode.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/ping |
Health check |
GET |
/api |
API info + endpoint list |
POST |
/api/auth/login |
Login |
POST |
/api/auth/register |
Register |
POST |
/api/auth/logout |
Logout |
POST |
/api/auth/forgot-password |
Request password reset |
POST |
/api/auth/reset-password |
Complete password reset |
GET |
/api/admin/users |
Get all users (admin) |
POST |
/api/admin/users |
Create user (admin) |
POST |
/api/admin/users/update |
Update user (admin) |
POST |
/api/admin/users/delete |
Delete user (admin) |
GET |
/api/admin/dashboard |
Admin dashboard stats |
GET |
/api/superadmin/admins |
Get all admins (superadmin) |
POST |
/api/superadmin/admins |
Create admin (superadmin) |
POST |
/api/superadmin/admins/update |
Update admin (superadmin) |
POST |
/api/superadmin/admins/delete |
Delete admin (superadmin) |
GET |
/api/superadmin/users |
Get all users (superadmin) |
GET |
/api/superadmin/dashboard |
Superadmin dashboard stats |
GET |
/api/profile |
Get current user profile |
POST |
/api/profile/avatar |
Upload avatar |
POST |
/api/profile/update |
Update profile |
POST |
/api/profile/change-password |
Change password |
GET |
/api/app/home |
Authenticated user home data |
π Super Admin Panel
The super admin is the highest-privilege role in the system. It has its own dedicated panel at /superadmin/dashboard with a purple-accented UI to distinguish it from the regular admin panel.
What super admin can do
- Dashboard β Overview stats: total users, active/inactive users, total admins, new this month
- Manage Admins β Full CRUD: create, edit, delete admin accounts (
super_adminstable) - Manage Users β Full CRUD on all user accounts (same as admin panel)
- Profile β Update name, email, avatar, and password
- Settings β Appearance and notification preferences
Database table
Super admins are stored in a dedicated super_admins table, separate from both users and admins.
CREATE TABLE `super_admins` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `email` VARCHAR(150) NOT NULL, `password` VARCHAR(255) NOT NULL, `avatar` VARCHAR(255) DEFAULT NULL, `status` ENUM('active','inactive') NOT NULL DEFAULT 'active', `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_super_admins_email` (`email`) );
New files added
app/models/SuperAdmin.php
app/controllers/superadmin/SuperAdminDashboardController.php
app/controllers/superadmin/SuperAdminAdminController.php
app/views/layouts/superadmin/header.php
app/views/layouts/superadmin/footer.php
app/views/components/superadmin/sidebar.php
app/views/components/superadmin/topbar.php
app/views/superadmin/dashboard.php
app/views/superadmin/admins.php
app/views/superadmin/users.php
app/views/superadmin/profile.php
app/views/superadmin/settings.php
routes/web/superadmin/pages.php
routes/web/superadmin/ajax.php
Modified files
| File | Change |
|---|---|
app/core/Controller.php |
Added superadmin() layout method |
app/core/Router.php |
Added app/controllers/superadmin/ to auto-discovery |
app/models/Admin.php |
Added update(), delete(), adminCreate() methods |
app/controllers/auth/AuthController.php |
Login checks super_admins table, redirects to /superadmin/dashboard |
app/controllers/auth/ProfileController.php |
Avatar upload, profile update, and password change support superadmin role |
app/controllers/admin/UserController.php |
Guard allows both admin and superadmin roles |
routes/web.php |
Loads super admin page + AJAX route files |
database/starter.sql |
Added super_admins table + seed account |
π OAuth Login
Google and GitHub OAuth are wired up and ready β just add credentials to .env to activate.
Flow
- User clicks Google or GitHub on login or register page
- Redirected to provider β user authenticates
- Existing email β logged in directly, flash toast shown, redirect to dashboard
- New email β redirected to
/registerwith name + email auto-filled and locked, user only sets a password - On register submit β OAuth prefill cleared from session
Setup
Add to .env:
# Google: https://console.cloud.google.com/ β APIs & Services β Credentials β OAuth 2.0 Client ID # Redirect URI: BASE_URL/oauth/google/callback GOOGLE_CLIENT_ID=your-client-id GOOGLE_CLIENT_SECRET=your-client-secret # GitHub: https://github.com/settings/developers β OAuth Apps β New OAuth App # Callback URL: BASE_URL/oauth/github/callback GITHUB_CLIENT_ID=your-client-id GITHUB_CLIENT_SECRET=your-client-secret
New files added
app/config/oauth.php
app/controllers/auth/OAuthController.php
routes/web/auth/oauth.php
π Flash Toast System
Session::flash() stores a one-time message that fires as a toast on the next page load. All layout footers (auth, app, admin, superadmin) read and display it automatically.
// Set in any controller before redirecting Session::flash('toast', ['message' => 'Saved successfully!', 'type' => 'success']); // types: success | error | info Router::redirect('dashboard');
The toast renders bottom-right with a gradient background, progress bar, and auto-dismisses after 4 seconds.
The project uses PHPUnit 11 with 77 tests and 98 assertions across two suites.
tests/
βββ bootstrap.php β loads .env, constants, and core classes for CLI
βββ unit/
β βββ RouterTest.php β URI parsing, query strings, trailing slashes, isAjax, route registration
β βββ AuthSessionTest.php β Auth::check, Session set/get/destroy, edge payloads
β βββ HelperTest.php β dd() output wrapping, types, nested arrays
βββ feature/
βββ UserModelTest.php β create, findByEmail, findById, emailExists, count, getAll, default role/status
βββ AdminModelTest.php β findByEmail, role normalization, password verify, getAll
βββ AuthValidationTest.php β login/register validation, bcrypt, role redirects, inactive status
| Suite | Tests | Needs DB |
|---|---|---|
| Unit | 32 | No |
| Feature | 45 | Yes |
| Total | 77 | β |
Running tests
# All tests php vendor/phpunit/phpunit/phpunit # Unit only (no database required) php vendor/phpunit/phpunit/phpunit --testsuite Unit # Feature only (requires MySQL running with .env credentials) php vendor/phpunit/phpunit/phpunit --testsuite Feature
Or via Composer:
composer test # all composer test:unit # unit only composer test:feature # feature only
Feature tests hit the real database. Make sure your .env credentials are correct and database/starter.sql has been imported before running the feature suite. Test data is created and cleaned up automatically β no permanent records are left behind.
βοΈ GitHub Workflows
All workflows live in .github/workflows/ and are inactive by default β they only run when manually triggered via Actions β Run workflow. Uncomment the push/pull_request triggers inside each file to activate them.
| File | Purpose | Activate on |
|---|---|---|
php-lint.yml |
Syntax-checks every .php file with php -l |
push / PR |
php-quality.yml |
PHPMD mess detection + PHPCS PSR-12 style check on app/ |
push / PR |
secret-scan.yml |
Gitleaks scan for hardcoded credentials and API keys | push / PR |
sql-validate.yml |
Imports database/starter.sql into MySQL and verifies all tables |
SQL file changes |
deploy.yml |
rsync deploy to remote server over SSH | push to main |
Enabling a workflow
- Open the workflow file in
.github/workflows/ - Uncomment the
push/pull_requestblock underon: - Commit and push β GitHub Actions picks it up automatically
Deploy secrets
Before enabling deploy.yml, add these in Settings β Secrets β Actions:
| Secret | Value |
|---|---|
SSH_HOST |
Server IP or hostname |
SSH_USER |
SSH username |
SSH_PRIVATE_KEY |
Contents of your id_rsa private key |
DEPLOY_PATH |
Absolute path on server e.g. /var/www/html/project |
π€ Agent Context (AI Coding Assistant)
This project ships with ready-made context files for AI coding assistants so they understand the architecture, conventions, and patterns without you having to explain them every time.
.claude/
βββ CLAUDE.md # Context file for Claude (Cursor, Claude.ai)
.agent/
βββ context/
β βββ project.md # Universal project map β stack, patterns, DB, env vars
βββ prompts/
βββ scaffold-feature.md # Prompt template: new controller + view + route
βββ scaffold-model.md # Prompt template: new model with CRUD methods
βββ scaffold-ajax.md # Prompt template: new AJAX POST endpoint
βββ debug-review.md # Prompt templates: debug routes, views, controllers
- Claude / Cursor β paste or reference
.claude/CLAUDE.mdat the start of a session - Any agent β point it to
.agent/context/project.mdfor the full project map - Prompt templates β copy a template from
.agent/prompts/, fill in the placeholders, and send it to your agent
π Star History
π License
This project is open-source software licensed under the MIT License. Created and maintained by Marcelo Rodrigo (MarDev) - Software Developer.
You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, subject to the conditions outlined in the LICENSE file.
Developed by MarDev β Software Developer





