Skip to content
CAI
Software that uses CAICheck a score

playframework/play-ws

62.3

Adequate · 20 September 2026

6.7k

lines of production code

Scala

with Java

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a standalone HTTP client library that operates independently of the Play Framework runtime, built on Apache Pekko Streams for asynchronous request handling. It provides a comprehensive API for constructing and executing HTTP requests, featuring support for JSON and XML body serialization, OAuth authentication, and RFC-compliant HTTP response caching. The library also includes configurable connection pooling, secure XML parsing, and utilities for request filtering and debugging.

How it got here

2016 — Migration to Pekko and standalone extraction

17 changes.

The project extracted Play WS into a standalone library decoupled from the Play Framework, migrating the underlying HTTP client from Akka to Apache Pekko Streams. This period involved rebranding the module, removing legacy implementations and test suites, and modernizing the build infrastructure to support Scala 3 and Java 17.

2017–2025 — Standalone WS module enhancements

16 changes.

This period focused on expanding the Play WS standalone modules with new features, including RFC 7234-compliant HTTP caching, secure XML parsing, and dedicated JSON body handling interfaces for Java and Scala. These functional additions were accompanied by extensive test coverage, integration tests, and performance benchmarks to ensure robustness and correctness across the updated client implementation.

Features

Add XML body read and write support for WS requests and responses

The Play WS standalone XML module now provides built-in support for handling XML payloads. Users can read XML responses directly into a W3C DOM Document via the new \xml()\ body readable, and write DOM documents in outgoing requests using the new \body(Document)\ body writable. The implementation includes a new \XML\ utility class that safely parses XML using a secure DocumentBuilderFactory configuration (disabling external entities and DOCTYPE declarations) and converts DOM nodes to byte strings using Apache Pekko's ByteString.

play-ws-standalone-xml/src/main/java/play/libs/ws · high confidence

Add implicit JSON body readables and writables for Play-WS

The play-ws-standalone-json module now provides implicit conversions to seamlessly read and write JSON bodies in WebSocket responses. Users can directly access the response body as a JsValue using the new JsonBodyReadables trait, and send JsValue or Jackson JsonNode payloads via the updated JsonBodyWritables, which optimize serialization by converting directly to byte arrays.

play-ws-standalone-json/src/main/scala/play/api/libs/ws · high confidence

Configurable AHC standalone client settings

The standalone AHC WS implementation now exposes a comprehensive set of configuration options via \reference.conf\, allowing users to tune connection pooling (max connections per host/total, keep-alive, idle timeout, cleaner period), request handling (redirects, retries, URL encoding), and cookie behavior (lax vs strict decoding, cookie store enablement).

play-ahc-ws-standalone · high confidence

HTTP response caching support added to the standalone AHC client

The standalone AHC client now includes a complete HTTP caching implementation compliant with RFC 7234. This change introduces a new \AhcHttpCache\ class and supporting components (such as \CachingAsyncHttpClient\, \AsyncCachingHandler\, and \BackgroundAsyncHandler\) that intercept requests to serve fresh, stale, or validated responses from a local cache before contacting the origin server. Users benefit from reduced latency and bandwidth usage for repeated requests, with support for features like stale-while-revalidate and heuristic freshness calculation.

play-ahc-ws-standalone/src/main/scala/play/api/libs/ws/ahc/cache · high confidence

Introduce standalone Play WS API with Pekko streaming support

The \play-ws-standalone\ module now provides a standalone HTTP client API built on Apache Pekko Streams, decoupling it from the Play Framework runtime. This change introduces core traits for the client (\StandaloneWSClient\), request builder (\StandaloneWSRequest\), and response (\StandaloneWSResponse\), along with default body readables and writables that leverage Pekko's \ByteString\ and \Source\ types. Configuration is handled via \WSConfigParser\ using Jakarta Inject, and the API supports request filtering through \WSRequestFilter\. Users can now perform HTTP requests using a self-contained library without requiring the full Play web framework.

play-ws-standalone/src/main/scala/play/api/libs/ws · high confidence

New Java JSON body read/write interfaces

The play-ws-standalone-json module now provides Java-specific interfaces for handling JSON bodies in WebSocket requests and responses. JsonBodyReadables allows reading response bodies into Jackson JsonNode objects using a configurable ObjectMapper, while JsonBodyWritables enables writing JsonNode objects into request bodies as ByteString payloads with automatic content-type setting. These interfaces replace previous Scala-centric approaches and provide direct integration with Jackson's ObjectMapper for JSON serialization and deserialization.

play-ws-standalone-json/src/main/java/play/libs/ws · high confidence

Removals

Removal of Play WS implementation classes

The AhcWSAPI, AhcWSClient, AhcWSCookie, AhcWSModule, AhcWSRequest, and NingWSClient classes have been removed from the play-ahc-ws module. This eliminates the internal implementation details of the AsyncHttpClient-based WebSocket client and its associated dependency injection bindings, effectively decoupling the public API from the underlying AsyncHttpClient infrastructure.

play-ahc-ws/src/main/java/play/libs/ws · high confidence

Removal of Play WS standalone implementation

The standalone Play WS implementation (including the \play-ahc-ws\ module and core \play-ws\ abstractions) has been removed. This deletes the \AhcWSClient\, \NingWSClient\, and their associated configuration parsers (\AhcConfig\, \NingConfig\), along with the \WS\ companion object and \WSClient\/\WSRequest\ traits. Users can no longer use the standalone Play WS library for HTTP requests; this functionality is no longer available in this module.

(repo-wide) · high confidence

Removal of WSTestClient test utility

The \WSTestClient\ trait, previously located in \play-ahc-ws/src/main/scala/play/api/test/\, has been removed from the codebase. This eliminates the built-in helper methods (\wsCall\, \wsUrl\, \withClient\) that allowed users to easily construct and execute WebSocket requests against a running Play application during testing. Users relying on this specific test client implementation will need to adopt an alternative testing strategy or provide their own implementation.

play-ahc-ws · high confidence

Removal of legacy Play WS Java API classes

The \play.libs.ws\ package has removed several legacy classes, including \WS\, \WSAPI\, \StreamedResponse\, \WSCookie\, \WSRequestExecutor\, \WSRequestFilter\, \WSResponse\, and \WSResponseHeaders\. This change eliminates the deprecated static factory methods and filter-based request processing previously available in the Play WS library, requiring users to rely on dependency-injected \WSClient\ instances instead.

play-ws/src/main/java/play/libs/ws · high confidence

Behavioural changes

Introduce standalone Java WS client implementation with Pekko streams

The Play WS library now includes a standalone Java implementation (AhcWS) that replaces the previous Akka-based backend with Apache Pekko streams for handling asynchronous HTTP requests and streamed responses. This change introduces new Java API classes such as StandaloneAhcWSRequest and StreamedResponse, enabling users to build and execute HTTP requests using Pekko's Source and Sink abstractions while maintaining compatibility with the existing Play WS interface.

play-ahc-ws-standalone/src/main/java/play/libs/ws · high confidence

Introduction of DefaultObjectMapper for Jackson integration

A new DefaultObjectMapper object has been added to the play.libs.ws package, providing a centralized way to access the Jackson ObjectMapper instance used by the Play JSON library. This change enables users in the Java/Scala WS standalone JSON module to easily retrieve the underlying Jackson mapper for custom serialization or deserialization needs, leveraging the private\[play\] methods now accessible via the Scala object structure.

play-ws-standalone-json/src/main/scala/play/libs/ws · high confidence

OAuth library implementation switched to shaded dependencies

The OAuth module in the standalone Play WS implementation now uses internally shaded versions of the OAuth Signpost and AsyncHttpClient libraries instead of external dependencies. This change removes the need for users to manually provide these libraries, as the required classes are now bundled within the Play WS standalone artifact, simplifying dependency management for applications using OAuth authentication.

play-ahc-ws-standalone/src/main/java/play/libs/oauth · high confidence

Play WS Java API refactored with typed body handling and Pekko streams

The Java WS client API in play.libs.ws has been restructured to use a standalone interface model (StandaloneWSClient, StandaloneWSRequest, StandaloneWSResponse) and now relies on a typed body system using BodyReadable and BodyWritable interfaces. This replaces the previous method overloads that accepted raw types (String, JsonNode, File, InputStream) with a unified BodyWritable contract for requests, allowing for more consistent and type-safe body handling. Response bodies are now accessed via BodyReadable transformations, and the underlying streaming infrastructure has been migrated from Akka to Apache Pekko, as evidenced by the imports of org.apache.pekko.stream.javadsl.Source and org.apache.pekko.util.ByteString.

play-ws-standalone/src/main/java/play/libs/ws · high confidence

Play WS Standalone rebrands and updates documentation

The project has officially rebranded from 'Play WS' to 'Play WS Standalone', shifting the Maven groupId from \com.typesafe.play\ to \org.playframework\ and updating the README to reflect the new standalone nature of the library (no Play dependencies). The documentation now highlights support for typed request/response bodies, the QUERY HTTP method (RFC 10008), and streaming responses using Pekko Streams (referencing \org.apache.pekko\). Additionally, the repository now uses Scalafmt 3.11.5 for code formatting and updates the LICENSE file to the standard Apache 2.0 text.

(repo-wide) · high confidence

Play WS standalone configuration simplified and TLS defaults updated

The Play WS standalone module's reference configuration has been streamlined by removing obsolete SSL settings (such as disabled signature/key algorithms, debug flags, and weak protocol/cipher allowances) and AHC-specific connection pool settings that are no longer managed here. Additionally, the default SSL protocol has been upgraded from TLSv1.2 to TLSv1.3, with TLSv1.2 explicitly enabled alongside it, and comments added recommending environment variables for keystore/truststore passwords.

play-ws-standalone · high confidence

Play WS standalone implementation extracted and migrated to Apache Pekko

The Play WS standalone implementation has been extracted into the \play-ahc-ws-standalone\ module, moving core classes like \StandaloneAhcWSClient\ and \StandaloneAhcWSResponse\ to this new location. The underlying HTTP client has been migrated from Akka to Apache Pekko, evidenced by the use of \org.apache.pekko.stream\ and \org.apache.pekko.Done\ in the new client code. The implementation now relies on shaded AsyncHttpClient classes (prefixed with \play.shaded.ahc\) and includes a new \AhcLoggerFactory\ to bridge SSL config logging with SLF4J. Additionally, the \AhcCurlRequestLogger\ has been updated to support the new \StandaloneAhcWSRequest\ type, adding explicit handling for Basic authentication headers and cookies in its curl output.

play-ahc-ws-standalone/src/main/scala/play/api/libs/ws/ahc · high confidence

Play WS standalone library migrates to Apache Pekko and adds request filtering and curl logging

The Play WS standalone library has migrated its underlying actor system from Akka to Apache Pekko, updating imports and dependencies accordingly. It introduces a new request filter mechanism (WSRequestFilter) that allows users to intercept and modify requests, demonstrated by new filter implementations for appending headers and logging. A new AhcCurlRequestLogger filter is provided to log outgoing requests in curl format for debugging. The API has been refined with the addition of a query method for the HTTP QUERY verb, support for disabling URL encoding, and a more consistent approach to body handling using BodyReadable and BodyWritable type classes. Cookie handling has been improved with the introduction of a WSCookieBuilder and Optional return types for getCookie, and the client configuration now exposes settings for connection pool cleaning and cookie store usage.

repository · high confidence

Secure XML parsing and body handling in Play WS

The Play WS standalone XML module now provides secure, configurable XML parsing and body read/write capabilities. A new XML object configures the SAX parser to prevent XXE (XML External Entity) injection by disabling external general and parameter entities, disallowing DOCTYPE declarations, and enabling secure processing features. This secure parser is used by XMLBodyReadables to safely convert response bodies into Scala XML elements, and by XMLBodyWritables to serialize XML nodes and DOM documents into request bodies with the 'text/xml' content type.

play-ws-standalone-xml/src/main/scala/play/api/libs/ws · high confidence

Test coverage

Added JMH benchmarks for StandaloneAhcWSRequest map operations; Added integration test for HTTP response caching; Added integration tests for Play WS Ahc client; Added integration tests for Play WS client and request filters; Added test coverage for AHC WS client configuration and request handling; Added test coverage for AhcWSRequest and AhcWSResponse; Added test for OAuth signpost availability; Added test suite for HTTP caching components; Added tests for JSON body decoding with various character encodings; Removal of Play WS and OpenID test suite; Removed OAuth test suite and verification utilities; Updated WSConfigParserSpec test suite.

Dependencies

Build infrastructure modernized to sbt 2 and Play 3 dependencies

The build system has been upgraded from sbt 0.13 to sbt 2.0.8, and the project now targets Play 3.1.0-M10 and Pekko 2.0.0-M4. This update introduces a new dependency management structure in \project/Dependencies.scala\, explicitly shading Netty dependencies to resolve version conflicts with Async Http Client, and adds support for Java 9+ module names via a new \AutomaticModuleName\ helper. Publishing is now handled by \sbt-ci-release\, replacing the previous Sonatype and PGP plugins, while code formatting is enforced by \sbt-scalafmt\ and binary compatibility is checked by \sbt-mima-plugin\.

project · high confidence

Major build system overhaul and dependency updates

The build configuration has been significantly restructured, upgrading the Java target to version 17 and adding support for Scala 3 alongside Scala 2.13. The project organization has switched to org.playframework, and binary compatibility is now enforced against version 3.0.0 using MiMa. Additionally, the build now shades the AsyncHttpClient and OAuth libraries to prevent conflicts, and updates the sbt-assembly plugin to version 2.0.0.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 62.

Lenses

  • Code Health 98
  • Architecture 74
  • Maturity 58
  • Readiness 73
  • Security 57

Changes since last survey

  • 300 commits — 297 feature/other, 3 fixes

By area

  • (repo) — 136 commits
  • project/Dependencies.scala — 86 commits
  • (root) — 24 commits
  • project/build.properties — 19 commits
  • project/plugins.sbt — 16 commits
  • .github/workflows — 5 commits
  • play-ahc-ws-standalone/src — 5 commits
  • play-ws-standalone-json/src — 4 commits
  • play-ws-standalone/src — 3 commits
  • .github/scala-steward.conf — 2 commits

Notable commits

  • fix: Merge pull request #1130 from mkurz/revert-jackson-module-scala
  • fix: Merge pull request #1269 from mkurz/fix-release-drafter
  • fix: Revert "Explicitly set jackson-module-scala version"
  • change: Add 'Reformat with scalafmt 3.10.6' to .git-blame-ignore-revs
  • change: Add 'Reformat with scalafmt 3.9.7' to .git-blame-ignore-revs
  • change: Add HTTP QUERY method support (RFC 10008)
  • change: Async Http Client 2.15.0 + netty-reactive-streams upgrade
  • change: Bump actions/checkout from 4 to 5
  • change: Bump actions/checkout from 5 to 6
  • change: Bump actions/checkout from 6 to 7
  • change: Bump cachecontrol to 3.1.0-M2 (upgrades scala-parser-combinators for Scala 2.13)
  • change: Bump release-drafter/release-drafter from 6 to 7
  • change: DefaultObjectMapper is a Scala object now so we can access private[play] methods
  • change: Drop ssl config because it's dead code in ssl-config
  • change: Drop ssl config from reference conf which is no longer in ssl-config
  • change: Explicitly set jackson-module-scala version
  • change: Merge pull request #1010 from playframework/update/specs2-core-4.21.0
  • change: Merge pull request #1011 from playframework/update/patches
  • change: Merge pull request #1012 from mkurz/cachecontrol_3.1.0-M2
  • change: Merge pull request #1013 from mkurz/scala_steward-no_frequency
  • …and 280 more

Architecture

  • 0 containers · 1 bounded contexts · 0 dependency edges (baseline)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

playframework/play-ws was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 01e101fae3d96b3c57b8ace8be0fc5f4aa046b75 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.