Grafana Faro Web SDK, real user monitoring that stops at the browser
The Grafana Faro Web SDK, part of the Grafana Faro project, is a highly configurable web SDK for real user monitoring (RUM) that instruments browser frontend applications to capture observability signals. Frontend telemetry can then be correlated with backend and infrastructure data for full-stack observability.
At a glance
- What is it?
- The Faro Web SDK instruments browser frontends and forwards what it collects to Grafana Alloy, to Grafana Cloud or to a receiver you write, so that browser telemetry can be correlated with backend and infrastructure data. Its most useful documentation is the table of what it does not support, and its most useful engineering artifact is the reference application the team maintains alongside it.
- Who is it for?
- Faro fits a team running a browser application that already has a Grafana stack, or that wants front-end telemetry in the same place as back-end traces, and the package split means you can take the core and the React binding without the rest. It does not fit a Node service, a service worker, a browser extension or a server-rendered runtime, and the readme is explicit that extension use is unsupported and that issues for it are not accepted.
- 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 received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What gets collected, and where it is sent
The Grafana Faro Web SDK is described as a highly configurable web SDK for real user monitoring that instruments browser frontend applications to capture observability signals, and the point of the whole thing is correlation. Frontend telemetry can then be correlated with backend and infrastructure data for full-stack observability.
That correlation is the argument for a browser SDK at all. A slow request is easy to see in a back-end trace; a slow request that the user felt, because the button did nothing for four seconds on a phone with a bad connection, only shows up if the browser reports it. Faro is the piece that reports it, and the rest of the stack is where you make sense of it.
The destinations are three, and the choice of receiver is the first decision a user makes. Telemetry can be forwarded to Grafana Alloy, with the faro receiver integration enabled, to a Grafana Cloud instance, or to a custom receiver. Alloy then sends the data on to Loki or to Tempo, which is the piece that makes the full-stack correlation work, since the same identifiers carry from the browser into the back-end trace.
A custom receiver is the option that keeps this project from being a vendor lock-in, and it is the one to think about if the rest of your infrastructure is not Grafana. What the SDK needs from a receiver is a well-defined push endpoint, and the readme leaves the contract to the receiver documentation and the quick start guide rather than describing it here.
Five packages in one monorepo
The repository consists of multiple packages that can be combined depending on your requirements, and the four documented ones are worth naming.
@grafana/faro-core is the main package providing the core functionality of the SDK, and its README gives an overview of the architecture and the API. @grafana/faro-web-sdk provides instrumentations, metas and transports for use in web applications, which is the vocabulary of the SDK: instrumentations produce signals, metas attach context to them, and transports move them out of the browser. @grafana/faro-web-tracing provides the implementation for tracing web applications. And @grafana/faro-react enables easier integration in projects built with React, which is a binding package rather than a feature.
The workspace configuration in the root package.json shows the wider shape. The workspaces are `packages/**`, with `packages/core/internal` excluded, plus `experimental/**` and `e2e/*`. The root package is marked private, with a lerna.json for the tooling and a yarn workspace setup with a .yarnrc.yml, so this is a Lerna and Yarn monorepo rather than a single package with a build step.
There is also a Session Replay package, mentioned in the description of the reference application, and the experimental/ directory, which is where a package lives before it is ready to be depended on.
The reference application is worth paying attention to, because it is the most efficient way to see the intended configuration. The readme points at grafana/quickpizza as the canonical frontend observability demo, deployed live at quickpizza.grafana-dev.com and instrumented with the current Faro Web SDK, the Web Tracing package and the Session Replay package. A live example on the current release tells you more about the default configuration than any document.
The supported environments table is the useful documentation
The Faro Web SDK instruments web pages that run in a browser. During initialization, the SDK and most of its default instrumentations read browser APIs such as window, document, PerformanceObserver and sessionStorage, and JavaScript that does not run in a typical web page context is outside the supported scope.
The readme then publishes the boundaries as a table, and it is the single most useful piece of documentation in the repository. Web applications that run in a browser are supported. The client side of server-rendered applications, such as Next.js and React SSR, is supported. The server runtime of server-rendered applications is not. Browser extensions are not. Web workers and service workers are not. Node.js, React Native and other non-browser JavaScript environments are not.
The line is drawn by the browser APIs, and that makes the rule easy to apply. If your code has a window and a document, Faro can instrument it. If it does not, the default instrumentations have nothing to attach to.
The extension case is called out separately because it comes up often, and the readme is unusually firm. Some users have made Faro run inside an extension by supplying their own set of instrumentations, but that configuration is unsupported and issues for it are not accepted. That is a good way to state it, because the alternative, a stream of issues from people who did it anyway, helps nobody.
The readme also points to a documentation page with the reasoning behind each row and what to use instead when monitoring a server or a back end, which is the part that turns a limitation into a decision.
What Faro v2 changed, and what it removed
Faro v2 is a modernization release, and the readme lists the changes in a way that is useful to anyone still on v1.
Web Vitals moved to version 5 of the Web Vitals library, to remove the FID metric and for improved performance. That is a breaking change for anyone whose dashboards or alerts mention FID, and it is the kind of change that is easy to miss because the collection still works.
The tracing APIs are cleaner, with redundant and deprecated attributes removed. The console instrumentation configuration was simplified. And the core is leaner, because deprecated packages and legacy internals were removed, which the readme frames as an improvement for stability.
Two separate upgrade guides are linked, an upgrading guide and a v2 upgrade guide, which suggests the path from an early version and the path from v1 are documented as different journeys. That is the right call, because a project that skipped a version has a different set of changes to read than one that upgraded in step.
The release naming section is also precise. Faro follows semantic versioning, and the readme defines each level: major releases include large new features which will significantly change how Faro operates and possible backwards-compatibility breaking changes, minor releases include new features which generally do not break backwards compatibility, and patch releases include bug and security fixes which do not break backwards compatibility.
The stated goal is regular releases that are as stable as possible, with backwards-compatibility taken seriously, and the instruction to always read the release notes and the upgrade guide whenever choosing a new version to install.
The quality gate of a large TypeScript monorepo
The root package.json shows how the project checks itself, and the quality script is the interesting one. It runs five checks in parallel: circular dependency detection, the tests, the type check, the lint, and an end-to-end smoke run in CI. Each has its own script, and the type check is split, with a version check that builds the version information for the core package first, then a per-package type check run through Lerna.
The circular dependency check has a .madgerc at the root, which is the configuration for the tool that finds them. A monorepo of packages that depend on each other will accumulate cycles without meaning to, and a check that fails the build is the only reliable way to stop it.
The TypeScript configuration is layered, with tsconfig.base.json and separate base files for CommonJS, for ES modules, for specs, plus the root spec configuration, which is what lets the packages emit both module formats from one source. The bundler configuration is tsdown.config.base.js. The test runner configuration is jest.config.base.js, and the end-to-end suites live in e2e/ with a smoke harness package that the CI job runs.
Around that, the repository has the standard modern tooling: ESLint in flat config form, Prettier with a cache directory under .cache, husky with lint-staged for commit hooks, a .browserslistrc that defines the browsers the output has to work in, an .nvmrc pinning the Node version for development, and a .markdownlintrc for the documentation. Releases are automated with release-please, configured through release-please-config.json and .release-please-manifest.json, which is how the changelog and the version bumps are produced without a human editing them.
Where the Faro Web SDK is the wrong tool
The first limit is the one the table states, and it is a real one for a lot of front-end code. Anything that is not a browser page is out of scope, which rules out service workers, which are exactly where a performance-conscious team might want to measure the cold start of an offline cache, and it rules out server-side rendering runtimes, which is where the server-rendered part of a Next.js application would want the same instrumentation. The readme points to the supported environments documentation for what to use instead, and the honest answer for those cases is a different SDK.
The second is the receiver. Faro needs somewhere to send its data, and the three options are Alloy, Grafana Cloud or a custom receiver. The first two mean adopting a piece of Grafana infrastructure, and the third means writing and operating a service. There is no mode in which the SDK simply logs to the console and is useful, so a team evaluating it should budget for the receiving side, not only for the browser bundle.
The third is the v2 transition. A project on an early version faces the removal of deprecated packages and of the FID metric, and the readme's own advice to read the release notes and the upgrade guide before choosing a version is the practical instruction. The benefit is a smaller and better performing SDK.
The fourth is that the configuration surface is wide. Instrumentations, metas and transports are all pluggable, and the whole selling point is configurability, which is a virtue until it means that a bug in a production telemetry pipeline is a bug in your configuration rather than in a default. The reference application is the mitigation, and it is a mitigation that requires you to look at somebody else's configuration rather than at a documented default.
The fifth is the ecosystem alignment. The SDK is built and released by the same organisation that builds Alloy, Loki and Tempo, and while the custom receiver option keeps the data path open, the instrumentation vocabulary is Grafana's. A team that has chosen a different tracing backend will find the correlation story weaker than the readme implies.
Editorial conclusion
Faro fits a team running a browser application that already has a Grafana stack, or that wants front-end telemetry in the same place as back-end traces, and the package split means you can take the core and the React binding without the rest. It does not fit a Node service, a service worker, a browser extension or a server-rendered runtime, and the readme is explicit that extension use is unsupported and that issues for it are not accepted. Before adopting it, read the supported environments table rather than the feature list, decide whether you can run a receiver in the path, since Alloy, Grafana Cloud or a custom receiver all have to be somewhere, and read the v2 upgrade guide, because Web Vitals v5 removes the FID metric and the deprecated packages are gone. The licence is Apache-2.0, version 2.12.1 was published on 2026-09-22, and the last push was on 2026-10-15.
Frequently asked questions
Can Faro instrument a web worker or a service worker?
No. The supported environments table lists web workers and service workers as not supported, along with browser extensions, Node.js, React Native and the server runtime of server-rendered applications. The rule is that the SDK reads browser APIs such as window, document and PerformanceObserver during initialization.
Where can Faro send its telemetry?
To Grafana Alloy with the faro receiver integration enabled, to a Grafana Cloud instance, or to a custom receiver you write. Alloy can then forward the data to Loki or to Tempo, which is how front-end telemetry gets correlated with back-end and infrastructure data.
What changed in Faro v2?
Web Vitals moved to version 5 with the FID metric removed, the tracing APIs lost redundant and deprecated attributes, the console instrumentation configuration was simplified, and deprecated packages and legacy internals were removed from the core. Separate upgrading and v2 upgrade guides are published.
How do I develop the Faro Web SDK locally?
The readme documents three supported paths: the in-repo smoke harness, your own Grafana Cloud free-tier stack, or a local Alloy install. The repository also publishes a live reference application, grafana/quickpizza, instrumented with the current SDK, Web Tracing and Session Replay.
Which Node versions does the Faro build support?
All active LTS and current Node versions, and versions are removed from the test matrix when they reach end of life. That section is about the versions used to build, test and publish the SDK, since Node.js is not a runtime the SDK itself supports.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/grafana-faro-web-sdk)Was this useful?