PHPackages                             scrapyard-io/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. scrapyard-io/framework

ActiveLibrary[Framework](/categories/framework)

scrapyard-io/framework
======================

The ScrapyardIO Framework.

0.4.4(1mo ago)062MITPHPPHP ^8.3

Since Jun 2Pushed 2w agoCompare

[ Source](https://github.com/ScrapyardIO/framework)[ Packagist](https://packagist.org/packages/scrapyard-io/framework)[ Docs](https://scrapyard-io.projectsaturnstudios.com)[ RSS](/packages/scrapyard-io-framework/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (10)Used By (2)

The ScrapyardIO Framework
=========================

[](#the-scrapyardio-framework)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2015d5021ed548b93428ffd5d7c515627a003173e4d29686018451bdd6771c3a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7363726170796172642d696f2f6672616d65776f726b2e737667)](https://packagist.org/packages/scrapyard-io/framework)[![Total Downloads](https://camo.githubusercontent.com/8de8fb68e541d951f2eeeb5a2ad3e9c4a1d95fa9dde62deeb5b223a85687153d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7363726170796172642d696f2f6672616d65776f726b2e737667)](https://packagist.org/packages/scrapyard-io/framework)[![License](https://camo.githubusercontent.com/353c028f2f2e7acdd40ab371812f72bda0fab251b40b2f8368e6c6b38c8f0c80/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7363726170796172642d696f2f6672616d65776f726b2e737667)](LICENSE)

A PHP 8.3+ framework for talking to real hardware — displays, sensors, GPIO pins, and serial buses — from a single-board computer or a laptop via USB. Write the same PHP code whether you are running on a Raspberry Pi or wiring up an FT232H breakout on macOS.

---

Contents
--------

[](#contents)

- [Architecture](#architecture)
- [Requirements](#requirements)
- [Installation](#installation)
- [The Extension Stack](#the-extension-stack)
- [Config-based Device Loading](#config-based-device-loading)
- [Waveforms — the Transport Layer](#waveforms--the-transport-layer)
    - [SPI](#spi)
    - [I²C](#ic)
    - [GPIO](#gpio)
    - [UART](#uart)
- [RealityInterface — Displays](#realityinterface--displays)
- [RealityInterface — Sensors](#realityinterface--sensors)
- [GFX Renderer](#gfx-renderer)
- [Device Drivers (DeptOfScrapyardRobotics)](#device-drivers-deptofscrapyardrobotics)
- [License](#license)

---

Architecture
------------

[](#architecture)

ScrapyardIO is a layered monorepo. The `scrapyard-io/framework` package replaces four logical sub-packages via Composer's `replace` key:

Sub-packagePurpose`scrapyard-io/waveforms`Protocol transports — SPI, I²C, GPIO, UART`scrapyard-io/reality-interface`Typed display and sensor abstractions`scrapyard-io/nuts-and-bolts`Pixel buffers, `FormatSpec`, enums, helpers`scrapyard-io/bare-metal``IntegratedCircuit` base class, config repositories```
┌──────────────────────────────────────────────────────────────────┐
│  Application  (Laravel, CLI, Artisan commands, etc.)             │
├──────────────────────────────────────────────────────────────────┤
│  RealityInterface                                                 │
│    Displays:  Screen → Display → EmbeddedDisplay (chip driver)   │
│    Sensors:   Sensor → SensorChip (chip driver)                  │
├──────────────────────────────────────────────────────────────────┤
│  DeptOfScrapyardRobotics  (chip drivers for DOSR hardware)       │
├──────────────────────────────────────────────────────────────────┤
│  Waveforms  (SPI · I²C · GPIO · UART)                            │
├──────────────────────────────────────────────────────────────────┤
│  BareMetal  (IntegratedCircuit, config repositories)             │
├──────────────────────────────────────────────────────────────────┤
│  NutsAndBolts  (buffers · FormatSpec · enums · helpers)          │
└──────────────────────────────────────────────────────────────────┘

```

Each layer depends only on the one below it. Chip drivers (DOSR packages) sit between Waveforms and RealityInterface — they implement the chip-level contracts (`DisplayInterface`, `GenericDistanceSensor`, etc.) and expose a fluent `::connection()` builder.

**Two transport modes** run the same application code on different hardware:

ModeUsed onBacked by`native`Linux SBCs (Raspberry Pi, Jetson Orin, …)`ext-posi` (POSIX syscalls)`usb`Any Linux or macOS machine with an FTDI adapter`ext-ftdi` + `microscrap/mpsse` (SPI/I²C/GPIO); `ext-ftdi` + `microscrap/ftdi` (UART)---

Requirements
------------

[](#requirements)

- PHP 8.3+
- For **native** (SBC) transport: [`ext-posi`](https://github.com/php-io-extensions/posi) ^0.4.0
- For **USB** transport: [`ext-ftdi`](https://github.com/php-io-extensions/ftdi) ^0.4.0 + `libftdi1` (SPI/I²C/GPIO go over MPSSE; UART is plain async serial)

Optional Composer packages that wrap those extensions with helpers and enums:

PackageWrapsAdds[`microscrap/posix`](https://github.com/microscrap/posix)`ext-posi`Global `posix_open`, `posix_read`, `fcntl`, `ioctl`, … helpers[`microscrap/ftdi`](https://github.com/microscrap/ftdi)`ext-ftdi`Global `ftdi_usb_open`, `ftdi_read_data`, … helpers[`microscrap/spi`](https://github.com/microscrap/spi)`ext-posi``spi_open`, `spi_transfer`, `SPITransfer`, `SPIMode` enum[`microscrap/i2c`](https://github.com/microscrap/i2c)`ext-posi``i2c_open`, `i2c_rdwr`, SMBus helpers, `I2CMsgFlag` enum[`microscrap/gpio`](https://github.com/microscrap/gpio)`ext-posi`GPIO character device helpers, edge-event polling[`microscrap/uart`](https://github.com/microscrap/uart)`ext-posi``uart_open`, termios helpers, `BaudRate` enum[`microscrap/mpsse`](https://github.com/microscrap/mpsse)`ext-ftdi``MPSSE` static API, `mpsse_open`, typed enums, ACK/NACK, GPIO pins[`microscrap/phpdafruit-gfx`](https://github.com/microscrap/phpdafruit-gfx)—GFX renderer, partial-refresh buffers, fontsThe framework itself (`scrapyard-io/framework`) has no hard PHP-extension dependencies — it composes these optional packages at runtime.

---

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

[](#installation)

```
composer require scrapyard-io/framework
```

Install the DOSR chip drivers you need alongside it:

```
composer require dept-of-scrapyard-robotics/ssd1680  # ePaper B/W (122×250)
composer require dept-of-scrapyard-robotics/ssd1306  # OLED I²C/SPI
composer require dept-of-scrapyard-robotics/st77xx    # RGB565 TFT
composer require dept-of-scrapyard-robotics/vl53lxx  # Time-of-flight distance
composer require dept-of-scrapyard-robotics/hc-sr04  # Ultrasonic distance
# … etc.
```

---

The Extension Stack
-------------------

[](#the-extension-stack)

ScrapyardIO's native transport is built on two PHP C extensions.

### `ext-posi` — POSIX I/O

[](#ext-posi--posix-io)

[`php-io-extensions/posi`](https://github.com/php-io-extensions/posi) provides direct access to POSIX system calls from PHP: `open(2)`, `read(2)`, `write(2)`, `fcntl(2)`, `ioctl(2)`, and more. It is the foundation for all native SBC transports (SPI via `spidev`, I²C via `i2c-dev`, UART via `termios`, GPIO via `gpiod`).

Build and install on target platforms:

```
# Raspberry Pi / Debian
bash install-debian-trixie.sh

# Jetson Orin (JetPack 6)
bash install-jetpack6.sh

# macOS
bash install-macos.sh

# Or via PIE
pie install php-io-extensions/posi
```

Then add to `php.ini`:

```
extension=posi
```

`microscrap/posix` wraps the extension with C-style global helpers so calling code reads naturally:

```
$fd = posix_open('/dev/spidev0.0', O_RDWR);
posix_write($fd, $payload, strlen($payload));
posix_close($fd);
```

### `ext-ftdi` — libftdi1 Bindings

[](#ext-ftdi--libftdi1-bindings)

[`php-io-extensions/ftdi`](https://github.com/php-io-extensions/ftdi) wraps [libftdi1](https://www.intra2net.com/en/developer/libftdi/) so PHP can drive FTDI USB adapters (FT232H, FT232RL, etc.) directly. It powers the `usb` transport path — SPI, I²C, and GPIO are tunnelled over USB MPSSE, while UART runs as plain async serial through `microscrap/ftdi` (no MPSSE).

Runtime library requirements:

```
# Debian/Ubuntu/Raspberry Pi OS
apt install libftdi1-2

# macOS
brew install libftdi
```

`microscrap/ftdi` adds global helpers and `microscrap/mpsse` layers the higher-level MPSSE session API (start/stop, read/write, GPIO pin control) on top of them:

```
use Microscrap\Bindings\MPSSE\MPSSE;
use Microscrap\Bindings\MPSSE\Enums\{MPSSEMode, MPSSEEndianness, MPSSEClockRate, MpsseSupportedDevice};

$ctx = MPSSE::openDevice(
    MpsseSupportedDevice::FT232H,
    MPSSEMode::SPI0,
    MPSSEClockRate::ONE_MHZ->value,
    MPSSEEndianness::MSB,
);

MPSSE::start($ctx);
MPSSE::write($ctx, "\x9F");
$id = MPSSE::read($ctx, 3);
MPSSE::stop($ctx);
MPSSE::close($ctx);
```

---

Config-based Device Loading
---------------------------

[](#config-based-device-loading)

For production deployments where chips are permanently wired, you can preload all device definitions from a config file rather than constructing them inline.

**1. Set the config path in `.env`:**

```
SCRAPYARD_CONFIG_PATH=/home/pi/my-project/config
```

**2. Create `scrapyard-io.php` in that directory:**

```
use DeptOfScrapyardRobotics\Displays\SSD1680\SSD1680;
use DeptOfScrapyardRobotics\Sensors\VL53Lxx\VL53L0X;

return [
    'displays' => [
        'eink-panel' => [
            'class_name' => SSD1680::class,
            'connection' => ['driver' => 'usb'],
            'startup' => [
                'spi'      => ['ft232h', 0],
                'gpiochip' => ['ft232h'],
                'rst'      => [0],
                'dc'       => [1],
                'create'   => [],
            ],
        ],
    ],
    'sensors' => [
        'tof-sensor' => [
            'class_name' => VL53L0X::class,
            'connection' => ['driver' => 'usb'],
            'startup' => [
                'i2c'    => ['ft232h', 0x29],
                'create' => [],
            ],
        ],
    ],
];
```

**3. Resolve devices by config key:**

```
use RealityInterface\Displays\BWePaperDisplay;
use RealityInterface\Sensors\TimeOfFlightDistanceSensor;

$display = BWePaperDisplay::using('eink-panel');
$sensor  = TimeOfFlightDistanceSensor::using('tof-sensor');
```

Consult each DOSR package's README for the exact `startup` key shape for that chip.

---

Waveforms — the Transport Layer
-------------------------------

[](#waveforms--the-transport-layer)

`Waveforms\` provides the four bus protocols that chip drivers build on. Each has a `native` path (Linux kernel drivers via `ext-posi`) and a `usb` path. SPI, I²C, and GPIO drive the FT232H over `ext-ftdi` + `microscrap/mpsse`; UART instead uses `ext-ftdi` + `microscrap/ftdi` as plain async serial (no MPSSE).

### SPI

[](#spi)

```
use Waveforms\Carriers\SPI\SPI;

// Native — spidev on a Raspberry Pi
$spi = SPI::connection('native')
    ->device('/dev/spidev0.0')
    ->mode(0)
    ->speed(8_000_000)
    ->create();

// USB — FT232H via MPSSE
$spi = SPI::connection('usb')
    ->device('ft232h')
    ->speed(1_000_000)
    ->create();
```

Under the hood the native path uses `microscrap/spi` (`spi_open`, `spi_transfer`). The USB path opens an MPSSE session in `SPI0` mode.

### I²C

[](#ic)

```
use Waveforms\Carriers\I2C\I2C;

// Native — i2c-dev on a Raspberry Pi
$i2c = I2C::connection('native')
    ->bus('/dev/i2c-1')
    ->address(0x38)
    ->create();

// USB — FT232H via MPSSE (I2C mode)
$i2c = I2C::connection('usb')
    ->device('ft232h')
    ->address(0x38)
    ->create();
```

### GPIO

[](#gpio)

```
use Waveforms\Carriers\GPIO\GPIO;
use Waveforms\Carriers\GPIO\API\Native\{NativeGPIOInput, NativeGPIOOutput};
use Waveforms\Carriers\GPIO\API\USB\{UsbGPIOInput, UsbGPIOOutput};

// Native — Linux gpiod character device
$echo = NativeGPIOInput::line(22)->edgeEvents()->alias('echo');
$trig = NativeGPIOOutput::line(24)->alias('trig');

$bus = GPIO::connection('native')
    ->gpiochip(0)
    ->addInput($echo)
    ->addOutput($trig)
    ->nonblocking()
    ->consumer('distance-sensor')
    ->boot();

$bus->trig()->high();
usleep(10);
$bus->trig()->low();
$value = $bus->echo()->read();

// USB — FT232H CBUS/ADBUS GPIO pins
$echo = UsbGPIOInput::pin(0)->edgeEvents()->alias('echo');
$trig = UsbGPIOOutput::pin(1)->alias('trig');

$bus = GPIO::connection('usb')
    ->device('ft232h')
    ->addInput($echo)
    ->addOutput($trig)
    ->consumer('distance-sensor')
    ->boot();
```

### UART

[](#uart)

```
use Waveforms\Carriers\UART\UART;

// Native — /dev/ttyUSB0 via termios
$uart = UART::connection('native')
    ->port('/dev/ttyUSB0')
    ->baud(115200)
    ->create();

// USB — FT232RL serial over libftdi
$uart = UART::connection('usb')
    ->device('ft232rl')
    ->baud(115200)
    ->create();
```

Under the hood the native path uses `microscrap/uart` (termios). Unlike SPI, I²C, and GPIO, the USB path does **not** use MPSSE — it drives the FTDI chip as a plain async serial port via `microscrap/ftdi` (the adapter is reset to async-serial bitmode on open).

---

RealityInterface — Displays
---------------------------

[](#realityinterface--displays)

`RealityInterface\Displays\` provides the display abstraction stack. Application code works with the applied classes (`BWePaperDisplay`, `ColorTFTDisplay`, etc.) and never touches chip registers directly.

### Applied display classes

[](#applied-display-classes)

ClassPixel formatChip contracts it targets`MonochromeDisplay`1bpp monoSSD1306, SH1106 (OLED)`ColorTFTDisplay`RGB565ST7735, ST7789, ST7796, GC9A01`BWePaperDisplay`1bpp B/WSSD1680, IL3820`TriColorePaperDisplay`1bpp B/W + 1bpp redSSD1680 (B/W/R mode)`QuadColorePaperDisplay`2bpp B/W/R/YJD79661### Constructing a display

[](#constructing-a-display)

```
use DeptOfScrapyardRobotics\Displays\SSD1680\SSD1680;
use RealityInterface\Displays\BWePaperDisplay;

// Inline — useful during development
$chip = SSD1680::connection('usb')
    ->spi('ft232h', 0)
    ->gpiochip('ft232h')
    ->rst(0)
    ->dc(1)
    ->create();

$display = BWePaperDisplay::as($chip);
```

### Drawing with `Screen`

[](#drawing-with-screen)

`Screen` is the fluent drawing surface. It wraps a `GFXRenderer` (from `microscrap/phpdafruit-gfx`), transcodes the rendered buffer through the display's `FormatSpec`, and ships the bytes to the panel.

```
use RealityInterface\Displays\Screen;

$screen = Screen::on($display);

$screen
    ->fill(0x00)
    ->drawRect(2, 2, 118, 60, 0xFF)
    ->setTextColor(0xFF)
    ->setCursor(10, 20)
    ->print('Hello from PHP')
    ->render();
```

`render()` calls `display->transmit(DumpedBuffer)` internally; partial-refresh panels receive only dirty pages/regions.

---

RealityInterface — Sensors
--------------------------

[](#realityinterface--sensors)

`RealityInterface\Sensors\` mirrors the display stack for sensor chips. Each applied class carries a capability attribute that chip drivers must declare.

### Applied sensor classes

[](#applied-sensor-classes)

ClassCapabilityChip contract`DistanceSensor``MeasuresDistance``GenericDistanceSensor``UltrasonicDistanceSensor`extends `DistanceSensor``PulseDerivedDistanceSensor``TimeOfFlightDistanceSensor`extends `DistanceSensor``LaserGuidedDistanceSensor``Accelerometer``MeasuresAcceleration``GenericAccelerometer``AmbientLightSensor``MeasuresLuminance``GenericLuxSensor``TemperatureSensor``MeasuresTemperature``TemperatureSensor``RelativeHumiditySensor``MeasuresRelativeHumidity``RHSensor``BarometricPressureSensor``MeasuresBarometricPressure``PressureSensor``RFIDScanner``NearFieldCommunications``GenericRFIDScanner``GPSSensor``TriangulatesPosition``GlobalPositioningSystem``HumanPresenceDetector``MeasuresObjectPresence``HumanPresenseSensor`### Reading a sensor

[](#reading-a-sensor)

```
use DeptOfScrapyardRobotics\Sensors\VL53Lxx\VL53L0X;
use RealityInterface\Sensors\TimeOfFlightDistanceSensor;

$chip   = VL53L0X::connection('native')->i2c('/dev/i2c-1', 0x29)->create();
$sensor = TimeOfFlightDistanceSensor::as($chip);

$reading = $sensor->getDistance();
echo $reading->millimeters() . ' mm';
```

### Driver-agnostic GPS

[](#driver-agnostic-gps)

`GPSSensor` wraps any NMEA GPS chip behind one common API. Inject an MTK3339 or a GY-NEO6M and the application code is identical — `fixQuality()` returns a driver-agnostic `GpsFixQuality` enum so callers never need to know which module is plugged in.

```
use DeptOfScrapyardRobotics\Sensors\GYNEO6M\GYNEO6M\GYNEO6M;
use RealityInterface\Sensors\Applied\GPS\GPSSensor;
use RealityInterface\Sensors\Enums\GpsFixQuality;

$chip = GYNEO6M::connection('usb')->uart('ft232h', 9600)->create();
$gps  = GPSSensor::as($chip);

$gps->update(); // fold the next NMEA sentence into the running fix

if ($gps->fixQuality() === GpsFixQuality::GPS) {
    printf("%.6f, %.6f\n", $gps->getLatitude(), $gps->getLongitude());
}
```

---

GFX Renderer
------------

[](#gfx-renderer)

[`microscrap/phpdafruit-gfx`](https://github.com/microscrap/phpdafruit-gfx) is the rendering engine used by `Screen`. It is modelled on [Adafruit-GFX](https://github.com/adafruit/Adafruit-GFX-Library) and draws into a `FormatSpecFrameBuffer`. The buffer's `FormatSpec` determines how pixels are packed on `dump()` — the same drawing calls produce 1bpp mono page buffers for an OLED or RGB565 for a TFT.

### Primitives

[](#primitives)

CategoryMethodsPixels`drawPixel`, `drawPixels`, `fill`, `fillScreen`Lines`drawLine`, `drawHLine`, `drawVLine`, `drawLines`Rectangles`drawRect`, `fillRect`, `drawRoundRect`, `fillRoundRect`Curves`drawCircle`, `fillCircle`, `drawEllipse`, `fillEllipse`Triangles`drawTriangle`, `fillTriangle`Text`print`, `println`, `setCursor`, `setTextColor`, `setTextSize`, `setFont`Bitmaps`drawBitmap`, `drawXBitmap`, `drawColorMap`Images`drawImageFromFile` (requires `ext-gd`)Dithering`ditherFloydSteinberg`, `drawImageDithered` (requires `ext-gd`)### Partial-refresh buffers

[](#partial-refresh-buffers)

BufferUse case`PageSegmentBuffer`Monochrome OLED panels — emits one update per dirty 8-row page`DirtyRegionsBuffer`Color TFTs — coalesces changed rectangles, emits one update per region```
use Microscrap\GFX\PhpdaFruit\GFXRenderer;
use Microscrap\GFX\PhpdaFruit\Buffers\PageSegmentBuffer;
use ScrapyardIO\NutsAndBolts\Enums\{BitDepth, BitOrder, PixelFormat};

$buffer = PageSegmentBuffer::size(128, 64)
    ->pixelFormat(PixelFormat::MONO_VERTICAL_PAGE)
    ->bitDepth(BitDepth::B1)
    ->bitOrder(BitOrder::LSB_FIRST)
    ->build();

$renderer = new GFXRenderer($buffer);
$renderer->fill(0)->drawCircle(64, 32, 20, 1)->print('ok');

$updates = $renderer->render(); // array of DumpedBuffer
```

---

Device Drivers (DeptOfScrapyardRobotics)
----------------------------------------

[](#device-drivers-deptofscrapyardrobotics)

All chip drivers live in separate `dept-of-scrapyard-robotics/*` packages. Every driver follows the same fluent builder pattern and plugs cleanly into the `RealityInterface` applied classes above.

### Displays

[](#displays)

PackageChipsWrapper`ssd1680`SSD1680 — 122×250 ePaper`BWePaperDisplay`, `TriColorePaperDisplay``jd79661`JD79661 — 2bpp quad-color ePaper`QuadColorePaperDisplay``st77xx`ST7735 (128×160), ST7789 (240×320), ST7796 (480×320)`ColorTFTDisplay``gc9a01`GC9A01 — 240×240 round TFT`ColorTFTDisplay``ssd1306`SSD1306 — monochrome OLED (I²C or SPI)`MonochromeDisplay``sh1106`SH1106 — monochrome OLED (I²C)`MonochromeDisplay``il3820`IL3820 — ePaper controllerePaper wrappers### Sensors

[](#sensors)

PackageChipsTypeWrapper`vl53lxx`VL53L0X, VL53L1X, VL6180XTime-of-flight (I²C)`TimeOfFlightDistanceSensor``hc-sr04`HC-SR04Ultrasonic (GPIO)`UltrasonicDistanceSensor``adxl34x`ADXL345Accelerometer (I²C/SPI)`Accelerometer``lis3dx`LIS3DH, LIS3DSHAccelerometer (I²C/SPI)`Accelerometer``msa3xx`MSA311, MSA301Accelerometer (I²C)`Accelerometer``bh1750`BH1750Ambient light (I²C)`AmbientLightSensor``tsl2591`TSL2591Dual-channel lux (I²C)`AmbientLightSensor``veml7000`VEML7000Ambient light (I²C)`AmbientLightSensor``ahtx0`AHT10, AHT20, AHT30Temp + RH (I²C)`TemperatureSensor`, `RelativeHumiditySensor``bmp`BMP280Temp + pressure (I²C/SPI)`TemperatureSensor`, `BarometricPressureSensor``as3935`AS3935Lightning detector (SPI)Direct (no typed wrapper)`rfid`NFC/RFID controllersI²C/SPI/UART + GPIO`RFIDScanner``mtk3339`MTK3339GPS (UART + optional GPIO)`GPSSensor``gy-neo6m`GY-NEO6M (u-blox NEO-6M)GPS (UART)`GPSSensor``ld24xx`LD2410CHuman presence radar (UART)`HumanPresenceDetector`Each package's README documents the exact `::connection()` builder chain and the `scrapyard-io.php` config shape for that chip.

---

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance94

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 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 ~4 days

Total

9

Last Release

17d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10563160?v=4)[Angel Gonzalez](/maintainers/projectsaturnstudios)[@projectsaturnstudios](https://github.com/projectsaturnstudios)

---

Top Contributors

[![projectsaturnstudios](https://avatars.githubusercontent.com/u/10563160?v=4)](https://github.com/projectsaturnstudios "projectsaturnstudios (9 commits)")

---

Tags

frameworkscrapyard-io

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/scrapyard-io-framework/health.svg)

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

PHPackages © 2026

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