Skip to content

Releases: velkymx/vibefw

VibeFW v2.1 Release Notes

Choose a tag to compare

@velkymx velkymx released this 10 Mar 01:51
2946dfe

v2.1 is the largest single release in VibeFW's history. Building on the concurrency architecture introduced in v2.0, it ships the full SPA scaffolding stack, an extensive security hardening pass, a turnkey project setup experience, and 13 patch versions worth of correctness and reliability fixes.

What Changed in v2.1

For new projectscomposer create-project velkymx/vibefw my-app now gets you a fully working app in one command. No manual .env setup, no key generation, no empty database.

For SPA projectsphp fw make:spa scaffolds a complete Vue 3 + TypeScript + Vite frontend with authentication, routing, and VibeUI components in a single interactive command. php fw dev then starts both servers concurrently.

For all projects — 30+ security fixes land automatically on composer update. Nothing breaks; everything gets safer. Highlights include a complete Sanitizer rewrite, Fiber instance leak elimination, timing-attack hardening in auth flows, and storage permission tightening across the board.

New in the boxFw\Support\Hash for future-proof password hashing, Fw\Auth\EmailVerification for confirmation flows, five new CLI commands, and configurable CORS origins.

Upgrading from v2.0? v2.1 is fully backwards compatible — run composer update velkymx/vibefw and you're done. See the Upgrading from v2.0 section at the bottom of this document for recommended (optional) adoptions.

What's New

SPA Scaffolding — php fw make:spa

Run one command to scaffold a complete, production-ready Vue 3 + TypeScript + Vite frontend wired to a PHP API backend.

php fw make:spa

What you get:

  • Vue 3 + TypeScript frontend in /frontend/ using VibeUI 0.7+ components
  • 4-page starter — Home, Login, Register, Dashboard — with dark mode support throughout
  • Full auth flow — Bearer token login/register/logout, Axios 401 interceptor for server-side revocation
  • Vue Router 5 with authenticated route guards
  • Pinia state management
  • Vite 7 dev server with API proxy to localhost:8000
  • PHP API controllersApi/Auth/LoginController, Api/Auth/RegisterController, Api/StatsController
  • Database migrations installed and run (users, jobs, remember token, password resets, personal access tokens, email verifications)
  • CORS pre-configured for the Vite dev server
  • TypeScript API types — typed interfaces for all API responses
  • Vitest + Playwright test scaffolding
  • Frontend README with auth flow, API reference, and VibeUI cheat sheet

After scaffolding, start the full stack with:

php fw dev

php fw dev — Concurrent Dev Server

New command that runs the PHP backend and Vite frontend concurrently via pcntl_fork, so you get a single terminal for the full stack.

Backend:  http://localhost:8000
Frontend: http://localhost:5173

Falls back gracefully if pcntl is unavailable, printing the commands to run separately.

Turnkey Project Setup

composer create-project velkymx/vibefw my-app
cd my-app

That's it. The post-install hook automatically:

  • Creates .env with a secure APP_KEY
  • Sets up storage/ directories
  • Creates the SQLite database file

No manual cp .env.example .env or key generation required. Also available for cloned repos:

php fw setup

New CLI Commands

Command Description
php fw make:spa Scaffold Vue 3 + TypeScript SPA starter
php fw dev Start backend + frontend dev servers concurrently
php fw setup First-time project initialization
php fw env:sync Sync .env keys to frontend/.env.local with VITE_ prefix
php fw security:check Focused security audit (permissions, debug flags, exposed files, hardcoded credentials)

Fw\Support\Hash

New utility class for password hashing:

use Fw\Support\Hash;

$hash  = Hash::make($password);                    // PASSWORD_DEFAULT algorithm
$valid = Hash::check($password, $hash);            // true/false
$stale = Hash::needsRehash($hash);                 // true if algorithm or cost changed
$hash  = Hash::make($password, ['cost' => 12]);    // custom cost

Uses PASSWORD_DEFAULT so the algorithm automatically upgrades as PHP evolves.

Fw\Auth\EmailVerification

Foundation class for email confirmation flows. Supports token generation, single-use verification with timing-attack protection, and automatic expiry cleanup. Opt-in — no routes or sending logic included.

Queue Security: allowClasses()

FileDriver and DatabaseDriver now expose an explicit deserialization allowlist on top of the default HMAC verification:

$queue->driver()->allowClasses([
    SendWelcomeEmail::class,
    ProcessPayment::class,
]);

CORS Configuration

CorsMiddleware now reads from $app->config('cors') for per-project overrides:

// config/app.php
'cors' => [
    'allowed_origins'      => array_filter(array_map('trim', explode(',', env('CORS_ALLOWED_ORIGINS', '*')))),
    'supports_credentials' => true,
],

make:spa automatically writes CORS_ALLOWED_ORIGINS to .env to allow the Vite dev server.

Security Hardening

v2.1 includes 30+ targeted security fixes. Highlights by area:

Authentication & Sessions

  • Remember token replay — Token rotated on every use; old token invalidated immediately
  • Remember cookie Secure flag — Set to true on HTTPS automatically, respects trusted proxy headers
  • Auth logout() orderclearRememberToken() now runs before context teardown
  • Logout Bearer token revocation — Token cannot be replayed after logout
  • UUID session user IDsAuth::user() and Auth::id() now accept both integer and string (UUID) primary keys
  • RegisterController TOCTOU race — Duplicate email race caught at the DB unique constraint level

SQL & QueryBuilder

  • SQL injection via alias expressionsvalidateIdentifier() tightened to reject arbitrary SQL in AS aliases
  • SQL injection via aggregate functionsCOUNT(*) OR 1=1; -- patterns now rejected
  • Foreign key action injectiononDelete()/onUpdate() validate against a whitelist
  • BelongsToMany unquoted identifiers — All identifiers in eagerLoad(), detach(), pluck() now quoted
  • DatabaseDriver table name injection — Constructor validates table names at construction time
  • Migrator path traversal — Migration files validated with realpath() to stay within migrations directory

Cryptography & Tokens

  • Str::ulid() entropy — Fixed from 50-bit to correct 80-bit per the ULID spec
  • EmailVerification single-use tokens — Verification links now consumed on first use
  • PersonalAccessToken token hash isolation — Rotating the configured prefix no longer invalidates existing tokens
  • Auth::getUserFromRememberToken() integer overflow(int) cast replaced with ctype_digit() + constant-time dummy comparison

Input Validation & Sanitization

  • Sanitizer rewritejson(), float(), url() hardened; stripTags() no longer accepts an allowlist (was insecure)
  • Validator ReDoSvalidateAlpha() / validateAlphaNum() reject inputs over 65KB before reaching the Unicode regex
  • Router::validateConstraint() ReDoS — Replaced blacklist approach with a whitelist that rejects all parenthesized groups
  • QueryWatcher ReDoSnormalizeQueryPattern() capped at 8KB input

Async & HTTP

  • SSRF in AsyncHttpvalidateHost() rejects private IPs, loopback, and cloud metadata addresses
  • AsyncHttp header injection — Headers validated against \r\n before sending
  • SpaAuthMiddleware origin bypass — Missing origin headers now rejected in production; dev mode restricted to localhost
  • View::resolvePath() path traversal — View names validated with realpath()

Infrastructure

  • Storage permissions — All cache, log, queue, and config cache directories changed from 07550750; log files set to 0640
  • ErrorHandler path leakage — Debug pages strip BASE_PATH from file paths
  • StreamedResponse security headersX-Content-Type-Options, X-Frame-Options, Referrer-Policy now included
  • CSP unsafe-inline removed — No longer included in script-src or style-src
  • CSRF silent failureensureSession() throws RuntimeException on premature output instead of silently disabling CSRF protection

Reliability & Correctness

Fiber / Worker Mode

  • Container Fiber instance leakspl_object_id() keying replaced with WeakMap<Fiber, array> for automatic GC
  • Model strict mode leak$globalStrictMode reset between requests
  • PasswordReset / Gate / ApiToken static leaks — All wired into HttpKernel::resetState()
  • View output buffer leak — Exception inside a fragment cache block no longer leaves buffers open across requests
  • Deferred fiber resurrection crashresolve()/reject() check isTerminated() before resuming a Fiber

Async

  • Deferred::race() never settles — Replaced polling with onSettle() listener that fires immediately on resolution
  • Deferred::race() memory leak — Losing deferreds release references after the race settles

Cache

  • Null TTL semanticsset($k, $v, null) now stores indefinitely per PSR-16 in both FileCache and OpcacheCache
  • FileCache::gc() orphaned lock files.lock sidecars cleaned up alongside expired entries
  • OpcacheCache::increment() race — Atomic via sidecar lock file
  • ViewCache temp file racetempnam() replaces uniqid() for OS-guaranteed uniqueness

Model & Database

...

Read more

VibeFw Framework v2.0.0

Choose a tag to compare

@velkymx velkymx released this 06 Mar 01:35
742fb6f

This is a major release that transforms the framework from a traditional request-response library into a production-grade, fiber-safe foundation for high-concurrency PHP 8.4+ applications.

Benchmark Results

Running on FrankenPHP (Worker Mode) with 4 workers on Apple M2 (MacBook Air), the refactored framework achieves massive throughput improvements. After applying Container Fast-Paths and Route Pre-loading, we observed a >150% increase in performance over early v2 dev builds.

Command: wrk -t8 -c200 -d30s http://localhost:8081/health

Metric Result
Requests per Second 40,058.37
Average Latency 5.15ms
Total Requests (30s) 1,202,023
Memory Stability Stable (Zero leaks after 1.2M+ requests)

🛠 Upgrading from v1.0.5

VibeFW v2.0.0 introduces breaking changes to core execution patterns. Follow this guide to migrate your application.

1. Update Kernel Execution

The HttpKernel::handle() method no longer emits the response. You must now capture the returned object and emit it using the new SapiEmitter.

Old (v1.0.5):

$app->run(); // Implicitly called $kernel->handle($req, $res) which echoed output

New (v2.0.0):

$response = $app->getKernel()->handle($request);
(new SapiEmitter())->emit($response);

2. Mandatory QueryBuilder Re-assignment

The QueryBuilder is now immutable. Method chaining remains supported, but you must assign the result back to a variable if branching your queries.

Old (v1.0.5):

$query = $db->table('users');
$query->where('active', 1); // Modified $query in place

New (v2.0.0):

$query = $db->table('users')->where('active', 1); // Returns new instance

3. Request Property Access

Direct modification of Request properties is no longer allowed as they are now readonly. If you were manually overriding $_GET values on the Request object, you must now inject those values during construction or via the Middleware pipeline.

4. Resettable Interface

If you have custom services that store data in-memory (static arrays or class properties), they should now implement Fw\Support\ResettableInterface and be registered in the Container. This ensures they are automatically cleared between requests in worker mode.


Summary of Changes

Performance & Async Improvements

  • True Non-Blocking I/O: Refactored AsyncHttp to use non-blocking socket streams and the EventLoop watcher system.
  • Event Loop Optimization: Removed "busy-wait" loops in the Kernel. The framework now yields control back to the loop while waiting for Fiber completion.
  • Boot Optimization: Routes and global middleware are now pre-loaded once at boot time in worker mode.
  • Container Fast-Path: Added a high-speed resolution path for global singletons.

State Integrity & Safety

  • Fiber-Scoped Singletons: The Container now isolates request-scoped services per Fiber.
  • Fiber-Safe Context: RequestContext now uses a WeakMap keyed by the current Fiber to prevent data leakage between concurrent requests.
  • Leak Detection: Added a "State Integrity Check" in HttpKernel that throws a RuntimeException if request state from a previous execution is detected.
  • Memory Management: Services like MemoryCache and QueryWatcher are now automatically reset after every request.

Release 1.0.5

Choose a tag to compare

@velkymx velkymx released this 27 Feb 19:40
a5e51e4

Nothing new. Just a release with new packagist config and install instructions

Fw Framework v1.0.4

Choose a tag to compare

@velkymx velkymx released this 24 Feb 04:00
641c294
  • Fixed array response handling: The framework now correctly handles array responses from controllers by converting them to JSON responses with proper headers. Previously, calling setHeader() on the Response object would fail because the method doesn't exist.
  • Fixed json_encode() on Model instances producing wrong output: Model now implements \JsonSerializable, delegating to toArray(). Previously, passing a model directly to json_encode() would silently serialize internal object state instead of the model's attributes, with no warning. Collection was already correctly implemented.

Changed Methods

  • RequestFiber.php:233: Changed $this->app->response->setHeader('Content-Type', 'application/json') to $this->app->response->header('Content-Type', 'application/json')
  • Component.php:315: Changed $this->app->response->setHeader('Content-Type', 'application/json') to $this->app->response->header('Content-Type', 'application/json')
  • Component.php:326: Changed $this->app->response->setHeader('Location', $url) to $this->app->response->header('Location', $url')
  • src/Model/Model.php: Added implements \JsonSerializable to the class declaration and added jsonSerialize(): array method that delegates to toArray()

Impact

  • Controllers returning arrays will now work correctly
  • JSON responses will have proper Content-Type headers
  • Redirect functionality in components will work properly
  • No breaking changes - maintains backward compatibility

Migration

No migration steps required. This is a bug fix that improves existing functionality.

Notes

This release fixes a critical bug that prevented array responses from working correctly in API controllers. The framework now properly handles array responses by converting them to JSON with appropriate headers.

Fw Framework v1.0.3

Choose a tag to compare

@velkymx velkymx released this 20 Feb 01:04
0248d72

This release fixes a critical bug that prevented array responses from working correctly in API controllers. The framework now properly handles array responses by converting them to JSON with appropriate headers.

Bug Fixes

Core Framework

  • Fixed array response handling: The framework now correctly handles array responses from controllers by converting them to JSON responses with proper headers. Previously, calling setHeader() on the Response object would fail because the method doesn't exist.

Changed Methods

  • RequestFiber.php:233: Changed $this->app->response->setHeader('Content-Type', 'application/json') to $this->app->response->header('Content-Type', 'application/json')
  • Component.php:315: Changed $this->app->response->setHeader('Content-Type', 'application/json') to $this->app->response->header('Content-Type', 'application/json')
  • Component.php:326: Changed $this->app->response->setHeader('Location', $url) to $this->app->response->header('Location', $url')

Impact

  • Controllers returning arrays will now work correctly
  • JSON responses will have proper Content-Type headers
  • Redirect functionality in components will work properly
  • No breaking changes - maintains backward compatibility

Fw Framework v1.0.2

Choose a tag to compare

@velkymx velkymx released this 13 Feb 05:04
067dc3c

This is a maintenance release focused on resolving a significant encapsulation bug within the ORM relationship logic that affected many-to-many queries.

Bug Fixes

**Fixed: Protected Property Access in BelongsToMany**

We identified an issue where the BelongsToMany relationship class was unable to retrieve the primary key of related models because it was attempting to access a protected static property from outside the class hierarchy.

  • Impact: This bug previously caused errors when calling $model->relationship()->get() or during eager loading if the primary key was not explicitly provided.
  • Resolution: Introduced a public accessor Model::getKeyName() to safely expose the primary key name to relationship handlers and other internal components.

Internal Changes

  • Enhanced Encapsulation: Added public static function getKeyName() to the base Model class.
  • Relationship Cleanup: Standardized BelongsToMany.php to use the new accessor, ensuring it no longer relies on direct property access which can be restricted by PHP's visibility rules.
  • Eager Loading Stability: Fixed an edge case where eager loading would fail to pluck the correct parent keys due to the visibility issue mentioned above.

Migration & Workarounds

If you were previously using a manual workaround like the one below:

// Old Workaround
$categoryIds = $post->categories()->pluck('category_id');
$categories = Category::whereIn('id', $categoryIds)->get();

You can now simplify your code back to the standard, expressive syntax:

// New & Fixed
$categories = $post->categories()->get();

Release 1.0.1

Choose a tag to compare

@velkymx velkymx released this 11 Feb 04:35
62808c6

This is a mainenance release only

  • Add support for static files with CLI server
  • Add helpers documentation

Fw Framework v1.0.0

Choose a tag to compare

@velkymx velkymx released this 04 Feb 04:53

🐺 Fw Framework v1.0.0 - "Alpha Super Awesome Cool Dynamite Wolf"

The first official release of Fw - a blazing fast PHP framework built for speed, simplicity, and vibes.

🚀 Performance

  • 13,593 requests/second on Mac M2 with FrankenPHP
  • 17x faster than Laravel
  • 9x faster than Symfony
  • 14.8ms average latency under load

✨ Key Features

Speed First

  • Fiber-based async I/O with PHP 8.4
  • FrankenPHP worker mode support for 5-10x throughput
  • Lazy session loading - no overhead on stateless requests
  • Zero runtime dependencies

Modern PHP

  • PHP 8.4+ with property hooks and asymmetric visibility
  • Result<T,E> and Option monads for explicit error handling
  • 100% type coverage
  • Built-in security headers and CSRF protection

Developer Experience

  • Elegant ORM with relationships, eager loading, and migrations
  • Fluent query builder
  • Built-in auth (session + API tokens)
  • Powerful CLI generators (php fw make:model, php fw make:controller)
  • Quill.js rich text editor integration

Vibe Coding Ready

  • Clean, expressive syntax
  • Sensible defaults everywhere
  • Minimal boilerplate
  • AI-friendly codebase structure

📦 Quick Start

git clone https://github.com/velkymx/fw myapp
cd myapp
composer install
php fw serve

🔗 Links

📄 License

MIT License © 2026 Alan Bollinger


Built for developers who want to ship fast and enjoy the process. 🐺⚡