Make PHP great again

Fast to run, easy to use, and small enough to understand. Crab gives long-lived PHP applications a clear foundation for web apps, JSON APIs, and the work around them.

Build a regular server-rendered website too: Arc adds HTML views, layouts and components, with ordinary forms and no frontend framework required.

composer create-project crabphp/crab my-app
cd my-app
php cua dev

Read the documentation

Fast to run. Easy to use.

Fast
The application loads once and serves requests as a real server. No PHP-FPM, no bootstrapping on every request.
Easy
Typed actions, named services, ordinary PHP. One way to do each thing keeps the important parts visible.
Built-in
Routing, validation, databases, queues, scheduling, authentication, HTTP, streaming, and WebSockets on one small foundation.

Benchmarks

Requests per second · PHP 8.5.12 · 64 connections · median of five runs.Motion follows Hello.
Framework / serverHelloDatabase
Crab 0.6.4 Native server108,52220,240
webman 2.2.5 Workerman73,2828,301
Hyperf 3.2.0 Swoole41,6529,380
ReactPHP HTTP 1.12.0 ext-event · HTTP library40,99812,543
AMP HTTP Server 3.4.8 Revolt · ext-event · HTTP library14,0014,166
Symfony 8.1.11 FrankenPHP6,1143,540
Spiral 3.18.2 RoadRunner3,1252,517
Laravel 13.40.0 Octane · FrankenPHP2,1791,589
Tempest 3.21.0 FrankenPHP991904

ReactPHP and AMP are HTTP libraries, not full application frameworks. Each uses a router, explicit input validation and its native async MySQL driver.

Intel Core i5-9400F · 2 CPU / 2 GiB RAM limit per app (shared host). Frameworks tested 2026-11-10; ReactPHP and AMP tested separately 2026-11-11. Separate runs, not a simultaneous comparison. Framework results · ReactPHP / AMP results · Run it yourself

One command starts the application

HTTP, queue workers, and the scheduler start together. No Supervisor config, no systemd unit per worker, no crontab line. List the queue and the scheduler in app.php, then start.

$ php cua start --daemon
Starting my-app server on http://127.0.0.1:8080

  Server    Workers  Runs
  http      2        http://127.0.0.1:8080
  queue     3        queue:work: mail x1, default x2
  schedule  1        schedule:work
--daemon
Runs in the background and returns once it is up. A worker that dies is started again.
reload
HTTP, the queue, and the scheduler get the new code together, without refusing a connection.
status
Every worker, what it has handled, and its memory, in one table.

Deployment guide

Included

A route is just a route

// routes/web.php
use Crab\Route;

Route::get('/hello/{name}', static function (string $name): array {
    return ['hello' => $name];
});

Written for agents too

Explicit types, no hidden state, one way to do each thing. The same things that make code easy for a person to read make it easy for a coding agent to get right.

$ php cua describe routes
routes
  POST /orders -> App\Actions\PlaceOrder via Crab\Auth\TokenAuth
    body { lines: Array<{ productId: int; quantity?: int | null (minimum=1, maximum=20, default=1) }> (minItems=1, maxItems=20) }
    user: App\User
  GET /products/{id} -> App\Actions\ShowProduct
    {id}: int
describe
The whole application in one read: routes and what each takes, middleware, commands, schedule, listeners, databases, settings. One thing per line, in few tokens. --json gives JSON Schema.
AGENTS.md
Every new app ships with one: where things go, the rules a long-lived server needs, and how to check the work.
Preflight
describe app lists settings that do not fit and services that cannot be made, before start refuses them.
Markdown
The guide is plain Markdown, in vendor/crabphp/framework/docs/ and at /llms.txt.

Describing the application