---
title: 'Full-stack tracing: Javascript observability with Pydantic Logfire'
description: >-
  Bridge the gap between your Python backend and JavaScript frontend with
  Logfire's JavaScript SDK for complete distributed tracing
date: '2026-01-14'
authors:
  - Petyo Ivanov
categories:
  - Pydantic Logfire
  - JavaScript
canonical: 'https://pydantic.dev/articles/javascript-observability'
---

> Markdown version of [Full-stack tracing: Javascript observability with Pydantic Logfire](https://pydantic.dev/articles/javascript-observability) — the canonical HTML page.
>
> By [Petyo Ivanov](https://pydantic.dev/authors/petyo-ivanov.md) · 2026-01-14 · Pydantic Logfire, JavaScript
>
> Related: [You've built this agent before](https://pydantic.dev/articles/harness-week.md) · [Your traces already know how to fix your prompt](https://pydantic.dev/articles/logfire-prompt-optimization.md)
>
> All articles: [/articles.md](https://pydantic.dev/articles.md) · Site index: [/llms.txt](https://pydantic.dev/llms.txt)

---

# Full-stack tracing: Javascript observability with Pydantic Logfire

You've instrumented your Python backend with Logfire. You can see every FastAPI request, every database query, every external API call. But what happens _before_ that request arrives? What did the user click? How long did they wait? What was the state of the application when things went wrong?

If your application has a JavaScript frontend—and statistically, it almost certainly does—there's a whole layer of your stack you're not seeing.

## JavaScript is Everywhere

JavaScript powers 98.9% of websites on the client side. Even teams that are Python-first typically have JavaScript somewhere in their stack: a React dashboard, a Next.js marketing site, an admin panel built with Vue.

But it's not just browsers. JavaScript runs in:

- **Node.js backends** — over 4.6 million websites use Node.js server-side
- **Edge functions** — Cloudflare Workers, Vercel Edge Functions, Deno Deploy
- **Desktop apps** — Electron powers VS Code, Slack, Discord
- **Mobile apps** — React Native brings JavaScript to iOS and Android

And increasingly, these JavaScript layers serve as the interface to Python backends—the dominant choice for AI and machine learning workloads. Your React dashboard calls your PydanticAI-powered API. Your Next.js app talks to your FastAPI inference service. The user experience lives in JavaScript; the intelligence lives in Python.

For Python developers building modern AI-powered applications, JavaScript observability isn't optional—it's the missing piece of the puzzle.

## Why Client-Side Observability Matters

Backend monitoring tells you what happened on your servers. But [Google's research](https://www.thinkwithgoogle.com/consumer-insights/consumer-trends/mobile-site-load-time-statistics/) shows that 53% of mobile users abandon sites that take longer than 3 seconds to load, and [case studies](https://web.dev/case-studies/vitals-business-impact) from companies like Vodafone and Lazada demonstrate that even modest performance improvements lead to measurable revenue gains. These problems often originate in the browser, not the backend.

### See the Full User Journey

When a user reports "the app is slow," backend metrics might show normal response times. But what if the slowness is in the browser? Maybe a heavy JavaScript bundle is blocking rendering. Maybe a third-party script is competing for resources. Maybe the user's interaction triggers multiple redundant API calls.

With client-side observability, you see document load times, user interactions, network requests, and how they all connect to your backend traces.

### Debug Issues You Couldn't See or Reason About Before

Here's a real example: we were receiving malformed payloads on a certain API endpoint. The backend validation was rejecting them, but we couldn't figure out why users were sending bad data. Only after instrumenting the client-side code path did we discover that a certain account was producing OTel traces with multiple root-level spans, resulting in a miscalculated payload that was far removed from the actual endpoint call. Detecting and fixing this issue would have been impossible without full-stack tracing.

### Same API, Same Mental Model

If you already know Logfire in Python, you already know it in JavaScript:

```python
# Python
logfire.info('User {user_id} logged in', user_id=123)
```

```javascript
// JavaScript - same pattern
logfire.info('User {user_id} logged in', { user_id: 123 })
```

Message templates, log levels, spans—they all work the same way. The concepts you've learned transfer directly.

## How It Works

Pydantic Logfire provides [JavaScript SDKs](https://pydantic.dev/docs/logfire/typescript-sdk/?utm_date=20260114%253Futm_source=javascript-blogpopst%253Futm_author=petyo) for different runtime environments:

- **Node.js** — Full auto-instrumentation for HTTP, databases, and web frameworks
- **Browser** — Automatic tracing of fetch requests, page loads, and user interactions
- **Cloudflare Workers** — Edge function instrumentation

### Auto-Instrumentation Does the Heavy Lifting

Just like `logfire.instrument_fastapi()` in Python, the JavaScript SDKs automatically instrument common libraries. Under the hood, Logfire uses [OpenTelemetry's auto-instrumentation](https://opentelemetry.io/docs/languages/js/libraries/) packages, which support 30+ libraries out of the box: web frameworks like Express, Fastify, Koa, Hapi, and NestJS; databases including PostgreSQL, MySQL, MongoDB, and Redis; plus GraphQL, gRPC, Kafka, and the AWS SDK. In the browser, every `fetch()` call and page load is captured automatically.

You focus on instrumenting your business logic. The plumbing is handled for you.

### Browser Security: The Proxy Pattern

There's one important difference for browser instrumentation: you can't put your Logfire token in client-side code—it would be visible to anyone who opens DevTools. Instead, browser traces are sent to your own backend, which forwards them to Logfire with the token attached server-side.

It's a simple pattern, and the [documentation](https://pydantic.dev/docs/logfire/typescript-sdk/?utm_date=20260114%253Futm_source=javascript-blogpopst%253Futm_author=petyo) walks through the setup for Express, Next.js, and other frameworks.

### Distributed Tracing: The Complete Picture

This is where JavaScript observability really shines. When a user clicks a button in your React app, that click triggers a `fetch()` call. The browser SDK automatically attaches a trace context header to the request. Your Python backend receives that header and continues the same trace.

The result? A single trace that shows:

```
[Browser] Button click
    └── [Browser] fetch /api/orders
            └── [Python] POST /api/orders
                    └── [Python] SELECT * FROM orders
                    └── [Python] Redis cache lookup
```

You see the complete journey from user action to database query, with timing at every step. When something is slow, you know exactly where.

<iframe
  title="Distributed trace in Pydantic Logfire"
  width="100%"
  height="600"
  src="https://logfire-eu.pydantic.dev/public-trace/7579d7fd-89df-4753-b2d4-d1039a039f71?spanId=2da4ba76c46a366f&embedded=true&theme=light">
</iframe>


This is how distributed client-to-server traces from the [nextjs example](https://github.com/pydantic/logfire-js/tree/main/examples/nextjs-client-side-instrumentation?utm_date=20260114?utm_source=javascript-blogpopst?utm_author=petyo) appears in the Logfire UI. You can interact with the example above by clicking on the spans.

## Tips for Effective JavaScript Observability

### Use Logfire During Development

Enable console output locally (`console: true` in the configuration) to see your traces in the terminal as you develop. It's a fast feedback loop that helps you understand what's being captured before you deploy. Keeping Logfire's live view on your second monitor is also a great way to spot issues early.

### Let Auto-Instrumentation Handle the Basics

Don't manually instrument every HTTP call—that's already covered. Focus your manual spans on business-critical paths: checkout flows, authentication steps, data synchronization. Instrument the code where bugs would be most painful.

### Track What Users Actually Experience

The metrics that matter are the ones users feel:

- **Page load time** — How long until the page is interactive?
- **Interaction latency** — How long between click and response?
- **API timing from the browser** — Not server processing time, but the full round-trip including network latency

### Leverage Familiar Patterns

Everything you know from Python Logfire applies:

- Message templates extract attributes automatically
- Sensitive data scrubbing is built-in (passwords, tokens, API keys)
- Log levels work the same way (`trace`, `debug`, `info`, `warn`, `error`)

## Getting Started

The Logfire JavaScript SDK is open source and available on npm. Setup takes just a few minutes:

1. **Read the docs**: [JavaScript integration](https://pydantic.dev/docs/logfire/typescript-sdk/?utm_date=20260114%253Futm_source=javascript-blogpopst%253Futm_author=petyo)
2. **Explore the examples**: [Express](https://github.com/pydantic/logfire-js/tree/main/examples/express), [Next.js](https://github.com/pydantic/logfire-js/tree/main/examples/nextjs), [browser](https://github.com/pydantic/logfire-js/tree/main/examples/browser), and [Cloudflare Workers](https://github.com/pydantic/logfire-js/tree/main/examples/cf-worker) examples in the [GitHub repository](https://github.com/pydantic/logfire-js?utm_date=20260114?utm_source=javascript-blogpopst?utm_author=petyo)
3. **Try it free**: If you're not already using Logfire, [sign up](https://logfire.pydantic.dev/?utm_date=20260114?utm_source=javascript-blogpopst?utm_author=petyo) and get started

Full-stack observability means seeing your entire application—Python backend and JavaScript frontend—in one place, with traces that flow seamlessly between them. No more blind spots. No more guessing what happened in the browser.


<script type="application/ld+json">
	{
	  "@context": "https://schema.org",
	  "@graph": [
		{
		  "@type": "BlogPosting",
		  "mainEntityOfPage": {
			"@type": "WebPage",
			"@id": "https://pydantic.dev/articles/javascript-observability"
		  },
		  "headline": "Full-stack tracing: Javascript observability with Pydantic Logfire",
		  "description": "Bridge the gap between your Python backend and JavaScript frontend with Logfire's JavaScript SDK for complete distributed tracing.",
		  "keywords": "JavaScript, Pydantic Logfire, Observability, Full-Stack, Distributed Tracing, Python",
		  "image": {
			"@type": "ImageObject",
			"url": "https://pydantic.dev/assets/blog/js-observability/distributed-trace.png"
		  },
		  "author": {
			"@type": "Person",
			"name": "Petyo Ivanov"
		  },
		  "datePublished": "2026-01-14T09:00:00.000Z",
		  "publisher": {
			"@type": "Organization",
			"name": "Pydantic",
			"url": "https://pydantic.dev/",
			"logo": {
			  "@type": "ImageObject",
			  "url": "https://pydantic.dev/logo.png"
			}
		  },
		  "about": [
			{
			  "@type": "Thing",
			  "name": "Observability",
			  "sameAs": "https://en.wikipedia.org/wiki/Observability_(software)"
			},
			{
			  "@type": "Thing",
			  "name": "Distributed Tracing",
			  "sameAs": "https://en.wikipedia.org/wiki/Distributed_tracing"
			}
		  ]
		},
		{
		  "@type": "FAQPage",
		  "mainEntity": [
			{
			  "@type": "Question",
			  "name": "What is full-stack observability?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "Full-stack observability means monitoring both your frontend (JavaScript/browser) and backend (Python/Node.js) in a unified view. With Pydantic Logfire, distributed traces flow seamlessly from user clicks in the browser through API calls to database queries, giving you complete visibility into application performance."
			  }
			},
			{
			  "@type": "Question",
			  "name": "How do I trace JavaScript requests to my Python backend?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "Pydantic Logfire automatically attaches trace context headers to fetch() requests from the browser. Your Python backend receives these headers and continues the same trace, creating a single unified view from user action to database query. No manual header propagation required."
			  }
			},
			{
			  "@type": "Question",
			  "name": "Is it safe to use Logfire in browser JavaScript?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "Yes. Browser traces are sent to your own backend proxy, which forwards them to Logfire with your token attached server-side. Your Logfire token never appears in client-side code, keeping it secure from exposure in DevTools."
			  }
			},
			{
			  "@type": "Question",
			  "name": "What JavaScript frameworks does Logfire support?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "Logfire provides SDKs for Node.js, browsers, and Cloudflare Workers. Auto-instrumentation covers 30+ libraries including Express, Fastify, Next.js, NestJS, PostgreSQL, MongoDB, Redis, and GraphQL. Browser instrumentation automatically captures fetch requests, page loads, and user interactions."
			  }
			},
			{
			  "@type": "Question",
			  "name": "Do I need to manually instrument every API call?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "No. Logfire's auto-instrumentation automatically captures HTTP calls, database queries, and common framework operations. You only need to add manual spans for business-critical paths like checkout flows or authentication steps where detailed tracing adds the most value."
			  }
			},
			{
			  "@type": "Question",
			  "name": "Why do I need client-side observability if I already monitor my backend?",
			  "acceptedAnswer": {
				"@type": "Answer",
				"text": "Backend metrics can show normal response times while users experience slowness. Client-side issues like heavy JavaScript bundles, third-party script interference, or redundant API calls are invisible without browser instrumentation. Google research shows 53% of mobile users abandon sites taking over 3 seconds to load—problems often originating in the browser."
			  }
			}
		  ]
		}
	  ]
	}
</script>
