Langfuse JS/TS SDKs
    Preparing search index...

    Module @langfuse/tracing

    GitHub Banner

    @langfuse/tracing

    Langfuse is the open-source LLM engineering platform: tracing & evaluation for LLM and agent applications, prompt management, datasets & experiments, and evaluation (scores). This package provides the tracing instrumentation primitives of the Langfuse JS SDK, built on OpenTelemetry: startObservation, startActiveObservation, the observe() wrapper, and propagateAttributes for user/session attribution and prompt linking. It pairs with the LangfuseSpanProcessor from @langfuse/otel, which exports the spans to Langfuse. Prompt management, datasets/experiments, evals/scores, and the full REST API live in @langfuse/client.

    Important

    This is the current SDK generation (@langfuse/* scoped packages). The unscoped langfuse npm package is the legacy v3 SDK β€” for new integrations use @langfuse/tracing + @langfuse/otel. Migration guides: v3 β†’ v4, v4 β†’ v5.

    npm install @langfuse/tracing @langfuse/otel @opentelemetry/sdk-trace-node
    
    LANGFUSE_PUBLIC_KEY="pk-lf-..."
    LANGFUSE_SECRET_KEY="sk-lf-..."
    LANGFUSE_BASE_URL="https://cloud.langfuse.com" # πŸ‡ͺπŸ‡Ί EU region. πŸ‡ΊπŸ‡Έ US: https://us.cloud.langfuse.com

    The most common setup: trace streamText / generateText calls in a Next.js app, with user and session attribution, and reliable span delivery on serverless.

    1. Register the span processor in instrumentation.ts:

    // instrumentation.ts (project root)
    import { LangfuseSpanProcessor } from "@langfuse/otel";
    import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";

    // Exported so route handlers can flush it before the serverless
    // function is frozen or terminated.
    export const langfuseSpanProcessor = new LangfuseSpanProcessor();

    export function register() {
    const tracerProvider = new NodeTracerProvider({
    spanProcessors: [langfuseSpanProcessor],
    });

    tracerProvider.register();
    }

    2. Trace the route handler with user/session attribution:

    // app/api/chat/route.ts
    import { openai } from "@ai-sdk/openai";
    import {
    observe,
    propagateAttributes,
    updateActiveObservation,
    } from "@langfuse/tracing";
    import { trace } from "@opentelemetry/api";
    import { streamText, type UIMessage } from "ai";
    import { after } from "next/server";

    import { langfuseSpanProcessor } from "@/instrumentation";

    const handler = async (req: Request) => {
    const {
    messages,
    chatId,
    userId,
    }: { messages: UIMessage[]; chatId: string; userId: string } =
    await req.json();

    updateActiveObservation({ input: messages });

    // userId / sessionId / tags / metadata set here are applied to every
    // span created inside the callback β€” call this as early as possible.
    return propagateAttributes(
    { traceName: "chat-message", userId, sessionId: chatId },
    async () => {
    const result = streamText({
    model: openai("gpt-5.1"),
    messages,
    // AI SDK ≀ 6 only: experimental_telemetry: { isEnabled: true },
    onFinish: async (result) => {
    updateActiveObservation({ output: result.content });
    // End the root observation once the stream has finished
    trace.getActiveSpan()?.end();
    },
    onError: async (error) => {
    updateActiveObservation({ output: error });
    trace.getActiveSpan()?.end();
    },
    });

    // Critical on serverless: export spans before the function freezes
    after(async () => await langfuseSpanProcessor.forceFlush());

    return result.toUIMessageStreamResponse();
    },
    );
    };

    // observe() wraps the handler in a root observation
    export const POST = observe(handler, {
    name: "handle-chat-message",
    endOnExit: false, // ended manually in onFinish after the stream completes
    });

    See the full guide at https://langfuse.com/integrations/frameworks/vercel-ai-sdk.

    import { startActiveObservation, startObservation } from "@langfuse/tracing";

    await startActiveObservation("user-request", async (span) => {
    span.update({ input: { query: "What is Langfuse?" } });

    // Nested observation, e.g. an LLM call, typed as a generation
    const generation = startObservation(
    "llm-call",
    {
    model: "gpt-5.1",
    input: [{ role: "user", content: "What is Langfuse?" }],
    },
    { asType: "generation" },
    );
    // ... call your LLM ...
    generation.update({
    output: { role: "assistant", content: "..." },
    usageDetails: { input: 12, output: 156 },
    });
    generation.end();

    span.update({ output: "done" });
    });

    Key exports:

    • startObservation / startActiveObservation β€” create spans, generations, agents, tools, and other observation types
    • observe() β€” wrap any existing function with tracing
    • propagateAttributes() β€” set userId, sessionId, environment, tags, metadata, version, and prompt links on all spans created within a callback
    • createTraceId() β€” deterministic trace IDs for correlating external IDs
    • updateActiveObservation, getActiveTraceId, setActiveTraceAsPublic
    1. Consider new LangfuseSpanProcessor({ exportMode: "immediate" }) so spans are not held in a batch.
    2. Always await langfuseSpanProcessor.forceFlush() before the function instance is frozen (e.g. Vercel after(), waitUntil()).
    3. For streaming responses, end the root observation in onFinish (see the recipe above) so it is included in the flush.
    Package NPM Description Environments
    @langfuse/tracing NPM OpenTelemetry-based tracing instrumentation Node.js 20+
    @langfuse/otel NPM LangfuseSpanProcessor to export OpenTelemetry spans to Langfuse Node.js 20+
    @langfuse/client NPM Prompt management, datasets, experiments, scores, full REST API Universal JS
    @langfuse/openai NPM observeOpenAI wrapper for tracing the OpenAI SDK Universal JS
    @langfuse/langchain NPM CallbackHandler for LangChain / LangGraph tracing Universal JS
    @langfuse/vercel-ai-sdk NPM Telemetry integration for Vercel AI SDK v7 Universal JS
    @langfuse/browser NPM Browser score ingestion with public-key auth Browser
    @langfuse/core NPM Shared core: generated API client, logger, utilities Universal JS

    MIT

    Enumerations

    LangfuseOtelSpanAttributes

    Classes

    LangfuseAgent
    LangfuseChain
    LangfuseEmbedding
    LangfuseEvaluator
    LangfuseEvent
    LangfuseGeneration
    LangfuseGuardrail
    LangfuseRetriever
    LangfuseSpan
    LangfuseTool

    Interfaces

    ObserveOptions
    PropagateAttributesParams

    Type Aliases

    LangfuseEventAttributes
    LangfuseGenerationAttributes
    LangfuseObservation
    LangfuseObservationAttributes
    LangfuseObservationType
    LangfuseSpanAttributes
    LangfuseTraceAttributes
    ObservationLevel
    PropagatedPromptInput
    StartActiveObservationContext
    StartActiveObservationOpts
    StartObservationOptions
    StartObservationOpts

    Functions

    createObservationAttributes
    createTraceAttributes
    createTraceId
    getActiveSpanId
    getActiveTraceId
    getLangfuseTracer
    getLangfuseTracerProvider
    observe
    propagateAttributes
    setActiveTraceAsPublic
    setActiveTraceIO
    setLangfuseTracerProvider
    startActiveObservation
    startObservation
    updateActiveObservation