Download the PHP package ochorocho/frankenphp without Composer

On this page you can find all versions of the php package ochorocho/frankenphp. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package frankenphp

TYPO3 FrankenPHP integration

Provides one CLI command that generates everything needed to run TYPO3 under FrankenPHP:

--profile dev|prod drives the defaults for ports, TYPO3_CONTEXT, worker count, and max_requests. --prometheus adds the metrics directive and an admin localhost:METRICS_PORT block to the Caddyfile and powers the live dashboard widget described below.

Composer also runs the command automatically on package install / update / dump-autoload via the TYPO3 installer-scripts mechanism, so users who don't touch the CLI still get a working setup. Without --force, the command preserves files that already exist (warns instead of overwriting), so a composer update won't clobber a hand-edited Caddyfile, .env, php.ini, or public/worker.php.

The files:

The install-tool recovery URL needs Bootstrap::init with $failsafe=true so the container exposes InstallApplication — mutually exclusive with the worker's always-on HttpApplication boot. Rather than shipping a duplicate entry-point, the Caddyfile routes those requests to TYPO3's existing canonical public/index.php, which already implements that branch. index.php is not registered as a FrankenPHP worker, so requests reach it as standard per-request PHP execution.

For users — install into an existing TYPO3

Then run FrankenPHP from the project root using the created config files (Caddyfile, .env). The flag is --envfile: Caddy silently ignores an unknown -e, and without the env file only the Caddyfile's built-in defaults apply (PHP still sees .env when helhum/dotenv-connector is installed, which hides the mistake):

The generated profile follows TYPO3_CONTEXT: with TYPO3_CONTEXT=Production set during composer install, the Composer auto-run writes the production profile (ports 80/443, errors logged not displayed, Caddy admin API off). Any other context yields the development profile. Pass --profile to override, and note that --force backs up an existing .env to .env.bak-<timestamp> before overwriting it.

Diagnostics

The TYPO3 backend's System Information dropdown (the info icon in the topbar) shows a Worker Mode row — Enabled when the current request is being served by the long-running FrankenPHP worker, Disabled when served by per-request PHP execution (e.g. the install-tool recovery URL via /index.php). The row icon is the FrankenPHP mascot ( the skeleton elephant from frankenphp.dev). Use it to quickly verify that requests you expect to hit the worker actually do.

Which services survive a request?

In a TYPO3 project this is the project's vendor/bin/typo3. In this repository it also works from the root: typo3/cms-composer-installers is allowed in the root composer.json, so composer install generates the package artifact from the installed typo3/cms-* packages and the CLI boots without a settings.php (the extension's own installer script skips frankenphp:init when the root package is not a typo3-cms-project). The root run classifies Core plus the dev-dependency extensions; the Build/ sandbox (scripts/typo3 frankenphp:audit) additionally covers whatever else is installed there. The classification is computed when the DI container is compiled, so flush caches (vendor/bin/typo3 cache:flush) after changing KeepList, service tags or a FrankenPhpWorker.php.

Worker mode is discard-by-default: every DI service instance that is not provably stateless (or explicitly pinned) is dropped at the start of each request and rebuilt lazily by the compiled container. The audit prints the classification with reasons so you can see why a service is kept or discarded and tune it: extension authors use the frankenphp.keep / frankenphp.discard service tags or a declarative Configuration/FrankenPhpWorker.php (pin / keep / discard / discardPatterns, also for services of other packages), integrators get the final say in config/system/frankenphp-worker.php. An explicit discard always wins over a keep, and the audit shows the origin of every override as config:<extension key>. In Development context every response carries tuning headers: X-FrankenPHP-Discarded (instances the previous request left behind; should stabilise after warm-up, growth means a leak), X-FrankenPHP-Reset-Us (microseconds of reset inside this request), X-FrankenPHP-Post-Reset-Us (microseconds of the structural reset that ran after the previous response) and X-FrankenPHP-Reset-Mode (post, or inline when the worker fell back to resetting in front of the request). Details, including measured costs: Documentation/WorkerMode.md.

What a request costs

Measured on the sandbox (SQLite, 10 cores): a cached frontend page takes 7 to 9 ms end to end with one client, 4.3 ms of it inside PHP. The extension's own per-request work is 0.2 ms for the reset plus about 0.5 ms to rebuild discarded services. The machine serves 750 to 850 such pages per second before it is CPU-bound, so in a closed-loop load test the average is concurrency divided by that throughput: about 10 ms at 8 concurrent clients, 25 ms at 20. Kept database connections, file-based caches in the sandbox and one worker thread per core are what brought it there. Measured at a fixed rate instead of a closed loop (Tests/load/scenarios/frontend-latency.js, 300 requests per second) a cached page averages 4.6 ms. The breakdown, both test matrices and the deployment checklist (real database server, Redis or APCu, cores) are in Documentation/Performance.md.

Adapting an extension for worker mode

Under PHP-FPM every request starts from a fresh process. In a worker, DI service instances live until something drops them, and this extension drops every instance it cannot prove stateless at the start of each request. Most extensions therefore work unchanged. What is left for an author is to check the verdict, write services so they are kept, and override the analysis where it is wrong.

1. Read the audit for your namespace

Reason Meaning for you
keep / readonly, keep / readonly-props Kept across requests. Nothing to do.
discard / mutable Rebuilt per request. Correct by default; only worth changing for expensive boot-populated registries.
discard / demoted-via:<service> Would be kept, but holds a discarded service, a non-shared service or RequestId. Fix the dependency, not the holder.
discard / pattern *Controller, *ToolbarItem: always per request.
discard / pin-conflict:<chain> A pin whose closure reaches a per-request service. The chain in the reason shows where.

2. Write services so they are kept automatically

3. Override the analysis where it is wrong

Three hooks, all inert when this extension is not installed. All are read when the DI container is compiled, so run cache:flush after editing.

You want to Use
Keep or discard one of your own services frankenphp.keep (mode: soft or pinned) / frankenphp.discard tag in Services.yaml, or #[AutoconfigureTag] on the class
Address services of other packages, use patterns, or ship one file per package Configuration/FrankenPhpWorker.php (below)
Give the project the final say over every extension config/system/frankenphp-worker.php, same format
Clear the state of a pinned service each request Listener on WorkerRequestStartingEvent

Precedence is one rule: an explicit discard from any source (curated list, tag, pattern, file) wins over a keep or pin from any other source. The only exception is the curated boot-populated infrastructure (TcaSchemaFactory, IconRegistry, cache.runtime, …) and its dependencies: a file cannot discard those, the audit shows the ignored request as pinned:ignored-discard:…. keep is soft and can still be demoted by its dependencies; a pin whose closure reaches a per-request service is reported as a pin conflict and not kept. Keeping a Core service you do not own can leak one user's state to the next: verify with two backend users, discard is always the safe direction. The audit shows the origin of every override as config:<extension key>, pinned:config:<extension key> or pattern:config:<extension key>, and warns about entries that matched no service. A class name also reaches a service registered under a custom id. Unknown keys, non-string entries or invalid patterns fail the container build with the file name in the message.

4. Verify

Prometheus metrics dashboard widget

Run vendor/bin/typo3 frankenphp:init --prometheus (add --force to overwrite an existing Caddyfile / .env). This adds:

A dashboard widget titled Prometheus Metrics then appears in the FrankenPHP widget group. It charts the metric you pick — FrankenPHP worker-pool gauges, Caddy HTTP counters/histograms, or Go runtime stats — by polling the backend AJAX route ajax_frankenphp_metrics (Configuration/Backend/AjaxRoutes.php), which proxies http://127.0.0.1:METRICS_PORT/metrics. The proxy exists because Caddy's admin endpoint rejects any browser request that ships an Origin header; only server-side scrapers (this proxy, Prometheus, curl) can reach it directly.

The curated metric list lives in PrometheusMetricsWidget::METRIC_CHOICES. Enumerate what your build actually exposes with:

Install Tool access

Two URLs reach the TYPO3 Install Tool, each routed differently:

If you ever change the Caddyfile manually and forget to keep the @typo3_install matcher, the recovery URL will 404 — vendor/bin/typo3 frankenphp:init --force --no-interaction regenerates a working config.

Action URLs are AJAX-only

URLs that carry both install[controller]=… and install[action]=… (anything other than install[controller]=layout) are designed for the install tool's own JS to call via XMLHttpRequest. They return a JSON envelope {success: true, html: '…', buttons: [...]} for the JS to inject into a modal. Pasting such a URL into a browser address bar shows the raw JSON, not a usable page.

To avoid that confusion, the Caddyfile's @install_browser_ajax matcher detects browser top-level navigation ( Sec-Fetch-Mode: navigate + Sec-Fetch-Dest: document, without X-Requested-With: XMLHttpRequest) to ?__typo3_install&install[action]=… URLs and redirects (302) to the install tool dashboard at /?__typo3_install. From there, click into the relevant tile (Maintenance, Settings, Upgrade, Environment). The redirect is a Caddyfile-level concern; no extra PHP entry-point is involved.

For long-running maintenance like the reference index, the CLI alternative is usually preferable — the install tool's own UI literally points at this:

Repository layout

This repository is the extension package, not a TYPO3 installation. A throwaway TYPO3 sandbox is materialized in Build/ (gitignored) so the extension can be exercised end-to-end.

Folder Purpose
Classes/ Extension PHP source — Command/ (frankenphp:init), Controller/Backend/ (metrics AJAX proxy), Service/ (PrometheusTextParser), Widget/ (PrometheusMetricsWidget), Worker/ (WorkerStateResetter + KeepList — per-request reset of the worker process), DependencyInjection/ (WorkerKeepListPass — compile-time keep/discard classification), EventListener/, Middleware/, Event/, Composer/ (TYPO3 installer-scripts hook).
Configuration/ TYPO3 service wiring (Services.yaml, Services.php), Backend/AjaxRoutes.php, Backend/DashboardWidgetGroups.php, Backend/DashboardPresets.php, JavaScriptModules.php, Icons.php, RequestMiddlewares.php.
Resources/Private/ Fluid templates (Templates/Widget/), Language/ XLF files, and Php/worker.php — the template InitCommand copies into the user's public/.
Resources/Public/ Frontend assets — JavaScript/widget/ (Chart.js-backed Lit web component for the metrics widget), Css/widget/, Icons/.
Tests/ Unit/ PHPUnit tests for the compiler pass, e2e/ Playwright suite (correctness) and load/ k6 scenarios (performance + worker stability). Each has its own README.
Documentation/ WorkerMode.md — the service lifecycle model and the audited list of Core services for worker mode.
scripts/ Developer bootstrap — setup-typo3.sh materializes the Build/ sandbox; typo3 runs the sandbox CLI from the repo root.
Build/ Gitignored. Throwaway TYPO3 install for development. Build/composer.json requires this extension via a Composer path repository pointing at ../, so edits to root Classes/ / Resources/ / Configuration/ affect the sandbox immediately.

Contributing

Prerequisites

PHP extensions (Ubuntu / Debian)

TYPO3 needs intl: without it the Filelist/Media module fails with Class "Collator" not found (FileList::sortResources() builds a \Collator for every folder listing).

FrankenPHP embeds thread-safe (ZTS) PHP, so Ubuntu's own php8.x-* packages don't apply — they're non-thread-safe and their .so files won't load. Two ways to get the extensions:

mbstring, dom, xml, simplexml, libxml, sodium, exif, fileinfo, opcache, openssl, ctype, filter, iconv, session, tokenizer, zlib, curl and phar are already in php-zts-cli (it Provides: them), and json / pcre / date are PHP core — none of them has a separate package. intl is the notable exception, which is why it's the one that goes missing. For anything unpackaged use PIE, not pecl: sudo apt install pie-zts && sudo pie-zts install <vendor/ext>.

Verify what the binary actually has:

frankenphp php-cli -m does not work — it treats -m as a filename. Use -r as above.

The container equivalent is docker/Dockerfile (install-php-extensions exif gd imagick intl mysqli opcache zip). When adding APCu by hand, write the absolute path to apcu.so in php.ini: FrankenPHP resolves a bare extension=apcu against its compiled-in extension_dir, not the one the global php.ini declares (see scripts/setup-typo3.sh and Documentation/Performance.md).

Bootstrap the dev sandbox

The script is idempotent. On a re-run with the same TYPO3_VERSION it skips work that's already done; with a different version it resets Build/vendor/, composer.lock, config/system/, and var/cache before re-installing — so switching TYPO3 majors is one command. It writes a Build/composer.json that requires the extension as a symlinked path repository ("url": "../"), so editing root files affects the sandbox immediately with no extra step.

The sandbox and the Docker setup use fixed, well-known credentials (backend admin, e2e editor, MariaDB root) and run with display_errors on. Keep them on localhost; never expose the sandbox ports to a network.

Admin login (created by typo3 setup): admin / Password.1. Override via:

Run the dev server

To regenerate Caddyfile / .env / php.ini / public/worker.php after switching profiles or toggling --prometheus:

Run with Docker (no native FrankenPHP / Composer / PHP needed)

If you'd rather not install PHP, Composer, sqlite3, and the frankenphp binary on your host, a Docker Compose setup is provided that runs everything in containers, backed by MariaDB instead of SQLite.

The first boot is slow — it fetches the images, provisions the FrankenPHP image, downloads all of TYPO3, and runs typo3 setup.

Subsequent docker compose up runs skip every already-completed step and start immediately.

Once the frankenphp-app became healthy, open the app in your browser:

Amend the configuration to your needs:

Concern Where to change it
Ports HTTP_PORT / HTTPS_PORT in docker-compose.yml (or a Compose-level .env). Defaults: 8888 / 8885.
TYPO3 version TYPO3_VERSION in docker-compose.yml (any Composer constraint, e.g. 15.*@dev).
Worker pool FRANKENPHP_WORKER_COUNT / MAX_REQUESTS in docker-compose.yml.
DB / admin creds TYPO3_DB_* / TYPO3_SETUP_* in docker-compose.yml.
Added PHP extensions docker/Dockerfile.

To rebuild from scratch (e.g. after changing TYPO3_VERSION), wipe the named volumes first:

Static analysis & code style

Dev dependencies are in the root composer.json; run the tools from the repository root:

Tests

Suite Location What it covers
Unit (PHPUnit) Tests/Unit/ WorkerKeepListPass classification and dependency-closure rules against a small fixture container.
End-to-end (Playwright) Tests/e2e/ Backend correctness against the running sandbox, including cross-user isolation on a shared worker. See Tests/README.md.
Load / soak (k6) Tests/load/ Throughput, tail latency, and (most importantly) the regression net for Classes/Worker/WorkerStateResetter.php. See Tests/load/README.md.

Submitting changes

Standard GitHub PR workflow against main. Please make sure phpstan and php-cs-fixer are clean and include a Playwright or k6 test when the change is behavior-visible.


All versions of frankenphp with dependencies

PHP Build Version
Package Version
Requires typo3/cms-core Version ^14.3 || 15.*@dev
helhum/dotenv-connector Version ^3.2
cweagans/composer-patches Version ^1.7
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ochorocho/frankenphp contains the following files

Loading the files please wait ...