Model or dataset
guidewire-oss/fern-platform avatar
guidewire-oss/fern-platform

Fern Platform: a central store for test results across CI pipelines

Unified test intelligence platform with multi-format ingestion, real-time analytics, and AI-powered insights via LLM integration

459 stars31 forksGoApache-2.0

At a glance

What is it?
Fern Platform ingests test results from any framework over a REST API and exposes them through a dashboard and GraphQL. The interesting part is the ingestion model, not the AI framing; the awkward part is that the documented install path is a k3d cluster, not a container.
Who is it for?
Adopt Fern Platform if you already run Kubernetes, want one query surface across Go, JUnit and Jest suites, and are willing to maintain the Postgres, Redis and Keycloak stack it depends on. Do not adopt it if you need a single docker run today, since the README marks the Docker image as not yet available, or if you cannot run the k3d-based deploy and its /etc/hosts entries.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Fern Platform targets: test results that never leave their CI job

Test output is usually ephemeral. A Jest run prints to a CI log, a JUnit XML file is uploaded as a build artifact, and both disappear from view once the pipeline is green. The README frames the gap as fragmented test data that needs to become actionable insight, and the concrete promise is narrower than that slogan: aggregate results from any CI/CD system into one place, then detect flaky tests and track execution times across runs.

The audience is engineering teams with more than one test framework in play. The README names Jest, pytest and JUnit as inputs, and the official client libraries listed are Go/Ginkgo, Java/JUnit (with a Gradle plugin) and JavaScript/Jest. A team running a single framework with a single pipeline gets less from this than a team running three, because the value comes from having one query surface over results that otherwise live in three different artifact stores.

The secondary audience is platform or DevOps engineers, since the documented install is a Kubernetes deployment with OAuth, and the README routes them to separate installation, configuration and troubleshooting docs. This is not a library you add to a test file. It is a service you operate.

Ingestion, storage and query: the three moving parts visible in the repository

The architecture the README describes has three layers. On the way in, a REST API accepts test results from any framework or CI/CD system, and the documented client libraries are the convenience wrapper over that endpoint. In the middle there is state: PostgreSQL 14 or later for the results, Redis 6 or later alongside it, and JIRA integration that needs a JIRA_ENCRYPTION_KEY generated with openssl rand -hex 32. On the way out there are two read paths, a dashboard and a GraphQL API.

The GraphQL example in the README is the clearest statement of the data model. A testRuns query takes a projectId, a first argument for pagination, and returns runs with id, status, duration and gitCommit fields. That gitCommit field is what makes cross-run analysis possible: without a commit identifier attached to each run you cannot say whether a failure is new or a repeat. Project identity is the other axis, and the README describes a manager creating a project in the UI, then developers configuring clients with FERN_PROJECT_ID.

Flaky test detection and performance tracking are described as automatic, but the README does not state the detection method, the window over which intermittency is measured, or the threshold that separates a flaky test from a genuinely broken one. Treat those features as documented behaviour you will have to validate against your own data rather than as a specified algorithm.

Getting it running: k3d, hosts entries and a Makefile target

There are two documented install paths, and only one of them works today. The Docker option is explicitly marked coming soon, with a docker run example labelled as future usage and not yet available. The README says plainly to use Kubernetes deployment or build from source for now.

The Kubernetes path is short but has prerequisites: Docker with buildx, k3d, kubectl, Go 1.21 or later (the README notes the Makefile uses it for architecture detection), Make, and 8GB of RAM minimum. The sequence is a git clone, two hosts entries, then a single make target. The hosts entries matter because OAuth is part of the default deployment: 127.0.0.1 fern-platform.local and 127.0.0.1 keycloak. Skipping them breaks the login flow rather than the service.

make deploy-all-v2 brings up the deployment with the React frontend, which the README recommends, and serves it at http://fern-platform.local:8080/v2. make deploy-all serves the classic frontend at the root. Default credentials are admin@fern.com with password test123, which is a development default and not something to expose.

There is a documented escape hatch for corporate networks. If k3d nodes cannot pull images because of TLS inspection, the README gives make deploy-quick-v2 after manually importing redis:7-alpine and quay.io/keycloak/keycloak:23.0 with k3d image import. On the client side, two environment variables do the work: FERN_PROJECT_ID and FERN_URL.

The Docker gap and the v1/v2 frontend split

The most concrete limitation is stated by the project itself: the container image is not available yet. For a service whose whole job is to sit behind a REST endpoint and collect results, requiring a Kubernetes cluster and a Keycloak instance to try it is a high floor. A team that wants to evaluate Fern Platform in an afternoon cannot do it with the documented steps unless they already have k3d and 8GB of headroom.

The frontend situation is the second friction point. There are two UIs, a v1 classic frontend at the root and a v2 SPA at /v2, and the v2 SPA is described as opt-in. Two frontends mean two surfaces to keep working, and the README does not say whether v1 is on a deprecation path. If you deploy v2 and your users have bookmarked the root URL, they will land on the older interface.

OAuth is effectively mandatory in the documented deployment, since Keycloak is part of the make target and the hosts entries exist to make it resolve. The README mentions team-based access control with OAuth/SSO and role-based permissions as a feature, which is reasonable for a multi-team deployment, but it also means there is no documented single-user or no-auth mode for a quick local trial. The friction is deliberate, but it is friction.

How this differs from a general observability stack

The README compares Fern Platform to Datadog or Grafana, purpose-built for test intelligence. The difference in approach is worth taking seriously. A general observability platform ingests metrics, logs and traces through its own agents and SDKs, and you model test outcomes as just another event type with your own schema and dashboards. Fern Platform inverts that: it defines the test-run schema itself, including project, status, duration and gitCommit, and gives you clients that emit into it. You get flaky detection and a treemap view without building them, and you give up the freedom to reshape the data model.

The GraphQL API is the seam between those two positions. If the testRuns query shape covers your questions, you avoid writing your own aggregation. If it does not, you are querying a schema someone else controls. That is the trade: less assembly work up front, less flexibility later.

The framework-specific clients are the other distinction. Datadog and Grafana expect you to emit from your test runner yourself. Fern Platform ships Go/Ginkgo, Java/JUnit and JavaScript/Jest clients, and the README points to a client development guide for Python, Ruby, PHP and .NET. If your framework is not on the list, the platform's value depends on how much work that guide actually saves you, and the README does not quantify it.

Maintenance, versioning and what the Apache-2.0 licence leaves you

The release history is thin and recent. v0.1.0 landed in July 2025, v0.2.0 in October 2025, and v1.0.0 in July 2026. Three releases over roughly a year, with the jump from 0.2.0 to 1.0.0 taking about nine months. The 1.0.0 label suggests the API is considered stable, but the README still carries a coming-soon marker on the Docker path, which is a sign that some planned surface area has not landed.

The operational load is the real cost. You are running PostgreSQL, Redis and Keycloak alongside the Go service, and the README's own prerequisite list asks for 8GB of RAM minimum on the Kubernetes path. Upgrades mean coordinating three stateful dependencies, not just swapping a binary. The JIRA integration adds a fourth concern: JIRA_ENCRYPTION_KEY has to be generated once and then preserved, because the README describes it as the key for that integration and rotating it carelessly would affect stored credentials.

Apache-2.0 is permissive: you can run it commercially, modify it and redistribute it, with the usual requirements around preserving notices and stating changes. This is a description of the licence text, not legal advice, and if you plan to redistribute a modified version, read the LICENSE file in the repository rather than this summary. The README does not describe any separate enterprise edition or licence gate, so the client libraries and the platform appear to sit under the same terms.

Who should adopt it, and what to check before you do

The fit is a team running several test frameworks across several repositories, already on Kubernetes, with a Keycloak or comparable OAuth provider they are willing to point the deployment at. For that team, the REST ingestion plus GraphQL query surface replaces a pile of CI artifacts with one place to ask whether a test has been flaky since a particular commit. The treemap view and saved views in the v2 SPA are the parts that make the data legible without writing queries.

The poor fit is a small team or a single-framework shop that wants a container and a database. The documented install is a k3d cluster with hosts entries and a Keycloak instance, and the Docker image is marked not yet available. If that is your situation, the setup cost exceeds the insight you would gain from one Jest suite.

Before deploying, verify three things against the repository rather than the README. First, confirm a current client library exists for your framework, since the listed official clients cover Go/Ginkgo, Java/JUnit and Jest only. Second, run the deploy target on a throwaway cluster and check that Keycloak resolves at the hostname the hosts entry creates, because OAuth failures there will look like application errors. Third, decide which frontend you are standardising on, /v2 or the root, and check the repository's docs for whether v1 is still receiving changes. If the flaky detection output does not match what your team would call flaky on your own history, the dashboard is a viewer, not an oracle.

Editorial conclusion

Adopt Fern Platform if you already run Kubernetes, want one query surface across Go, JUnit and Jest suites, and are willing to maintain the Postgres, Redis and Keycloak stack it depends on. Do not adopt it if you need a single docker run today, since the README marks the Docker image as not yet available, or if you cannot run the k3d-based deploy and its /etc/hosts entries. Before committing, verify the client library for your framework actually exists and is current, confirm the deploy path works behind your proxy, and check whether the v1 or v2 frontend is the one you intend to support.

Official sources

  1. guidewire-oss/fern-platform on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Community notes

Community notes