The flowchart pattern for backend code — self-explainable systems that AI can reason about.
MVC is a pattern for backends. FootPrint is a different pattern — the flowchart pattern — where your business logic is a graph of functions with transactional state. The code becomes self-explainable: AI reads the structure, traces every decision, and explains what happened — no hallucination.
npm install footprintjsYour LLM needs to explain why your code made a decision. Without structure, it reconstructs reasoning from scattered logs — expensive, slow, and hallucinates.
| MVC / Traditional | Flowchart Pattern (FootPrint) | |
|---|---|---|
| LLM explains a decision | Reconstruct from scattered logs | Read the causal trace directly |
| Tool descriptions for agents | Write and maintain by hand | Auto-generated from the graph |
| State management | Global/manual, race-prone | Transactional scope with atomic commits |
| Debugging | console.log + guesswork |
Time-travel replay to any stage |
A loan pipeline rejects Bob. The user asks: "Why was I rejected?"
The runtime auto-generates this trace from what the code actually did:
Stage 1: The process began with ReceiveApplication.
Step 1: Write creditScore = 580, dti = 0.6, employmentStatus = "self-employed"
Stage 2: Next step: Evaluate risk tier from all flags.
Step 1: Read creditScore = 580
Step 2: Write riskTier = "high"
Step 3: Write riskFactors = (3 items)
Stage 3: Next step: Route based on risk tier.
Step 1: Read riskTier = "high"
[Condition]: It evaluated "High risk": riskTier "high" eq "high" ✓, and chose RejectApplication.
Stage 4: Next step: Generate rejection.
Step 1: Write decision = "REJECTED — below-average credit; DTI exceeds 43%; Self-employed < 2yr"
The LLM backtracks: riskTier="high" ← dtiStatus="excessive" ← dtiRatio=0.6 ← app.monthlyDebts=2100. Every variable links to its cause:
LLM: "Your application was rejected because your debt-to-income ratio of 60% exceeds the 43% maximum, your credit score of 580 falls in the 'fair' tier, and your self-employment tenure of 1 year is below the 2-year minimum."
That answer came from the trace — not from the LLM's imagination.
import { flowChart, decide, narrative } from 'footprintjs';
// 1. Define your state
interface State {
user: { name: string; tier: string };
discount: number;
lane: string;
}
// 2. Build the flowchart
const chart = flowChart<State>('FetchUser', async (scope) => {
scope.user = { name: 'Alice', tier: 'premium' };
}, 'fetch-user')
.addFunction('ApplyDiscount', async (scope) => {
scope.discount = scope.user.tier === 'premium' ? 0.2 : 0.05;
}, 'apply-discount')
.addDeciderFunction('Route', (scope) => {
return decide(scope, [
{ when: { discount: { gt: 0.1 } }, then: 'vip', label: 'High discount' },
], 'standard');
}, 'route', 'Route by discount tier')
.addFunctionBranch('vip', 'VIPCheckout', async (scope) => {
scope.lane = 'VIP express';
})
.addFunctionBranch('standard', 'StandardCheckout', async (scope) => {
scope.lane = 'Standard';
})
.setDefault('standard')
.end()
.build();
// 3. Run — state + self-generated trace included
const result = await chart.recorder(narrative()).run();
console.log(result.state.lane); // "VIP express"
console.log(result.narrative);
// [
// "Stage 1: The process began with FetchUser.",
// " Step 1: Write user = {name, tier}",
// "Stage 2: Next, it moved on to ApplyDiscount.",
// " Step 1: Read user = {name, tier}",
// " Step 2: Write discount = 0.2",
// "Stage 3: Next step: Route by discount tier.",
// " Step 1: Read discount = 0.2",
// "[Condition]: It evaluated Rule 0 \"High discount\": discount 0.2 gt 0.1 ✓, and chose VIPCheckout.",
// "Stage 4: Next, it moved on to VIPCheckout.",
// " Step 1: Write lane = \"VIP express\"",
// ]Try it in the browser — no install needed
Browse 37+ examples — patterns, recorders, subflows, integrations, and a full loan underwriting demo
Expose any flowchart as an MCP tool in one line — the description, input schema, and step list are auto-generated from the graph.
const tool = chart.toMCPTool();
// { name: 'assesscredit', description: '1. AssessCredit\n2. ...', inputSchema: { ... } }
// Register with any MCP server or pass directly to the Anthropic SDK:
const anthropicTool = { name: tool.name, description: tool.description, input_schema: tool.inputSchema };The LLM calls the tool, gets back the decision and causal trace, and explains the result to the user — all from the same graph that runs in production.
Live demo: Claude calls a credit-decision flowchart as an MCP tool — enter your API key, watch the tool call happen, see the trace.
| Feature | Description |
|---|---|
| Causal Traces | Every read/write captured — LLMs backtrack through variables to find causes |
| Decision Evidence | decide() / select() auto-capture WHY a branch was chosen — operators, thresholds, pass/fail |
| TypedScope<T> | Typed property access — scope.creditScore = 750 instead of scope.setValue('creditScore', 750) |
| Auto Narrative | Build-time descriptions for tool selection, runtime traces for explanation |
| 7 Patterns | Linear, parallel fork, conditional, multi-select, subflow, streaming, loops |
| Transactional State | Atomic commits, safe merges, time-travel replay |
| PII Redaction | Per-key or declarative RedactionPolicy with audit trail |
| Flow Recorders | 8 narrative strategies for loop compression |
| Contracts | I/O schemas (Zod/JSON Schema) + OpenAPI 3.1 + MCP tool generation |
| Cancellation | AbortSignal, timeout, early termination via scope.$break() |
FootPrint ships with built-in instructions for every major AI coding assistant. Your AI tool understands the API, patterns, and anti-patterns out of the box.
# Download and run the setup script from GitHub
npx degit footprintjs/footPrint/ai-instructions footprint-ai && bash footprint-ai/setup.sh && rm -rf footprint-ai| Tool | What gets installed |
|---|---|
| Claude Code | .claude/skills/footprint/SKILL.md + CLAUDE.md |
| OpenAI Codex | AGENTS.md |
| GitHub Copilot | .github/copilot-instructions.md |
| Cursor | .cursor/rules/footprint.md |
| Windsurf | .windsurfrules |
| Cline | .clinerules |
| Kiro | .kiro/rules/footprint.md |
| Resource | Link |
|---|---|
| Getting Started | Quick Start · Key Concepts · Why footprintjs? |
| Guides | Building · Decision branching · Recorders · Subflows · Self-describing APIs |
| API Reference | flowChart() / Builder · decide() / select() · FlowChartExecutor · Recorders · Contract & Self-describing |
| Try it | Interactive Playground · Try with your LLM · Live Demo |
