phpSPA lets you build fast, interactive single-page apps using pure PHP — with dynamic routing, component architecture, and no full-page reloads. No JavaScript frameworks required.
To empower PHP developers to create modern, dynamic web apps with the elegance of frontend SPA frameworks — but fully in PHP.
- 🚫 No full-page reloads
- ⚡ Instant component swapping
- 🧱 Clean, function-based components
- 🌍 Real SPA behavior via History API
- 🧠 Now with State Management!
- 🔄 Dynamic content updates — feels like React
- 🧩 Component-based PHP architecture
- 🔗 URL routing (client + server synced)
- 🧠 Built-in State Management
- ⚙️ Lifecycle support for loaders, metadata, etc.
- 🪶 Minimal JS: one small file
- 🔁 Graceful fallback (no JS? Still works)
- ✅ Fully PHP + HTML syntax
- ✅ No template engines required
- ✅ Dynamic GET & POST routing
- ✅ Server-rendered SEO-ready output
- ✅ Per-component and global loading indicators
- ✅ Supports Composer or manual usage
- ✅ State system: update UI reactively from JS
- Layout → The base HTML (with
__CONTENT__) - Component → A PHP function returning HTML
- App → Registers and runs components based on routes
- State → Simple mechanism to manage reactive variables across requests
You can create persistent state variables inside your components using:
$counter = createState("counter", 0);Update state from the frontend:
phpspa.setState("counter", newValue);This will automatically re-render the component on update.
composer require dconco/phpspaInclude the autoloader:
require 'vendor/autoload.php';Include the core files:
require 'path/to/phpspa/core/App.php';
require 'path/to/phpspa/core/Component.php';<script src="https://cdn.jsdelivr.net/npm/phpspa-js"></script><?php
// layout.php
function layout() {
return <<<HTML
<html>
<head>
<title>My Live App</title>
</head>
<body>
<div id="app">__CONTENT__</div>
<script src="https://cdn.jsdelivr.net/npm/phpspa-js"></script>
</body>
</html>
HTML;
}<?php
// components.php
function HomePage() {
$counter = createState("count", 0);
return <<<HTML
<h1>Counter: {$counter}</h1>
<button onclick="phpspa.setState('count', {$counter} + 1)">Increase</button>
<button onclick="phpspa.setState('count', 0)">Reset</button>
<br><br>
<Link to="/login" label="Go to Login" />
HTML;
}
function LoginPage() {
return <<<HTML
<h2>Login</h2>
<form method="post">
<input name="username" placeholder="Username"><br>
<input name="password" type="password" placeholder="Password"><br>
<button type="submit">Login</button>
</form>
HTML;
}<?php
// index.php
require 'layout.php';
require 'components.php';
$app = new App('layout');
$app->targetId('app');
$app->attach(
(new Component('HomePage'))
->title('Home')
->method('GET')
->route('/')
);
$app->attach(
(new Component('LoginPage'))
->title('Login')
->method('GET|POST')
->route('/login')
);
$app->run();phpspa.on("beforeload", ({ route }) => showLoader());
phpspa.on("load", ({ success }) => hideLoader());Looking for a complete guide to phpSPA?
🔗 Read the full tutorial and advanced usage on Read the Docs:
👉 https://phpspa.readthedocs.io
The docs include:
- 📦 Installation (Composer & Manual)
- 🧩 Component system
- 🔁 Routing & page transitions
- 🧠 Global state management
- ✨ Layouts, nesting, and loaders
- 🛡️ CSRF protection
- 🧪 Practical examples & best practices
Whether you're just getting started or building something advanced, the documentation will walk you through every step.
- GitHub: dconco/phpspa
- JS Engine: dconco/phpspa-js
- Website: https://phpspa.readthedocs.io
- License: MIT
MIT License © dconco
Dave Conco Simple, fast, and native PHP – just the way we like it.
If you find phpSPA useful, please consider giving it a star on GitHub! It helps others discover the project and keeps the momentum going 🚀
Your support means a lot! ❤️