PHPackages                             epolabs/boundly - 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. epolabs/boundly

ActiveProject[Framework](/categories/framework)

epolabs/boundly
===============

The Metadata-Driven PHP Framework. Define your Domain. BOUNDLY handles the rest.

v0.9.0-alpha(1mo ago)12↑1400%MITPHPPHP ^8.3CI passing

Since Mar 22Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/EpOpenLabs/BOUNDLY)[ Packagist](https://packagist.org/packages/epolabs/boundly)[ RSS](/packages/epolabs-boundly/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (9)Versions (11)Used By (0)

🪄 BOUNDLY
=========

[](#-boundly)

**The Metadata-Driven PHP Framework**

> *Build enterprise-grade APIs by defining only your Domain. Everything else is automatic.*

**Metadata-driven. Convention-over-Configuration. Zero Boilerplate.**

[![License: MIT](https://camo.githubusercontent.com/e843ce4eed2908288cada32b82c766977cac608e3ca73043ae3c5d06921b2bb9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d76696f6c65742e737667)](https://opensource.org/licenses/MIT)[![PHP Version](https://camo.githubusercontent.com/89899a77bdce65fc4c3d3423dfacff9c6461066a0b5354dc18d7721c23ba596e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d626c75652e737667)](https://www.php.net/)[![Laravel](https://camo.githubusercontent.com/0fdafe0a46557bea1a7797fe03cbaa4b036e70cc4e02930f0d4a028ce830a974/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31332532422d7265642e737667)](https://laravel.com/)[![Version](https://camo.githubusercontent.com/e05671faf14409748ddff55a87797c1a2ac4c165f4eca48f364fac5ce4bc1827/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d76302e392e312d626c75652e737667)](https://github.com/EpOpenLabs/BOUNDLY/releases)[![CI](https://github.com/EpOpenLabs/BOUNDLY/actions/workflows/ci.yml/badge.svg)](https://github.com/EpOpenLabs/BOUNDLY/actions/workflows/ci.yml)[![PHPStan](https://camo.githubusercontent.com/a888f2d0226abcd1d67c047cb99223a0e99ec37b6385ea64571479fb347783e2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d4c6576656c253230352d627269676874677265656e2e737667)](https://phpstan.org/)[![Tests](https://camo.githubusercontent.com/68c1c2a5283eb7a92a393d6beb2f5526f4364c4747d04da29931784a0ce9dbf9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d32313825323070617373696e672d627269676874677265656e2e737667)](https://github.com/EpOpenLabs/BOUNDLY/actions/workflows/ci.yml)[![Packagist](https://camo.githubusercontent.com/21aa622ac3d757381032b842c37d9a7854e659c77d84530810bef5162fd56de4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5061636b61676973742d76302e392e312d76696f6c65742e737667)](https://packagist.org/packages/epolabs/boundly)

---

🗺️ Roadmap &amp; Strategy
-------------------------

[](#️-roadmap--strategy)

Stay updated on our progress toward **v1.0.0**. We are currently in active alpha development.

👉 **[View Full Roadmap on Wiki](https://github.com/EpOpenLabs/BOUNDLY/wiki/Roadmap)**

---

🧠 What is BOUNDLY?
------------------

[](#-what-is-boundly)

**BOUNDLY** is a high-performance PHP framework that uses **Metadata-Driven Architecture** and **Convention-over-Configuration**. It eliminates boilerplate code by using PHP 8+ **Attributes** as the single source of truth for your infrastructure.

You define your **Domain** (entities, actions, business logic). BOUNDLY handles the **Infrastructure** (routes, controllers, validation, persistence).

- ✅ **Zero manual migrations** — Your DB schema evolves with your code.
- ✅ **Zero route files** — Your endpoints are declared on your Actions.
- ✅ **Zero boilerplate repositories** — Generic CRUD is handled automatically.
- ✅ **Zero validation rules** — Payloads are validated against your entity attributes.
- ✅ **Enterprise features in one line** — Auditing, Soft Delete, Multi-Tenancy, Authorization, Rate Limiting.
- ✅ **Real-Time Agnostic** — Propagate Domain Events to WebSockets without coupling your logic to a visual driver.
- ✅ **Production-ready** — Static metadata cache, migration history, OpenAPI docs, and full CI/CD included.

---

🏛️ Architecture: Pure DDD
-------------------------

[](#️-architecture-pure-ddd)

BOUNDLY enforces a clean, screaming architecture where the folder structure tells you *what the system does*, not *what framework it uses*.

```
/
├── Application/          # Use Cases (Actions, DTOs)
│   └── Users/
│       ├── Actions/      # #[Action] defines the API endpoint
│       └── DTOs/
├── Domain/               # Pure Business Logic
│   └── Users/
│       ├── Entities/     # #[Entity] defines the DB table
│       ├── Events/
│       └── ValueObjects/
├── Infrastructure/       # Technical Adapters
│   ├── FrameworkCore/    # The BOUNDLY Engine (CLI, Repos, Attributes)
│   └── LaravelEngine/   # Laravel internals (config, storage, routes...)
├── bootstrap/            # Framework ignition point
├── config/               # Your project config (boundly.php)
├── public/               # Web entry point
└── artisan               # CLI entry point

```

---

🔥 Key Features
--------------

[](#-key-features)

### 🧬 1. Magic Evolution (Auto DB Sync)

[](#-1-magic-evolution-auto-db-sync)

Forget `php artisan migrate`. Define your entity, run the daemon, and your database evolves automatically.

```
#[Entity(table: 'users', resource: 'users')]
#[Auditable]
#[SoftDelete]
class User extends AggregateRoot
{
    #[Id]
    private int $id;

    #[Column(type: 'string', length: 150)]
    private string $name;

    #[Column(type: 'string', nullable: true, default: '555-0000')]
    private string $phone;
}
```

Run `php artisan core:watch` and your `/api/users` endpoint is live. ✨

---

### 🔐 2. Declarative Authorization

[](#-2-declarative-authorization)

Protect any resource with a single attribute — no route middleware, no guards to register manually:

```
// Only admins and managers can access this resource
#[Entity(table: 'salaries', resource: 'salaries')]
#[Authorize(roles: ['admin', 'manager'])]
class Salary extends AggregateRoot { ... }

// Public reads, auth required for writes
#[Entity(table: 'articles', resource: 'articles')]
#[Authorize(roles: [], methods: ['POST', 'PUT', 'PATCH', 'DELETE'])]
class Article extends AggregateRoot { ... }
```

---

### 🛡️ 3. Declarative Behavioral Traits

[](#️-3-declarative-behavioral-traits)

Add enterprise features with a single attribute:

AttributeWhat it does`#[Auditable]`Injects `created_by` / `updated_by` — auto-populated from the request`#[SoftDelete]`Handles `deleted_at` and filters queries silently`#[TenantAware]`Multi-tenant data isolation at the repository level`#[Authorize]`Role-based access control — reads PHP Attributes, not config files`#[Blameable]`Extended audit trail tracking created\_by/updated\_by/deleted\_by`#[Timestampable]`Auto-manage created\_at/updated\_at timestamps`#[Sluggable]`Auto-generate URL-friendly slugs from another field`#[Policy]`Map Laravel Policies for fine-grained authorization### 🔒 4. Security Attributes

[](#-4-security-attributes)

Protect sensitive data with declarative security:

AttributeWhat it does`#[Hidden]`Exclude properties from API responses`#[Encrypted]`Encrypt at rest with AES-256-CBC`#[Hashed]`One-way hashing (bcrypt/Argon2)`#[RateLimit]`API rate limiting with per-IP/user tracking### 🛡️ 5. Built-in Security

[](#️-5-built-in-security)

Enterprise-grade security out of the box:

FeatureDescription**Input Sanitization**Whitelist approach - only declared columns are accepted**SQL Injection Prevention**Column whitelist validation in DynamicRepository**Rate Limiting**Built-in `#[RateLimit]` attribute**Authorization**`#[Authorize]` attribute with role-based access control### ✅ 6. 40+ Validation Attributes

[](#-6-40-validation-attributes)

Comprehensive data validation out of the box:

- **Type**: Email, Url, IpAddress, Uuid, Json, IsoDate, Timezone, ColorHex, Slug, MacAddress
- **Numeric**: Min, Max, Between, Positive, Negative, Integer, Decimal
- **String**: MinLength, MaxLength, LengthBetween, Alpha, Alphanumeric, Numeric, Pattern, StartsWith, EndsWith, Contains
- **Format**: Phone, CreditCard, PostalCode, Coordinates
- **Database**: Unique, Exists, Enum
- **File**: Image, Mimes, FileSize
- **Compound**: Required, Confirmed, Password, StrongPassword, SameAs, DifferentFrom

### 🔗 7. Complete Relations Suite

[](#-7-complete-relations-suite)

All relationship types supported:

RelationAttributeOne-to-Many`#[BelongsTo]` / `#[HasMany]`One-to-One`#[HasOne]`Many-to-Many`#[ManyToMany]` (with pivot sync)Polymorphic`#[MorphTo]` / `#[MorphMany]` / `#[MorphOne]`### 🔎 8. Pro Query Engine

[](#-8-pro-query-engine)

Complex filtering, nested eager loading, and dual pagination out-of-the-box:

```
# Partial search
GET /api/users?name_like=boundly

# Range filtering with new operators
GET /api/users?age_gte=18&score_lte=100

# NOT and IN operators
GET /api/products?category_not=5&id_in=1,2,3

# OR filter groups
GET /api/users?or[name_like]=john&or[email_like]=john

# Nested eager loading (dot-notation)
GET /api/users?include=posts.comments.author

# Cursor pagination (efficient for large datasets)
GET /api/events?cursor=250&per_page=20

# Sorting & standard pagination
GET /api/users?sort=name&direction=asc&per_page=20
```

---

### 🌍 9. Full Internationalization (i18n)

[](#-9-full-internationalization-i18n)

Console output speaks your language:

```
php artisan core:watch --lang=es
```

---

### 📡 10. Agnostic WebSockets Bridge

[](#-10-agnostic-websockets-bridge)

Broadcast your domain events to the frontend in real-time, completely decoupled from infrastructure (Reverb, Pusher, Soketi) using the purely semantic `ShouldBroadcastToExterior` contract. [Read the Integration Guide](https://github.com/EpOpenLabs/BOUNDLY/wiki/WebSockets-Integration)

---

🚀 Quick Start
-------------

[](#-quick-start)

### 1. Create a new project

[](#1-create-a-new-project)

```
composer create-project epolabs/boundly boundly --stability=alpha
cd my-project
```

Or clone the repository:

```
git clone https://github.com/EpOpenLabs/BOUNDLY.git my-project
cd my-project
composer install
```

### 2. Configure environment

[](#2-configure-environment)

```
cp .env.example .env
php artisan key:generate
```

Configure your database in `.env`:

```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=my_project
DB_USERNAME=root
DB_PASSWORD=secret
```

### 2. Configure your database

[](#2-configure-your-database)

```
# .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=my_project
DB_USERNAME=root
DB_PASSWORD=secret
```

### 3. Define your Entity

[](#3-define-your-entity)

```
// Domain/Users/Entities/User.php
#[Entity(table: 'users', resource: 'users')]
#[Auditable]
class User extends AggregateRoot
{
    #[Id]
    private int $id;

    #[Column(type: 'string', length: 150)]
    private string $name;

    #[Column(type: 'string', unique: true)]
    private string $email;
}
```

### 4. Start the daemon

[](#4-start-the-daemon)

```
php artisan core:watch
```

🎉 Your API is live at `http://localhost:8000/api/users`.

### 5. Before deploying to production

[](#5-before-deploying-to-production)

```
# Preview schema changes
php artisan core:migrate --dry-run

# Apply schema
php artisan core:migrate

# Cache metadata for zero-overhead boot
php artisan core:cache

# Generate OpenAPI documentation
php artisan core:docs
```

---

⚙️ Configuration Reference
--------------------------

[](#️-configuration-reference)

KeyDefaultEnv VariableDescription`locale``en``BOUNDLY_LOCALE`Default language for CLI output`api_prefix``api``BOUNDLY_API_PREFIX`URL prefix for all auto-generated routes`disable_cache``true` in local`BOUNDLY_DISABLE_CACHE`Forces scan mode; set `false` in production`auth.default_guard``sanctum``BOUNDLY_AUTH_GUARD`Guard used by `#[Authorize]` middleware`pagination.default_per_page``15``BOUNDLY_PER_PAGE`Default page size`pagination.max_per_page``100``BOUNDLY_MAX_PER_PAGE`Hard cap on page size`rate_limit.enabled``true``BOUNDLY_RATE_LIMIT_ENABLED`Enable/disable rate limiting`rate_limit.max_attempts``60``BOUNDLY_RATE_LIMIT_MAX_ATTEMPTS`Max requests per window`rate_limit.decay_minutes``1``BOUNDLY_RATE_LIMIT_DECAY_MINUTES`Time window in minutes`paths.domain``Domain/`—Where BOUNDLY scans for `#[Entity]``paths.application``Application/`—Where BOUNDLY scans for `#[Action]`---

🛠️ Requirements
---------------

[](#️-requirements)

- PHP **8.2+**
- Laravel **13+** (core dependency, hidden in `Infrastructure/LaravelEngine`)
- MySQL / PostgreSQL / SQLite

---

🤝 Contributing
--------------

[](#-contributing)

BOUNDLY is an open source project and **contributions are welcome!**

Please read [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on:

- How to report bugs
- How to propose new features
- The Pull Request process
- Code style guidelines

---

📋 Versioning
------------

[](#-versioning)

BOUNDLY follows [Semantic Versioning (SemVer)](https://semver.org/):

- `MAJOR` → Breaking changes in the API or architecture
- `MINOR` → New backward-compatible features
- `PATCH` → Bug fixes

See the full history in [`CHANGELOG.md`](CHANGELOG.md).

---

📜 License
---------

[](#-license)

BOUNDLY is open-sourced software licensed under the [MIT License](LICENSE).

---

☕ Support the Project
---------------------

[](#-support-the-project)

If BOUNDLY has been useful to you or you like what we're building, you can support us to keep creating and maintaining open source software:

 [ ![Buy us a coffee](https://camo.githubusercontent.com/453c655ef274c7b8e0a588d3625323361bc55b359f917f6c4d18cd850dd1fc70/68747470733a2f2f63646e2e6275796d6561636f666665652e636f6d2f627574746f6e732f76322f64656661756c742d76696f6c65742e706e67) ](https://www.buymeacoffee.com/epolabs)

A coffee = more time for open source code ❤️

---

⭐ **If you like BOUNDLY, give it a star on GitHub!** ⭐

[GitHub](https://github.com/EpOpenLabs/BOUNDLY) · [Issues](https://github.com/EpOpenLabs/BOUNDLY/issues) · [Discussions](https://github.com/EpOpenLabs/BOUNDLY/discussions)

**Made with ❤️ by [EpOpenLabs](https://github.com/EpOpenLabs)**

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

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

Total

10

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/44333e7743c533d8fbceefc68fea80f45138cff6130c43a3d3705fd476448ecf?d=identicon)[lpachecoby](/maintainers/lpachecoby)

---

Top Contributors

[![lpachecob](https://avatars.githubusercontent.com/u/22027166?v=4)](https://github.com/lpachecob "lpachecob (40 commits)")

---

Tags

apiattributesboilerplateboundlyconvention-over-configurationddddomain-driven-designenterpriseframeworklaravellaravel-frameworkmetadatametadata-architecturemetadata-drivenphpphp-frameworkproduction-readyrestrest-apirestfulapiframeworklaravelrestattributesboilerplatedddphp8metadata-driven

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/epolabs-boundly/health.svg)

```
[![Health](https://phpackages.com/badges/epolabs-boundly/health.svg)](https://phpackages.com/packages/epolabs-boundly)
```

PHPackages © 2026

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