Pair is a lightweight PHP framework for server-rendered web applications. It focuses on fast setup, clear MVC routing, practical ORM features, and optional integrations (Aircall, S3, SES, Sentry, Telegram, Push, Passkey) without heavy tooling.
Pair v3 is currently in alpha and includes breaking changes compared to previous major versions.
composer require viames/pair<?php
use Pair\Core\Application;
require 'vendor/autoload.php';
$app = Application::getInstance();
$app->run();- Small and fast for small/medium projects.
- MVC structure with SEO-friendly routing.
- ActiveRecord-style ORM with automatic type casting.
- Plugin-oriented architecture (modules/templates).
- Good defaults for timezone, logging, and framework utilities.
- Optional third-party integrations when needed.
Pair maps classes to DB tables and supports automatic casts (int, bool, DateTime, float, csv), relation helpers, and caching-oriented query helpers.
Docs: ActiveRecord
Default route format (after base path):
/<module>/<action>/<params...>
Example: example.com/user/login
- module:
/modules/user - controller:
/modules/user/controller.php(extendsPair/Core/Controller.php) - action:
loginAction()when present - auto-loaded by convention:
model.php,viewLogin.php(UserViewLogin), and/modules/user/layouts/login.php
Docs: Router
Built-in log bar for loaded objects, memory usage, timings, SQL traces, backtraces, and custom debug messages.
Dependency-free helper for progressive enhancement in server-rendered apps (assets/PairUI.js).
Main directives:
data-text,data-html,data-show,data-ifdata-class,data-attr,data-prop,data-styledata-model,data-on,data-each
Docs: PairUI.js
Available assets:
PairPWA.jsPairSW.jsPairRouter.jsPairSkeleton.jsPairDevice.jsPairPasskey.js
Minimal frontend setup:
<script src="/assets/PairUI.js" defer></script>
<script src="/assets/PairPWA.js" defer></script>
<script src="/assets/PairRouter.js" defer></script>
<script src="/assets/PairSkeleton.js" defer></script>
<script src="/assets/PairDevice.js" defer></script>
<script src="/assets/PairPasskey.js" defer></script>Important notes:
- Keep progressive enhancement.
- Service workers require HTTPS (except localhost).
- Use a single SW URL if you also enable Push.
Backend:
class ApiController extends \Pair\Api\PasskeyController {}This enables:
POST /api/passkey/login/optionsPOST /api/passkey/login/verifyPOST /api/passkey/register/options(requiressid)POST /api/passkey/register/verify(requiressid)GET /api/passkey/list(requiressid)DELETE /api/passkey/revoke/{id}(requiressid)
Pair includes optional support for services such as:
Configuration reference: Configuration (.env)
If you are upgrading between major versions:
composer run upgrade-to-v2
composer run upgrade-to-v3To test unreleased code from main:
composer require viames/pair dev-mainMain docs live in the Wiki.
Useful pages:
| Software | Recommended | Minimum | Configuration |
|---|---|---|---|
| Apache | 2.4+ | 2.4 | modules: mod_rewrite |
| MySQL | 8.0+ | 8.0 | character_set: utf8mb4 collation: utf8mb4_unicode_ci storage_engine: InnoDB |
| PHP | 8.4+ | 8.3 | Composer-required extensions: curl, intl, json, mbstring, PDO |
Runtime notes:
pdo_mysqlis required when using the default MySQL driver (Pair\\Orm\\Database).fileinfois strongly recommended for reliable MIME detection in uploads.opensslis required only for Passkey/WebAuthn features.pcreandReflectionare part of standard PHP 8+ builds.
Start from pair_boilerplate to bootstrap a new app quickly.
- Issues: github.com/viames/pair/issues
- Wiki: github.com/viames/pair/wiki
- Source: github.com/viames/pair/tree/master/src
- Homepage: viames.github.io/pair
Version history is available in GitHub Releases: github.com/viames/pair/releases
If you discover a security issue, please open a GitHub issue with a clear description and steps to reproduce.
Feedback, code contributions, and documentation improvements are welcome via pull request.
MIT
