# Wrench: a plain PHP WebSocket server and client you read in an afternoon

> Wrench is a PSR-4 WebSocket server and client package for PHP 7.1 and later, with a small API built around a BasicServer, registered applications and a DataHandlerInterface callback. It suits a PHP developer who needs a socket endpoint inside an existing application rather than a separate realtime service, and it carries the WTFPL licence.

**varspool/Wrench** — A simple PHP WebSocket implementation for PHP 7.1

- Repository: https://github.com/varspool/Wrench
- Stars: 590 · Forks: 206
- Language: PHP
- License: WTFPL
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/varspool-wrench

## A socket layer for PHP applications, not a realtime framework

Wrench describes itself as a simple websocket server and client package for PHP 7.1, and the repository description calls it a simple PHP WebSocket implementation. The word doing the work is simple, and the API reflects that intent.

The library is PSR-4 compatible with a vendor name of Wrench, and it is published on Composer as wrench/wrench. That autoloading convention matters more than it sounds for a socket library, because a long-running server that receives a message and dispatches it to a handler of your own is exactly the shape of code where a mix of global functions and manual requires becomes painful.

What you get is a server, a client, and a small set of interfaces between them. What you do not get is a framework. There is no room concept, no channel subscription, no presence tracking and no message history. The feature list in the README is absent entirely, which is itself informative: the project is judged by its API surface rather than by a feature inventory.

The comparison the README itself offers is Ratchet, described as an excellent Websocket layer for React. That comparison sets the frame for the whole project. Wrench is not trying to be a Ratchet replacement for real-time applications at scale; it is the lower-level piece you would use when a PHP application needs to accept or originate a WebSocket connection, and the application logic stays yours.

The primary language is PHP, the default branch is master, and the documentation lives at wrench.readthedocs.org.

## BasicServer, registered applications, and a URI that routes

The server example in the README shows the whole architecture in about twenty lines, and the design is worth walking through because it is unusual compared with the routing frameworks most PHP developers use.

The server is constructed with a base URI and an options array, then applications are registered against path names, and each application is an object implementing a handler interface.



Three things stand out.

First, routing is by registered application name, not by path matching with regular expressions. The README describes a server on 127.0.0.1:8000 with one Application listening for WebSocket requests to ws://localhost:8000/echo and ws://localhost:8000/chat, and the registerApplication calls are what bind those names. The application key is the last segment of the request path, and registering an application is what makes that path live.

Second, the handler contract is a single method, onData, that receives the raw string and the Connection object, and returns void. Sending is done on the connection. The echo example returns the data to the connection that sent it, and the chat example is your own class. The interface lives under the Application namespace, separate from the server, which is what lets a handler be a plain object you construct yourself.

Third, allowed_origins is a server-level option with a list of hosts, which is the origin check for browser clients.  This matters because a WebSocket handshake from a browser carries an Origin header, and without a list to check it against, any page could open a connection to your endpoint.

Logging is wired through PSR-3, so setLogger takes a Monolog instance, and the comment in the example says PSR3 explicitly.

## The client side is four calls, and one of them looks wrong

The client example is much shorter than the server one, which is a fair hint at how much of the library is on each side.



The API is connect, sendData, receive and disconnect. The interesting detail is receive, which returns an array, and the example takes index zero and calls getPayload on it to get the string back. So a single receive call can deliver more than one frame, and the caller selects the one it wants.

There is a typo in the README's constructor argument. As printed, the first argument reads 'ws://localhost:8000, http://localhost:8000', with a comma and a second URL inside the same quoted string, and the closing parenthesis is inside the string as well. The intended value is clearly a single ws://localhost:8000 URI, since the following calls connect to that endpoint. Anyone copying the example verbatim will hit a malformed argument, and it is worth knowing that this is a documentation defect rather than a required two-URL syntax.

The absence of any framing or masking notes in the README means the client is a minimal implementation: connect, exchange payloads, disconnect. There is no reconnection logic, no ping or pong exposed at this level, and no callback interface for asynchronous reads, which makes it a synchronous client suited to scripts and to simple request-response patterns rather than to a long-lived bidirectional stream.

## Installing it, running the checks, and the PHP 5 branch

Installation is a single Composer requirement.



```bash
composer require wrench/wrench ~3.0
```

The ~3.0 constraint pins the major version, and the README notes that the library is available on Composer as wrench/wrench. The two badges at the top of the README point at the same package on Packagist for the latest stable and latest unstable versions, so Packagist is where the version history lives.

Older PHP versions are handled with a second branch rather than a polyfill. The README states that the latest major release dropped support for PHP versions prior to 7.1, and that if you need support for older versions of PHP you should see the 2.0 branch, whose latest release is 2.0.8.



That two-line split is a good signal about the project's shape. A library with a maintained 2.0 line for legacy PHP and a 3.0 line for modern PHP has an audience with real production systems on old runtimes, and it also means the constraint you write in composer.json is the thing that decides which API you get.

Development is documented in two commands. Run ./vendor/bin/phpcs and fix any errors that you come across, and run ./vendor/bin/phpunit --exclude-group large,medium for a fast test between changes.

The excluded groups are interesting. A test suite that distinguishes large and medium tests as separate groups implies there is a third tier, presumably slow tests, and the fast subset is what you run on every change. The repository layout backs this up: there are test and doc directories, an examples directory, a phpcs.xml for coding standard enforcement, a phpunit.xml for the test configuration, a CHANGELOG.md for release history,.

The examples directory is more revealing than its name suggests. It contains StatusApplication.php, server.php, server_ssl.php, a coffeescript directory and a run.sh script, so the project ships runnable examples including a TLS server variant, which is the answer to the question of how you would terminate encryption for a Wrench connection.

## The limits, and where another tool fits better

Three boundaries are worth being honest about.

The first is scale and the second is what comes with it, the connection model. Wrench gives you a blocking server loop and a callback per application. There is no room, no broadcast helper and no backpressure handling described anywhere in the README, so a chat application, which the example names, needs its own fan-out logic to reach other connected clients. The repository's own TODO file records what is still outstanding, and the README does not claim these features exist.

The second is the PHP version floor and the surrounding runtime. A PHP 7.1 minimum rules out the long-term support branches of PHP that most distributions now ship by default, so a project on PHP 8 has to confirm that the library runs cleanly on a runtime its CI never exercised, since the README's Travis badge points at a service that is no longer the standard for new projects.

The third is the licence, and it is unusual. The project is released under the WTFPL. That is a very permissive licence with an attribution requirement rather than the copyleft conditions of the LGPL, which was the licence Wrench historically used, and it means you can vendor the code into a commercial product without the reciprocal obligations that would attach to LGPL. It is a real advantage over the more common open source choices, and it is also a licence many corporate legal teams will want to see the actual text of, which sits in the LICENSE file at the top of the repository.

The alternative to name is Ratchet, and the difference in approach is real rather than cosmetic. Ratchet is built around the Reactor pattern: an event loop with selectable streams, and applications that implement a message interface to receive framed protocol messages rather than raw strings. Wrench is a lower-level implementation of the WebSocket protocol itself with a plain per-application data callback, so Ratchet gives you the protocol and the event model together, while Wrench gives you the protocol and leaves the event model and the framing decisions to you.

That is the correct trade for an application that already has its own PHP runtime and its own way of handling requests, and the wrong one for a real-time application that needs thousands of concurrent connections on a single process, where an event loop and cooperative scheduling are the point rather than an extra.

## Conclusion

Wrench fits a PHP team that wants a WebSocket endpoint inside an existing application and is willing to write its own message handling, and it does not fit a project that needs connection scale, a pub/sub layer or TLS termination without extra work. Before adopting it, confirm the ~3.0 release line is still what you want, since the last push was on 2026-08-08 and the repository has no GitHub releases to track versions against, and note that the WTFPL licence grants broad permission with attribution as its main condition.

## FAQ

### How do I install Wrench for PHP?

The library is PSR-4 compatible with a vendor name of Wrench and is available on Composer as wrench/wrench. Install the current major line with composer require wrench/wrench ~3.0, which requires PHP 7.1 or later.

### What PHP version does Wrench support, and what about older versions?

The README describes Wrench as a websocket server and client package for PHP 7.1, and states that the latest major release dropped support for PHP versions prior to 7.1. If you need older PHP, the 2.0 branch is the one to use, whose latest release is 2.0.8, installed with composer require wrench/wrench ~2.0.

### How do I write a WebSocket server with Wrench?

Create an object implementing \Wrench\Application\DataHandlerInterface with an onData method, construct a \Wrench\BasicServer with a base URI and options such as allowed_origins, register the application under a path name with registerApplication, optionally set a PSR-3 logger, and call run.

### What licence is Wrench released under?

Wrench is released under the WTFPL licence, and the LICENSE file at the top of the repository holds the full terms. There are no copyleft conditions attached to it.

### How is Wrench different from Ratchet?

The README points to Ratchet as an excellent Websocket layer for React. Ratchet is built on the Reactor pattern with an event loop and applications that handle framed protocol messages, while Wrench is a lower-level WebSocket implementation with a per-application onData callback and leaves the event model and framing to you.

## Sources

- [Issues](https://github.com/varspool/Wrench/issues)
- [License: WTFPL](https://github.com/varspool/Wrench/blob/master/LICENSE)
- [README](https://github.com/varspool/Wrench/blob/master/README.md)
- [varspool/Wrench on GitHub](https://github.com/varspool/Wrench)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/varspool-wrench
