Changelog

v1.4.0

August 21, 2026
  • Large Git pushes and other streaming uploads now work through a route-scoped BodyPolicy, with strict chunked decoding, configurable size limits, and secure disk spooling that keeps worker memory flat.
  • Active sessions now renew before they expire, for both cookie and store drivers. Set renewAfter to choose the refresh point, or use 0 when you need a fixed absolute lifetime.
  • Graceful restarts no longer resume fibers inside a signal handler, and requests that are still uploading finish inside the normal drain window instead of being cut off.
  • CSRF protection can skip a narrowly matched route with csrfExcept, and defer_stream() gives custom streaming responses the same safe request context used by SSE and WebSockets.
  • Rate-limit windows can no longer strand ordinary clients in a permanent 429 lockout. New counters receive an expiry, and an interrupted legacy counter repairs itself when it next refuses a request.
  • Malformed route parameters such as {repo}.git now fail clearly during registration instead of silently becoming dead literal routes. Rewrite them as whole-segment parameters before upgrading.

v1.3.0

July 19, 2026
  • Serve HTTPS directly: pass serve() a TlsConfig and Fast terminates TLS on every runtime, no reverse proxy required. Point it at a certificate and key with TlsConfig::certificate(), add per-host certificates for SNI, and choose a TLS 1.2 or 1.3 floor with a modern cipher suite. TLS is opt-in and only asks for ext-openssl, which ships with most PHP builds including native Windows.
  • Automatic Let's Encrypt on POSIX: TlsConfig::letsEncrypt() obtains and renews a certificate for you over ACME, a pure-PHP client with no third-party libraries. The owner process answers the HTTP-01 challenge on :80, writes the chain to storage, then renews ahead of expiry and rolls the workers so the new certificate goes live without downtime.
  • Force HTTPS with redirect_https(): drop it in as middleware to 308-redirect plaintext requests to their secure origin and emit HSTS on secure responses. Every request now reports request()->secure so you always know how it arrived.
  • Send email with mailer() and send_mail(): compose a Message with text, HTML, and file attachments, and Fast delivers it through your SMTP relay over TLS. Configure it from MAIL_* environment values or an explicit MailConfig, and it degrades on its own -- when the relay is unreachable it falls back to the local sendmail binary with no code change, while a relay that answers and rejects is reported rather than silently retried.

v1.2.3

July 19, 2026
  • Schedule recurring background work with schedule(): give it a Job class and a cadence, either a plain interval like every: '15m' or a cron expression like cron: '0 2 * * *', and the broker runs it on time. It fires once no matter how many workers you run, will not pile up if a run is slow, and skips missed occurrences after a restart instead of replaying them in a burst.

v1.2.2

July 18, 2026
  • The multi-process server (the default on Windows) now retires workers gracefully: in-flight and keep-alive responses always finish intact, a replacement worker is pre-spawned before the old one drains so the pool never loses capacity, and accepted connections set TCP_NODELAY. Together these close a multi-second tail latency seen under sustained load. Workers also recycle far less often by default.
  • Fixed a memory-harness self-test that could fail intermittently inside the full suite: it bounded post-reset peak memory with an absolute figure instead of measuring the transient above the live-memory floor.

v1.2.0

July 17, 2026
  • Run the dev server with --watch and it reloads on every save, no manual restart needed.
  • When a handler throws, Fast now catches it instead of dropping the request. Run with --debug for a full developer error page, or register on_error() to shape your own response.
  • A tiny structured logger: call logger()->info() and get one line of JSON per record, with levels and a LOG_LEVEL knob.
  • Handle file uploads with request()->file() and files(), backed by a real multipart parser that stays safe against path-traversal filenames.
  • Call out to other services with http(): a small async HTTP client that follows redirects, decodes JSON, and blocks connections to private addresses unless you opt in.
  • Page through big result sets with paginate(), which counts the matches and hands back a ready-to-render page with all the counters a pager needs.
  • Hand slow work off the request with background jobs: enable use_jobs(), write a class, and dispatch() it. Jobs run on your workers, retry with backoff when they fail, and give up gracefully after too many tries.
  • Style your own 404 page with not_found(), the missing-route sibling to on_error().
  • Validate uploads inline: the new file, ext, and max_kb rules check an uploaded file right alongside your form fields.

v1.1.0

July 17, 2026
  • Attach middleware to a single route or wrap a whole group of routes, all with the same tiny API.
  • Name a middleware stack with middleware_alias() and reuse it anywhere by that name.
  • Routes can be named, and url() builds their paths for you. Group names prefix through the "as" option.
  • Typed route parameters: declare fn(int $id) and get a real int, with an automatic 404 on a mismatch.
  • Templates can inherit from each other. Call render() inside a template to pick up the surrounding context, with layout(), section(), and slot().
  • Stack up content with push()/end_push()/stack(), and slot() now takes a default.
  • config() learned dot-paths for reaching into nested config.
  • New response helpers: back() and download().
  • Testing feels like Pest now, with beforeEach()/afterEach() hooks.
  • A new ready-to-launch starter download: unzip it, run the server, and you have a working app with the framework already bundled in.
  • Docs: Views & Templates is now its own section, split into Views, Layouts & Slots, and Stacks.

v1.0.0

July 15, 2026
  • The first release: a zero-dependency, async framework for PHP 8.2+.
  • Full HTTP stack: routing, middleware, requests, responses, and views.
  • Batteries included: database and ORM, key-value store, sessions, auth, and validation.
  • Real-time built in: live components, WebSockets, and server-sent events.
  • An in-process, deterministic test harness for fast, repeatable tests.