Create a minimal working Langfuse trace example.
Use when starting a new Langfuse integration, testing your setup,
or learning basic Langfuse tracing patterns.
Trigger with phrases like "langfuse hello world", "langfuse example",
"langfuse quick start", "first langfuse trace", "simple langfuse code".
Create your first Langfuse trace with real SDK calls. Demonstrates the trace/span/generation hierarchy, the observe wrapper, and the OpenAI drop-in integration.
Prerequisites
Completed langfuse-install-auth setup
Valid API credentials in environment variables
OpenAI API key (for the OpenAI integration example)
Instructions
Step 1: Hello World with v4+ Modular SDK
// hello-langfuse.ts
import { startActiveObservation, observe, updateActiveObservation } from "@langfuse/tracing";
import { LangfuseSpanProcessor } from "@langfuse/otel";
import { NodeSDK } from "@opentelemetry/sdk-node";
// Register OpenTelemetry processor (once at startup)
const sdk = new NodeSDK({
spanProcessors: [new LangfuseSpanProcessor()],
});
sdk.start();
async function main() {
// Create a top-level trace with startActiveObservation
await startActiveObservation("hello-world", async (span) => {
span.update({
input: { message: "Hello, Langfuse!" },
metadata: { source: "hello-world-example" },
});
// Nested span -- automatically linked to parent
await startActiveObservation("process-input", async (child) => {
child.update({ input: { text: "processing..." } });
await new Promise((r) => setTimeout(r, 100));
child.update({ output: { result: "done" } });
});
// Nested generation (LLM call tracking)
await startActiveObservation(
{ name: "llm-response", asType: "generation" },
async (gen) => {
gen.update({
model: "gpt-4o",
input: [{ role: "user", content: "Say hello" }],
output: { content: "Hello! How can I help you today?" },
usage: { promptTokens: 5, completionTokens: 10, totalTokens: 15 },
});
}
);
span.update({ output: { status: "completed" } });
});
// Allow time for the span processor to flush
await sdk.shutdown();
console.log("Trace created! Check your Langfuse dashboard.");
}
main().catch(console.error);
Step 2: Hello World with observe Wrapper
The observe wrapper traces existing functions without modifying internals:
import { observe, updateActiveObservation } from "@langfuse/tracing";
// Wrap any async function -- it becomes a traced span
const processQuery = observe(async (query: string) => {
updateActiveObservation({ input: { query } });
// Simulate processing
const result = `Processed: ${query}`;
updateActiveObservation({ output: { result } });
return result;
});
// Wrap an LLM call as a generation
const generateAnswer = observe(
{ name: "generate-answer", asType: "generation" },
async (prompt: string) => {
updateActiveObservation({
model: "gpt-4o",
input: [{ role: "user", content: prompt }],
});
const answer = "Langfuse is an open-source LLM observability platform.";
updateActiveObservation({
output: answer,
usage: { promptTokens: 10, completionTokens: 20 },
});
return answer;
}
);
// Both functions auto-nest when called within an observed context
const pipeline = observe(async () => {
await processQuery("What is Langfuse?");
await generateAnswer("Explain Langfuse in one sentence.");
});
await pipeline();