AgentPrism: React Components for Rendering Agent Traces as Timelines
React components for visualizing traces from AI agents
At a glance
- What is it?
- AgentPrism is an MIT-licensed React component library from Evil Martians that turns OpenTelemetry and Langfuse span data into a hierarchical trace timeline. It is an alpha-stage UI layer, not a tracing backend, and it ships as copied source rather than an npm UI package.
- Who is it for?
- Adopt AgentPrism if you already emit OTLP or Langfuse data and want a trace timeline inside an existing React 19 and Tailwind 3 app, and you accept copying component source into your own tree because the README marks the release alpha and warns that APIs may change. Skip it if you need a hosted backend, a stable versioned UI package, or anything other than React, since the prerequisites rule out other frameworks.
- Can I use it commercially?
- Yes. MIT 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 50 days ago.
- What is it written in?
- Mainly TypeScript, 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 JSON problem AgentPrism actually targets
Agent traces are rich and unreadable at the same time. The README states the case plainly: a trace contains "perfect information about an agent's behavior with every plan, action, and retry," but that information "gets lost in a sea of JSON." The target reader is an engineer who already has trace data in hand and needs to look at it. AgentPrism does not collect traces, store them, or ship a server. It is the last mile, the rendering layer that sits between an OTLP or Langfuse payload and a person trying to work out why an agent looped or which tool call consumed the tokens. That narrow scope matters when you evaluate it. If your problem is that you have no traces at all, this library has nothing to offer you yet.
What TraceViewer renders and how spans reach it
The data flow is adapter-first. Raw documents go into an adapter, normalized objects come out, and components render those objects. The README gives the shape explicitly: TraceViewer takes an array of records, each with a traceRecord field and a spans array, where spans are produced by openTelemetrySpanAdapter.convertRawDocumentsToSpans(yourTraceData). The interface is named TraceViewerData, and it also accepts an optional badges array of BadgeProps. The full TraceViewer bundles four pieces: a trace list for browsing multiple traces, a tree view for hierarchical spans with search and expand and collapse, a details panel for individual span attributes, and a responsive layout for desktop and mobile. If you want a different arrangement, the components are exported individually. The custom layout example wires TraceList, TreeView and DetailsView together with three pieces of React state: selectedTrace, selectedSpan and expandedSpansIds. That is the whole architecture. There is no context provider, no store, no data fetching layer. You own the state, and the library renders it.
Adapters normalize OpenTelemetry and Langfuse into one shape
Two adapters ship in @evilmartians/agent-prism-data: openTelemetrySpanAdapter and langfuseSpanAdapter. Both implement the same interface, which is what lets the same TreeView render either source. The OpenTelemetry adapter exposes convertRawDocumentsToSpans for whole documents, convertRawSpanToTraceSpan for a single span, and convertRawSpansToSpanTree when you only need the tree component. The Langfuse adapter takes a different tack and offers per-field getters: getSpanCategory, getSpanCost, getSpanDuration, getSpanInputOutput, getSpanStatus and getSpanTokensCount, each taking observation data. The README notes these apply "e.g. when you loaded one record," which suggests the Langfuse path is built for detail views rather than bulk conversion. On attribute recognition, the supported list names OpenTelemetry GenAI conventions under gen_ai.* for model, tokens and costs, OpenInference conventions under llm.* and retrieval.*, and "Standard OTEL" where the README text is truncated. Treat that last item as unconfirmed. If your spans use custom attribute names, the adapter has no documented mapping hook, so expect to write your own conversion into TraceSpan.
Install is a copy step, not an npm install
This is the detail that surprises people. The UI components are not published as a package. The README instructs you to copy them into your own source tree with npx degit evilmartians/agent-prism/packages/ui/src/components src/components/agent-prism. The data and types packages are separate installs: npm install @evilmartians/agent-prism-data @evilmartians/agent-prism-types. Then the peer UI dependencies: @radix-ui/react-collapsible, @radix-ui/react-tabs, classnames, lucide-react, react-json-pretty and react-resizable-panels. Prerequisites are React 19 or later, Tailwind CSS 3, and TypeScript. The degit approach means you get the source, you can edit it, and upstream fixes will not reach you through a version bump. That is a deliberate trade for a young library, but it shifts upgrade work onto you. The imports in the examples are relative paths into your copied folder, such as ./components/agent-prism/TraceViewer, which confirms the components are yours once copied.
Alpha status, Tailwind coupling and the missing backend
The README carries a bolded warning: "Alpha Release: This library is under active development. APIs may change." Combined with the copy-in install, that means every upstream change is a manual diff against your own edited files. The Tailwind CSS 3 requirement is a harder constraint than it looks. Your app must already run Tailwind 3, and the copied components bring their own class names into your build, so class collisions and purge configuration become your problem. React 19 is a floor, not a preference. The bigger limitation is scope: there is no backend here. No ingestion endpoint, no database, no query API, no alerting. You must already have OTLP or Langfuse data reachable from the browser or passed down as props. For a team with no tracing pipeline, AgentPrism is the wrong first purchase, because there is nothing to render. The README also does not document performance behaviour on very large traces, so the practical span ceiling is unverified from the supplied material.
Against a general trace UI such as Jaeger
The obvious comparison is a general-purpose trace viewer like Jaeger's UI. The difference is the data model. Jaeger's UI renders generic spans and assumes you will read service names and durations. AgentPrism normalizes specifically for agent semantics, which is why the supported attribute list names gen_ai.*, llm.* and retrieval.* and why the Langfuse adapter has getSpanCost and getSpanTokensCount as first-class methods. Cost and token counts are not standard span fields in a generic viewer. The second difference is embedding. Jaeger is a deployed service you link to. AgentPrism is React components you place inside your own product, next to the run that produced the trace. If you need one place to inspect everything across services, a general viewer wins. If you need the trace to appear inside the agent's own debugging screen, with your routing and your state, that is what this library is for. The two are not mutually exclusive, and nothing in the README suggests AgentPrism replaces a tracing backend.
Maintenance cost and the MIT licence
AgentPrism is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive baseline, and it is compatible with the copy-in distribution model the README describes. The practical maintenance cost sits in three places. The copied components are a fork in all but name, so upstream changes arrive as diffs you apply by hand. The alpha warning means those diffs may include breaking prop changes to TraceViewerData, TraceRecord or TraceSpan. The peer dependency set, Radix primitives plus Tailwind 3 plus React 19, pins your upgrade path for those libraries too. None of this is unusual for a young component library, but budget for it. This is a description of the licence terms as stated, not legal advice; check the LICENSE file in the repository for the authoritative text.
Who should pick this up, and what to check first
Pick AgentPrism up if you already emit OTLP or Langfuse traces, your frontend is React 19 with Tailwind 3, and you want the timeline inside your own app rather than in a separate tab. The Storybook at storybook.agent-prism.evilmartians.io and the live demo at agent-prism.evilmartians.io are the fastest way to judge whether the tree view and details panel match how you read traces. Before adopting, do three concrete things. Confirm your spans carry the gen_ai.*, llm.* or retrieval.* attributes the README lists, because the adapter has no documented fallback for custom names. Run the degit command into a scratch directory and read TraceViewer's props against your own data shape. And check whether your team can absorb a copied-source dependency, since that decision, not the component quality, is what determines the long-term cost here. If any of those three checks fails, wait for a versioned release.
Editorial conclusion
Adopt AgentPrism if you already emit OTLP or Langfuse data and want a trace timeline inside an existing React 19 and Tailwind 3 app, and you accept copying component source into your own tree because the README marks the release alpha and warns that APIs may change. Skip it if you need a hosted backend, a stable versioned UI package, or anything other than React, since the prerequisites rule out other frameworks. Verify first that the OTLP documents you produce carry the gen_ai.*, llm.* or retrieval.* attributes the supported-attribute list names, then run the degit command into a scratch directory and read the TraceViewer props before committing to the layout.
Community notes