
Product
Microsoft Teams Notifications Are Now Available in Socket
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.
Embeddable workbench for LangGraph Agent apps — edit, run, debug, and monitor in one place
Embeddable workbench for LangGraph Agent applications — design topology on canvas, implement logic in code, compile into executable graphs.
| LangGraph Studio (official) | Linforge |
|---|---|
| Desktop app | Web-embeddable — integrates into your product UI |
| Code-only graph definition | Visual canvas + code hybrid |
| Dev-only tool | Product managers sketch graphs, developers implement nodes |
| Dev-time debugging | Built-in run history, step replay, and prompt versioning |
npm install linforge
# or
pnpm add linforge
Peer dependencies (install only what you need):
# Server
pnpm add koa @koa/router
# UI
pnpm add react react-dom @xyflow/react
A minimal server in ~30 lines:
import Koa from 'koa';
import cors from '@koa/cors';
import bodyParser from 'koa-bodyparser';
import { StateSchema } from '@langchain/langgraph';
import { z } from 'zod/v4';
import { defineNodeFor } from 'linforge/core';
import { linforgeMiddleware } from 'linforge/server';
// 1. Define state
const MyState = new StateSchema({
messages: z.array(z.string()).default([]),
result: z.string().default(''),
});
// 2. Define nodes — state type is inferred automatically
const defineMyNode = defineNodeFor(MyState);
const greeter = defineMyNode({
key: 'greeter',
label: 'Greeter',
run: async (state) => ({
messages: [...state.messages, '[greeter] Hello!'],
result: 'Greeting complete.',
}),
});
// 3. Start server
const app = new Koa();
app.use(cors());
app.use(bodyParser());
app.use(linforgeMiddleware({
stateSchema: MyState,
nodes: [greeter],
}));
app.listen(3001);
This gives you a full REST API at http://localhost:3001/linforge — graph CRUD, run execution, step recording, and prompt management.
linforge Re-exports all submodules
linforge/core defineNode, Registry, Compiler, RunManager, Store interfaces
linforge/server Koa HTTP API (linforgeMiddleware + mountRoutes)
linforge/react React hooks for graph editing, runs, and prompts
linforge/testing In-memory Store implementations (dev/test)
Code Layer: Node implementations + StateSchema + Route predicates [developer]
Visual Layer: Topology + Wiring + Prompts + Parameters [canvas / DB]
Auto Layer: Compiler merges both into a LangGraph Runnable [linforge]
Create node implementations with defineNode() or the type-safe defineNodeFor():
import { defineNodeFor } from 'linforge/core';
const defineMyNode = defineNodeFor(MyState);
const planner = defineMyNode({
key: 'planner',
run: async (state) => ({
plan: 'Step 1: fetch. Step 2: analyze.',
}),
// Optional: conditional routing
routes: {
has_plan: (state) => !!state.plan,
},
});
Four database-agnostic interfaces — implement them to plug in any database:
| Interface | Purpose |
|---|---|
GraphStore | Graph definition CRUD |
RunStore | Run record lifecycle |
StepPersister | Step data write/query |
PromptStore | Prompt version management |
Linforge ships in-memory implementations (linforge/testing) for development. For production, use an adapter package (e.g., linforge-adapter-prisma) or implement the interfaces yourself.
One-line setup that auto-creates all internal components:
// Single-agent mode (backward compatible)
app.use(linforgeMiddleware({
stateSchema: MyState, // required — LangGraph StateSchema
nodes: [planner, tools], // required — node definitions
prefix: '/linforge', // default: "/linforge"
stores: { // optional — custom Store implementations
graphStore,
runStore,
stepPersister,
promptStore,
},
}));
Bind distinct stateSchema and nodes per Agent:
app.use(linforgeMiddleware({
agents: [
{ slug: 'qa-bot', name: 'QA Bot', stateSchema: QAState, nodes: [retriever, answerer] },
{ slug: 'coder', name: 'Coder', stateSchema: CoderState, nodes: [planner, coder] },
],
sharedNodes: [logger], // available to all agents
}));
Each agent gets its own NodeRegistry and GraphCompiler. Routes resolve context by slug. The middleware auto-creates empty graph definitions in GraphStore on first request (code-first mode).
| Option | Type | Default | Description |
|---|---|---|---|
agents | AgentConfig[] | — | Multi-agent config (mutually exclusive with stateSchema/nodes) |
sharedNodes | NodeDefinition[] | [] | Common nodes registered to every agent |
stateSchema | StateSchema | — | Single-agent: LangGraph StateSchema |
nodes | NodeDefinition[] | — | Single-agent: node definitions |
For full control over component creation. See examples/full-stack/ for a complete example.
All endpoints are prefixed with /linforge by default.
| Method | Path | Description |
|---|---|---|
| GET | /graphs | List graphs |
| POST | /graphs | Create graph |
| PATCH | /graphs/:slug | Update graph metadata |
| GET | /graph/:slug | Get graph definition |
| PUT | /graph/:slug | Save graph definition |
| POST | /graph/:slug/run | Trigger a run |
| GET | /graph/:slug/runs | List run history |
| GET | /runs/:runId | Get run details |
| GET | /runs/:runId/steps | List steps for a run |
| GET | /registry/nodes | List registered nodes |
| GET | /prompts/:nodeId | List prompt versions |
| GET | /prompts/:nodeId/active | Get active prompt |
| POST | /prompts/:nodeId | Create prompt version |
| POST | /prompts/:nodeId/versions/:id/activate | Activate prompt version |
| GET | /templates | List available templates |
| POST | /graph/:slug/apply-template | Apply template to graph |
Optional stores (runStore, stepPersister, promptStore) return 501 when not provided.
import {
useLinforgeGraph,
useLinforgeGraphList,
useLinforgeRuns,
useLinforgePrompt,
} from 'linforge/react';
| Hook | Purpose |
|---|---|
useLinforgeGraph | Graph editing (nodes, edges, save) |
useLinforgeGraphList | Graph list CRUD |
useLinforgeRuns | Run management (trigger, list, detail) |
useLinforgePrompt | Prompt version management |
Implement the four interfaces to connect any database:
import type { GraphStore, RunStore, StepPersister, PromptStore } from 'linforge/core';
class MyGraphStore implements GraphStore {
async getGraph(slug: string) { /* ... */ }
async saveGraph(graph) { /* ... */ }
async listGraphs() { /* ... */ }
}
// Pass to middleware
app.use(linforgeMiddleware({
stateSchema: MyState,
nodes: [planner],
stores: { graphStore: new MyGraphStore() },
}));
See linforge-adapter-prisma for a reference implementation.
MIT
FAQs
Embeddable workbench for LangGraph Agent apps — edit, run, debug, and monitor in one place
The npm package linforge receives a total of 8 weekly downloads. As such, linforge popularity was classified as not popular.
We found that linforge demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.

Security News
pnpm 12 rewrites the package manager in Rust, cutting install times by up to 90% while preserving pnpm 11 workflows and lockfiles.

Security News
Socket CTO Ahmad Nassri joins AppSec leaders at Black Hat to discuss active malware, package manager risks, and software supply chain defense.