Why I Keep Rewriting My PHP Framework

And why I'll probably never stop

Back to Blog

I've been building PHP frameworks for over a decade. It started on the job, maintaining a bespoke framework that was already 12+ years old at the time. That experience got me curious about how everything worked under the hood. I picked up Laravel, played with Symfony, studied Slim, and eventually thought: why not build my own?

That first attempt was called Aria. Then it became Project Mars, then Celestial, Constellation, Helios, and now Echo. Each version taught me something new, and each one got a little closer to what I actually wanted. I've been obsessed with the process ever since.

Echo is a PHP 8.4+ MVC framework. It runs on PHP-DI for dependency injection, Twig for templating, and Docker for the full stack (PHP-FPM, Nginx, MariaDB, Redis). It powers my personal website at williamhleucka.com.

What makes it fun

Attribute-based routing is probably my favorite feature. When PHP 8 introduced attributes, I immediately wanted to build a routing system around them. No more route files or config arrays. You just decorate your controller methods.

Routes are auto-discovered from controllers and cached for production. Groups handle shared prefixes and middleware. It feels clean and keeps everything close to the code that handles it.

The admin module system is something I'm particularly proud of. It's modeled after the legacy framework I worked with professionally, which had really solid patterns for list/edit views, bulk actions, link filters, searching, and audit logging. Echo's version uses a declarative builder pattern where you define your table and form schemas, and the framework handles the rest: HTMX-powered tables with sorting, filtering, pagination, modal-based CRUD, CSV export, and row-level permissions.

The QueryBuilder grew up a lot recently. Version 0.7.0 added JOINs, WHERE IN, DISTINCT, subqueries, raw expressions, upserts, UNIONs, and aggregate functions. It's fluent, composable, and handles the kind of queries the admin modules need without dropping to raw SQL everywhere.

Other things I like about the stack: an event system inspired by PSR-14, Redis-backed caching and rate limiting, an email queue with a Mailable API, a full CLI with code generators and migration tools, and a profiler for keeping an eye on query performance.

The past year

Echo started in January 2025. 609 commits and 18 releases later, it's at v0.7.1. The early days were the skeleton: routing, middleware, DI container, sessions, basic ORM. By mid-2025 I was deep in the admin system, building out the HTMX integration, table joins, filter dropdowns, and all the little UI details that make a CRUD interface actually usable.

Late 2025 into early 2026 was about hardening. Security audits across middleware and auth. Integration tests. Input validation. The kind of work that's not glamorous but matters. The QueryBuilder rewrite in v0.7.0 was a big milestone, replacing a lot of scattered raw SQL with something composable and safe.

The whole time, the framework has been the foundation for my personal site. That's the real test. Every feature gets used in production, and every rough edge gets felt immediately.

What's next

Honestly, I don't have a grand roadmap for the framework itself. It does what I need it to do, and it keeps getting better as I build on top of it. The next project on the site side is a recipe viewer, which will probably push the framework in new directions I haven't planned for yet. That's kind of the point. Echo evolves because I use it, not because I'm chasing a feature list.

If you're a developer who's ever been curious about what sits beneath the frameworks you use every day, I'd encourage you to try building one. You don't have to ship it. You don't have to compete with Laravel. But the understanding you gain from wiring up a router, a DI container, a middleware stack, and an ORM from scratch is worth the effort. It changed how I think about every framework I touch.

Echo is open source at github.com/whleucka/echo if you want to poke around.

Until next time! ⭐

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

Your email won't be published. Used for Gravatar only.