softwaremill/ox
63.9
Adequate · 20 September 2026
8.6k
lines of production code
Scala
primary language
1
measurement over time
What this system is
Ox is a Scala 3 library that provides structured concurrency primitives, including supervised scopes and a composable Flow API for asynchronous data streaming. It extends this core with resilient patterns like circuit breakers and rate limiting, alongside integrations for Kafka, Reactive Streams, and distributed tracing. The system is designed to manage thread lifecycles and error handling safely while supporting complex scheduling and JSON processing tasks.
How it got here
2023 — Structured concurrency and streaming API development
9 changes.
The project established its foundational structure and upgraded to Scala 3.3.8 and Java 21, while restructuring the core concurrency model around supervised scopes and error modes. Significant effort was dedicated to implementing a new channel-based streaming API with explicit error handling and comprehensive test coverage for core utilities. The period concluded with the introduction of a Kafka integration module for flow-based message processing.
2024 — Resilience, Scheduling, and Flow API expansion
11 changes.
This period focused on expanding the core concurrency library with new resilience primitives like adaptive retries and circuit breakers, alongside a major refactoring of the scheduling API. Significant effort was also dedicated to introducing a new Flow API for asynchronous data streaming, including Reactive Streams integration and comprehensive test coverage. Documentation infrastructure was simultaneously overhauled to support the growing feature set.
2025–2026 — Scheduling, observability, and streaming JSON
5 changes.
This period focused on expanding core capabilities with cron-based task scheduling and OpenTelemetry context propagation for virtual threads. It also introduced a new flow-json module for efficient streaming NDJSON and JSON array processing, alongside improved error diagnostics for concurrency scopes.
Features
Add InheritableMDC for structured concurrency
The mdc-logback module now includes InheritableMDC, allowing MDC values to be inherited by child threads within structured concurrency scopes. Users can use methods like supervisedWhere to set MDC context that is automatically available to forks created inside the scope, while standard MDC.put calls remain thread-local. This requires calling InheritableMDC.init early in the application startup to replace Logback's MDC adapter with a scope-aware implementation.
mdc-logback · high confidence
Add cron-based scheduling for repeat operations
Users can now schedule repeated tasks using standard cron expressions via the new \CronSchedule\ API in the \ox.scheduling.cron\ package. This feature allows specifying precise timing patterns (e.g., every second) for \repeat\ operations, replacing the previous interval-list based approach for such use cases.
cron · high confidence
Add flow-json module for streaming NDJSON and JSON array parsing and rendering
The new flow-json module introduces extension methods on Flow\[Chunk\[Byte\]\] and Flow\[T\] to handle JSON data in streaming contexts. Users can now parse UTF-8 Newline Delimited JSON (NDJSON) via parseNdjson, which handles line delimiters, BOMs, and configurable record size limits, or parse a complete top-level JSON array via parseJsonArray, which emits elements as they are discovered. Conversely, renderNdjson converts a flow of values into UTF-8 JSON lines, while renderJsonArray aggregates values into a single JSON array output. These capabilities rely on the jsoniter-scala library for efficient serialization and deserialization.
flow-json · high confidence
Initial project setup and tooling configuration
The repository is initialized with the Ox library (Apache 2.0 licensed) for Scala 3 on the JVM. This change introduces the core project configuration, including an Apache 2.0 LICENSE, a README with usage examples, and a \.scala-steward.conf\ pinning the Scala 3 library version. It also updates the code formatter (\.scalafmt.conf\) to version 3.11.5 with specific Scala 3 syntax rules, configures automated dependency updates via Scala Steward, and sets up documentation generation for ReadTheDocs. Additionally, it refines the \.gitignore\ to exclude local IDE and build artifacts.
(repo-wide) · high confidence
Initial release of generated documentation site
The documentation site for Ox is now available in the generated-doc/out directory. This includes the full source for a Sphinx-based static site (conf.py, index.md, tour.md, and topic pages) configured with the Read the Docs theme and the sphinx-llms-txt extension to generate LLM-friendly text files. The site is built using Python 3.12 and can be managed via Makefile, make.bat, or a Nix flake that sets up a virtual environment and installs dependencies.
generated-doc/out · high confidence
Integration with Reactive Streams Publisher
The flow-reactive-streams module now provides bidirectional conversion between Ox Flows and the org.reactivestreams.Publisher interface. Users can convert a Flow into a Reactive Streams Publisher using the new toReactiveStreamsPublisher extension method, and create a Flow from an existing Reactive Streams Publisher using FlowReactiveStreams.fromPublisher, enabling interoperability with libraries that rely on the Reactive Streams specification.
flow-reactive-streams · high confidence
Introduce Flow API for direct-style concurrency streaming
Adds a new \Flow\ abstraction in \core/src/main/scala/ox/flow\ that provides a lazy, composable pipeline for asynchronous data streaming. This API allows users to construct transformation stages (such as \map\, \buffer\, and \grouped\) and run them using various terminal operations like \runToList\, \runToChannel\, \runToInputStream\, and \runToFile\. It also includes companion methods to create flows from sources, iterators, or JDK 9+ \Publisher\s, and integrates with the existing \ox\ concurrency primitives like \OxUnsupervised\ scopes and \BufferCapacity\.
core/src/main/scala/ox/flow · high confidence
Introduce Ox Kafka integration with Flow-based streaming and offset management
This change adds a new Kafka integration module to the Ox library, providing a Flow-based API for consuming and producing messages. It introduces \KafkaFlow\ for subscribing to topics, \KafkaStage\ for publishing records and committing consumer offsets in a type-safe manner, and \KafkaDrain\ for running publish/commit operations as drains. The implementation includes \ConsumerSettings\ and \ProducerSettings\ for configuration, a thread-safe \KafkaConsumerWrapper\ backed by an actor, and packet types (\SendPacket\, \CommitPacket\) to manage message processing and offset commits. A Docker Compose file is also added to support local testing with Zookeeper and Kafka.
kafka · high confidence
Introduce structured concurrency channels with explicit error handling and configurable buffer capacity
The \ox.channels\ package now provides a new channel-based streaming API built on the \jox\ library, featuring \Source\ and \Sink\ abstractions with non-blocking \trySend\/\tryReceive\ methods and explicit \ChannelClosed\ union types for handling done/error states without throwing exceptions by default. Channel buffer capacity is now configurable via a \BufferCapacity\ context parameter (defaulting to 16), and the API includes a \select\ mechanism for multi-channel operations with support for default clauses. Additionally, a simple type-safe actor model is introduced via \Actor.create\, allowing serial execution of logic within a concurrency scope.
core/src/main/scala/ox/channels · high confidence
New resilience primitives: adaptive retries, circuit breaker, and rate limiting
The \ox.resilience\ package now includes three new capabilities to protect downstream systems. Adaptive retries use a token bucket to limit retry attempts based on success/failure outcomes, preventing overload during systemic failures. A circuit breaker monitors failure and slow-call rates to drop operations when a service is unhealthy, supporting both count-based and time-based sliding windows. Additionally, rate limiters are available with fixed, sliding, and leaky-bucket algorithms, allowing you to control operation throughput by either start time or total execution duration.
core/src/main/scala/ox/resilience · high confidence
OpenTelemetry context propagation for virtual threads
The otel-context module now includes a PropagatingVirtualThreadFactory that ensures OpenTelemetry context is automatically propagated to newly created virtual threads. When a thread is spawned, the current context is captured and made current for the duration of the task, and the scope is properly closed afterward, ensuring consistent tracing across virtual thread boundaries.
otel-context · high confidence
Removals
Removal of Warp structured concurrency and scoped value utilities
The \Warp\ object, which provided structured concurrency primitives (such as \Warp.fork\, \Warp.uninterruptible\, and \FiberLocal\) built on top of JDK incubator modules (\jdk.incubator.concurrent\), has been removed from the JDK module. Corresponding test files and characterization scripts that validated these scoped value and nested scope behaviors have also been deleted, eliminating this concurrency abstraction from the codebase.
jdk · high confidence
Behavioural changes
Add Scarf analytics tracking to documentation
The documentation now includes a Scarf tracking pixel on every page to collect usage analytics. This is implemented by injecting a specific image tag into the footer template, which loads a pixel from static.scarf.sh with a unique project ID.
_doc/\_templates, generated-doc/out/\templates · high confidence
Documentation build infrastructure and content structure
The documentation site has been restructured with a new 'Tour of Ox' featured on the front page and a comprehensive table of contents covering concurrency, streaming, scheduling, and integrations. The build system now uses Sphinx with the Read the Docs theme, supports both Markdown and reStructuredText, and includes a Python 3.12 development shell via Nix flakes. Additionally, the site now generates llms.txt files for AI coding assistants and provides a watch script for live development.
doc · high confidence
Improved error messaging for invalid fork creation
When attempting to create a fork outside of a valid concurrency scope, users now receive a specific error message identifying the unrelated thread that attempted the operation, rather than a generic scope-tree violation. This change is implemented in the internal ThreadHerd and ScopeContext components, which now track the current scope context per thread to provide clearer diagnostics for this user error.
core/src/main/scala/ox/internal · high confidence
New internal implementation for Flow.groupBy with parallelism support
The \groupBy\ operation on flows now uses a new internal implementation (\groupByImpl\) that supports configurable parallelism. This change introduces a \WeightedHeap\ data structure to manage child flow lifecycle, allowing the system to track the most recently active groups and complete the least active ones when the parallelism limit is reached. This enables concurrent processing of grouped elements while ensuring that the number of active child flows does not exceed the specified limit, preventing resource exhaustion and potential deadlocks.
core/src/main/scala/ox/flow/internal · high confidence
Refactored scheduling API with new Schedule and RepeatConfig abstractions
The scheduling subsystem has been restructured to use a new \Schedule\ class based on lazy interval lists, replacing the previous implementation. This change introduces \Jitter\ modes (Full and Equal) for randomizing delays, \SleepMode\ (StartToStart vs EndToStart) to control timing semantics, and a dedicated \RepeatConfig\ for repeat operations that decouples repetition logic from general scheduling. Users will now configure retries and repeats using these new types, which support methods like \maxAttempts\, \jitter\, and \andThen\ for composing schedules.
core/src/main/scala/ox/scheduling · high confidence
Structured concurrency with supervised scopes and application error modes
The core concurrency model is restructured around structured scopes (\supervised\, \supervisedError\, \unsupervised\) and their associated capabilities (\Ox\, \OxError\, \OxUnsupervised\). \supervised\ scopes now automatically manage fork lifecycle and resource cleanup, while \supervisedError\ introduces a pluggable \ErrorMode\ system (supporting \Either\ and union types) to handle application-level errors that terminate the scope. This is complemented by \OxApp\ for robust application entry points with proper shutdown hooks, and new utilities like \abandonOnInterrupt\ for uninterruptible blocking operations and \computeIntensive\ for offloading CPU-bound work to platform threads.
core/src/main/scala/ox · high confidence
Test coverage
Added comprehensive test coverage for Flow operations and IO integration; Added comprehensive test coverage for channels, actors, and source operations; Added comprehensive test coverage for core concurrency and utility features; Added test coverage for resilience and scheduling primitives; Added test utilities for timing, counting, and tracing; Added tests for Flow-to-Reactive Streams integration.
Dependencies
Upgrade to Scala 3.3.8 and Java 21; update core dependencies
The project now requires Scala 3.3.8 and Java 21, enabling the use of future lazy values and updated bytecode output. Core library dependencies have been updated, including logback-classic to 1.6.3, slf4j-api to 2.0.19, scalatest to 3.2.20, and pekko-stream to 1.7.0. Additionally, new modules for JSON flow support (using jsoniter-scala), cron scheduling (cron4s), and OpenTelemetry context propagation have been added to the build.
(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 64.
Lenses
- Code Health 96
- Architecture 97
- Maturity 66
- Readiness 50
- Security 78
Changes since last survey
- 300 commits — 287 feature/other, 13 fixes
By area
- (root) — 111 commits
- core/src — 64 commits
- project/build.properties — 27 commits
- generated-doc/out — 25 commits
- project/plugins.sbt — 20 commits
- .github/workflows — 7 commits
- cursor-rules/generation — 6 commits
- .devcontainer/devcontainer.json — 5 commits
- .devcontainer/Dockerfile — 4 commits
- .devcontainer/sandcat — 4 commits
- doc/info — 4 commits
- doc/basics — 3 commits
- doc/other — 3 commits
- cursor-rules/100-ox-direct-style.mdc — 2 commits
- doc/index.md — 2 commits
- doc/integrations — 2 commits
- .devcontainer/Dockerfile.app — 1 commit
- .devcontainer/post-create.sh — 1 commit
- .devcontainer/post-start.sh — 1 commit
- cursor-rules/100-ox-direct-style-overview.mdc — 1 commit
Notable commits
- fix: Fix AdaptiveRetry to retry retriable Left errors when shouldPayFailureCost is false (#451)
- fix: Fix channel docs
- fix: Fix data race in Flow.groupBy (#346)
- fix: Fix docs
- fix: Fix flaky CircuitBreakerTest timing assertions (#452)
- fix: Fix return doc of Channel.receive() (#392)
- fix: Fix rule metadata
- fix: Fix rule metadata
- fix: Fix rule metadata
- fix: Fix test
- fix: Fix to run finalizers once when there's an exception during releasing (#336)
- fix: Move ownership fix & fix claude update
- fix: Revert "Add abandonOnInterrupt utilities for uninterruptible blocking operations"
- change: Add ++ as alias for concat
- change: Add Claude Code GitHub Workflow (#395)
- change: Add Claude Code extension and mount host config files
- change: Add Flow.retry and Flow.recover (#339)
- change: Add Flow.usingChannel (#397)
- change: Add OpenTelemetry context module (#293)
- change: Add a commit drain & stage to Kafka (#383)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
softwaremill/ox 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 e48dd8ff4db705ecf067379afdbd5d4575a66639 — 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.