PHPackages                             phpcraftdream/garnet-framework - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. phpcraftdream/garnet-framework

ActiveLibrary[Framework](/categories/framework)

phpcraftdream/garnet-framework
==============================

High-performance, opinionated PHP 8 web framework with O(1) routing, parallel async MySQL, type-safe asset bridge, and React-island frontend

v0.1.0-alpha26(2w ago)069↓75%MITPHPPHP ^8.1CI passing

Since Aug 13Pushed 1mo agoCompare

[ Source](https://github.com/PHPCraftdream/garnet-framework)[ Packagist](https://packagist.org/packages/phpcraftdream/garnet-framework)[ Docs](https://github.com/PHPCraftdream/garnet-framework)[ RSS](/packages/phpcraftdream-garnet-framework/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (34)Versions (6)Used By (0)

Garnet Framework
================

[](#garnet-framework)

High-performance, opinionated PHP 8 web framework — O(1) routing, parallel async MySQL, type-safe asset bridge, Twig templating, React islands.

[![CI](https://github.com/PHPCraftdream/garnet-framework/actions/workflows/ci.yml/badge.svg)](https://github.com/PHPCraftdream/garnet-framework/actions/workflows/ci.yml)[![License: MIT OR Apache-2.0](https://camo.githubusercontent.com/6a380a6e924e76196bdb305d9a425347f5c103a5dfd60ae3b2722cd075777220/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542532304f522532304170616368652d2d322e302d626c75652e737667)](LICENSE)[![PHP](https://camo.githubusercontent.com/c1703f810126cc4cb0d9b794e4f7d3f1eeeacc06919198172230318ad37ccb00/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242342e7376673f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![PHPStan](https://camo.githubusercontent.com/6560cfd4478e416677902a5c90d52905f5dfee173e21a0cd4056ec7b11b01f92/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230352d3261356439632e7376673f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](phpstan.neon)[![Code style: php-cs-fixer](https://camo.githubusercontent.com/b57964113f414c67a1b111b80218d27c96366a6009e88e703d4ac4579e6130ff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64652532307374796c652d7068702d2d63732d2d66697865722d3436613266312e737667)](.php-cs-fixer.php)[![Tests: kahlan](https://camo.githubusercontent.com/37863f9827ffebe13a9cd361fd04f7c1e2445dc806d1017f2e15d1a0680acecb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d6b61686c616e253230254532253943253933253230323635372d3331633635332e737667)](https://kahlan.github.io/)[![Twig](https://camo.githubusercontent.com/700e86d7bf2af8a064a3930f9d782d54349a152da56f1efd80a7a3082aa27bc5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547769672d332d3862633334612e7376673f6c6f676f3d74776967266c6f676f436f6c6f723d7768697465)](https://twig.symfony.com/)[![React](https://camo.githubusercontent.com/1b641b1e41bd9b5802e596132eabcc2375c2369f56949fc1749492feae1422b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31382d3631444146422e7376673f6c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b)](https://react.dev/)[![MySQL](https://camo.githubusercontent.com/43f2d2c2a69de10ce4cb49e5b958d9799ed6941dc8cd644b176ddf06f167aa85/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d7953514c2d382e302532422d3434373941312e7376673f6c6f676f3d6d7973716c266c6f676f436f6c6f723d7768697465)](https://www.mysql.com/)[![rspack](https://camo.githubusercontent.com/9ae785f765b65d77205e8ae70d6bd7fcf46e83ffb343f1163ee660a462cb59a9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f62756e646c65722d72737061636b2d6639333932302e737667)](https://rspack.dev/)[![Playwright](https://camo.githubusercontent.com/fa44bc744ff3086fb821f5966f3fec11b73c08ef9706c2a47df8d5a4a6f65a50/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6532652d506c61797772696768742d3245414433332e7376673f6c6f676f3d706c6179777269676874266c6f676f436f6c6f723d7768697465)](https://playwright.dev/)[![PRs welcome](https://camo.githubusercontent.com/dd0b24c1e6776719edb2c273548a510d6490d8d25269a043dfabbd38419905da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e737667)](CONTRIBUTING.md)

Table of Contents
-----------------

[](#table-of-contents)

- [Quickstart](#garnet-framework)
- [Why Garnet](#why-garnet)
- [Feature highlights](#feature-highlights)
- [Installation](#installation)
- [What you get in an app](#what-you-get-in-an-app)
- [Architecture](#architecture-in-one-paragraph)
- [Documentation](#documentation)
- [Known limitations](#known-limitations-v0x)
- [Development](#development)
- [Security](#security)
- [License](#license)

```
# 1. Get the framework. `composer install` also wires the frontend
#    toolchain (npm + node_modules) via the bundled `garnet setup` hook.
git clone https://github.com/PHPCraftdream/garnet-framework
cd garnet-framework && composer install

# 2. Scaffold an app from the bundled template. It's born ready —
#    vendor, node deps, Playwright and a working build, zero manual config.
php bin/garnet app:create MyApp
cd MyApp

# 3. Build assets and run it (port 8001).
php garnet build
php garnet serve
```

That's the whole quickstart — no separate frontend install step. Re-run the installer any time with `php bin/garnet setup`. The rest of this README explains what you just installed and where to go next.

---

Why Garnet
----------

[](#why-garnet)

Garnet started as the engine of a production booking platform and was extracted into a standalone framework. It optimises for three things, in this order:

1. **Performance** — every architectural decision is weighed against its cost. The router is O(1) (path used as a hash-map key, no regex on dispatch). MySQL queries can fan out in parallel (`mysqli_poll`, total latency = `max(query_time)`, not the sum). Assets are pre-hashed and referenced through codegen-typed PHP classes.
2. **Developer experience** — repetitive work is automated. `php garnet prepare` generates type-safe `*Gen.php` accessors for every asset. `IEntityConfig` drives generic grid/form controllers via the Template Method pattern. The CLI is a single `php garnet `surface for everything: build, serve, migrate, deploy, cache.
3. **Explicit control** — no auto-discovery magic. Routes are PHP arrays. Bundle bootstrap is a method call. Dependencies are listed in `composer.json`, not divined at runtime.

If you're building a CRUD-heavy app with custom business logic and you want fewer dependencies, fewer mystery files, and a tight `php garnet`loop, this might fit.

Feature highlights
------------------

[](#feature-highlights)

- **O(1) router** — direct hash-map dispatch with `/path/~method` syntax.
- **Parallel async MySQL** — multiple queries via `mysqli_poll`; total wait time bounded by the slowest query.
- **Type-safe asset bridge** — `*Gen.php` classes give IDE-autocompletable, cache-busted URLs for every JS/CSS chunk.
- **Bundle architecture** — self-contained modules (auth, CRUD, i18n, uploads, comments, support, IM, notifications) that auto-register templates, assets and services.
- **`IEntityConfig` CRUD** — declarative entity specs drive generic grid/form controllers with validation, field types, role gates.
- **Passwordless auth** — built-in email magic-link state machine with CSRF, brute-force mitigation, single-page UX.
- **Twig templating** — strict separation of markup (Twig) from logic (PHP); auto-escaping by default.
- **React island frontend** — lazy-loaded React components in server-rendered pages; ErrorBoundary-wrapped; no full SPA required.
- **CLI tooling** — single `php garnet` entry point for build, serve, deploy, migrations, codegen.

Installation
------------

[](#installation)

### As a dependency

[](#as-a-dependency)

```
composer require phpcraftdream/garnet-framework
```

You typically don't `require` Garnet directly — you create an app from the bundled template (`php bin/garnet app:create MyApp`), which pins the dependency and wires the composer path-repo for you.

### Requirements

[](#requirements)

- PHP **8.1+**
- Extensions: `mbstring`, `json`, `pdo`, `mysqli`, `intl`
- MySQL **8.0+** or MariaDB **10.6+** (optional — only if you use the DB)
- Node.js **18+** (for the frontend build)
- Composer **2.x**

What you get in an app
----------------------

[](#what-you-get-in-an-app)

Once `app:create` finishes you have a working app that:

- Boots `php garnet serve` on `http://localhost:8001`.
- Has passwordless email auth and a wired admin console.
- Has CRUD scaffolding ready to plug into via `IEntityConfig`.
- Has a `php garnet build` frontend pipeline (rspack) that watches and rebuilds on save.

```
MyApp/
├── garnet              # local CLI wrapper
├── composer.json
├── package.json
├── Application.php     # main app class
├── Common/             # shared services
├── Foreground/         # public-facing controllers + Twig
├── Dashboard/          # admin panel (optional)
├── Front/              # business-specific React + CSS
├── Migrations/         # DB schema migrations
└── WorkDir/            # runtime: config, caches, logs (gitignored)

```

See `docs/quickstart.md` for the step-by-step.

Architecture, in one paragraph
------------------------------

[](#architecture-in-one-paragraph)

A request hits `public/index.php` → `IoRunWeb::run` builds the global request state → middlewares run in order → the O(1) router dispatches to a controller method (`get__foo`, `post__bar`) → the controller prepares a typed array and hands it to Twig → Twig renders the response, which is emitted by `Emitter`. CLI commands take the same shape via `IoRunConsole` and `php garnet`. DbPool wraps `mysqli` with async support, so any controller can fan out reads concurrently. Bundles register themselves at boot, contributing routes, services, templates and asset roots without auto-discovery.

For the full story see [`docs/architecture.md`](docs/architecture.md).

Documentation
-------------

[](#documentation)

- [`docs/quickstart.md`](docs/quickstart.md) — scaffold a new app
- [`docs/dev-workflow.md`](docs/dev-workflow.md) — develop framework + app together
- [`docs/architecture.md`](docs/architecture.md) — layers, request lifecycle, async DB
- [`docs/bundle.md`](docs/bundle.md) — writing your own bundle
- [`docs/cli.md`](docs/cli.md) — every CLI command
- [`docs/database.md`](docs/database.md) — DbPool, DbTable, async patterns
- [`docs/frontend.md`](docs/frontend.md) — React islands, codegen, asset bridge
- [`docs/i18n.md`](docs/i18n.md) — translation pipeline
- [`docs/deploy.md`](docs/deploy.md) — production deploy via `garnet bundle` / `deploy:diff`
- [`docs/testing.md`](docs/testing.md) — kahlan specs, writing tests
- [`docs/e2e-testing.md`](docs/e2e-testing.md) — Playwright end-to-end tests
- [`docs/core.md`](docs/core.md) — kernel-level primitives
- [`docs/io.md`](docs/io.md) — HTTP, CLI dispatch, Twig, config, caching, mailer
- [`docs/ssh.md`](docs/ssh.md) — SSH connection and remote commands
- [`docs/known-issues.md`](docs/known-issues.md) — sharp edges
- [`docs/cookbook/`](docs/cookbook/) — short copy-friendly recipes (routes, islands, CRUD, parallel queries, emails, uploads, i18n, validation, CLI commands, bundles)
- [`AGENTS.md`](AGENTS.md) — onboarding for AI agents / new devs

Known limitations (v0.x)
------------------------

[](#known-limitations-v0x)

Garnet evolved out of a booking platform, and a few framework primitives still carry domain names from that lineage. They work fine, but they look booking-shaped from the outside:

- `FwBalanceLedger` entry types are stored as string values `booking_invoice`, `booking_payment`, `booking_refund`. v1.0 will rename them to generic equivalents (`tx_invoice`, `tx_payment`, `tx_refund`) with a migration path.
- `FwAppSettings::cancellationPenaltyPercent` is a booking-domain setting in the framework's settings module; v1.0 will move it to the application layer.
- A handful of CRUD-action i18n keys reference `booking_*` operations (e.g. `AdminAction_booking_cancel`). They'll be generalised the same way.

Until v1.0 the framework is the most natural fit for booking / scheduling / appointment-style apps, but it works for plain CRUD or content apps too — these booking-shaped pieces are isolated to a few classes you can ignore if you don't need them.

Development
-----------

[](#development)

```
git clone https://github.com/PHPCraftdream/garnet-framework
cd garnet-framework
composer install
composer ci             # phpstan + cs:check + kahlan
```

See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the contribution flow.

Security
--------

[](#security)

If you discover a security issue, please **do not** open a public issue. See [`SECURITY.md`](SECURITY.md) for the responsible-disclosure contact and policy.

License
-------

[](#license)

Garnet Framework is **dual-licensed under MIT or Apache-2.0**, at your option. Pick whichever fits your project — both texts ship with the repo:

- [LICENSE-MIT](LICENSE-MIT)
- [LICENSE-APACHE](LICENSE-APACHE)

Unless you explicitly state otherwise, any contribution submitted for inclusion shall be dual-licensed as above, without any additional terms or conditions.

© PHPCraftdream and contributors.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance93

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

5

Last Release

17d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/14233546?v=4)[Arch-AI-tech](/maintainers/PHPCraftdream)[@PHPCraftdream](https://github.com/PHPCraftdream)

---

Top Contributors

[![PHPCraftdream](https://avatars.githubusercontent.com/u/14233546?v=4)](https://github.com/PHPCraftdream "PHPCraftdream (61 commits)")

---

Tags

asyncfastcgiframeworkfrontendhigh-performancekahlanmysqlopcacheopinionatedphpphp-frameworkphp8phpstanplaywrightreactrouterrspacktwigweb-frameworkphpasyncframeworkwebroutermysql

###  Code Quality

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpcraftdream-garnet-framework/health.svg)

```
[![Health](https://phpackages.com/badges/phpcraftdream-garnet-framework/health.svg)](https://phpackages.com/packages/phpcraftdream-garnet-framework)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.3k42.4k21](/packages/tempest-framework)[shopware/platform

The Shopware e-commerce core

3.4k1.5M3](/packages/shopware-platform)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

605.9M712](/packages/shopware-core)[symfony/symfony

The Symfony PHP framework

31.4k87.7M2.3k](/packages/symfony-symfony)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[laravel/framework

The Laravel Framework.

35.4k569.8M21.9k](/packages/laravel-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
