Forem

Rodrigo Borges
Rodrigo Borges

Posted on

I finally launched my first Open Source project: FacilPHP πŸš€

Hey dev community!

I’ve been writing code for a long time, but I always kept my tools and side projects to myself. Recently, I got tired of that. I wanted to build something small, useful, and put it out there.

Today, I’m finally pushing the "public" button on my first-ever open-source project: FacilPHP.

It’s a micro-framework focused insanely hard on DX (Developer Experience) and speed to market.

The "Why" behind FacilPHP

I love big frameworks, but sometimes I just want to validate a Micro-SaaS idea or build a prototype in a weekend. I didn't want to spend an hour setting up routes, configuring ORMs, or fighting CORS headers just to get "Hello World" from a database endpoint.

I wanted the vibe of file-based routing (like Next.js) but in PHP, combined with a super simple database layer (inspired by better-sqlite3 in JS).

So, I built it. It’s barebones on purpose.

Why you might care

If you like skipping boilerplate and jumping straight into code, this is for you.

Here is how straightforward it is:

πŸ“ 1. File-Based Routing

Want an endpoint at /api/products? Just create a file at routes/api/products.php. Done. No route files to maintain.

<?php
// routes/api/products.php
use Facil\Http\Response;

return [
    'GET' => function() {
        return Response::json(['message' => 'It just works.']);
    }
];
Enter fullscreen mode Exit fullscreen mode

Need dynamic parameters like /users/42? Name your file routes/users/[id].php. The ID comes straight into your closure.

πŸ—„οΈ 2. A true MicroORM (focused on SQLite)

Writing raw SQL is tedious. Setting up a huge ORM with complex models is overkill for prototypes.

FacilPHP has a fluent Query Builder. It's all about method chaining to get stuff done fast, with total security against SQL injection.

// Insert data
$newId = Query::table('users')->insert([
    'name' => 'Digo',
    'email' => 'digo@example.com'
]);

// Fetch with relationships (N+1 solved automatically)
$users = Query::table('users')
    ->where('is_active', 1)
    ->with('posts', 'user_id')
    ->get();
Enter fullscreen mode Exit fullscreen mode

And pagination? One method call.

πŸ›‘οΈ 3. "Batteries Included" (The essentials)

Prototypes still need security. FacilPHP handles:

  • .env Loader: Keep secrets secure.
  • CSRF & Security Headers: Clickjacking and XSS protection by default.
  • Validation: Clean pipe syntax, including CPF/CNPJ (Brazilian standard) out of the box.
  • Auth: Simple session-based authentication ready to go.

Check it out

Since this is my first open-source contribution, I know it’s not perfect. It’s far from it. It needs tests, optimizations, and community feedback.

If you are looking to hack together an idea quickly this weekend, give it a try.

Any feedback, bug reports, or contributions are welcome.

Thanks for reading!


Developed by Rodrigo Borges

Top comments (0)