# How to Inject Variables into Fabric Patterns: Complete Technical Guide

> Learn to inject variables into Fabric patterns using a reactive JSON store. Dynamically merge user values into templates at runtime for flexible designs.

- Repository: [Daniel Miessler 🛡️/fabric](https://github.com/danielmiessler/fabric)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Yes, you can inject variables into Fabric patterns using a reactive JSON store that dynamically merges user-defined values into pattern templates at runtime.**

Fabric by danielmiessler is an open-source framework for augmenting LLM interactions through modular patterns. When you need to customize pattern behavior without modifying source files, you can inject variables into Fabric patterns via a type-safe, reactive mechanism built into the web interface.

## How Variable Injection Works in Fabric

Fabric’s pattern variable system operates through a three-tier architecture that bridges the user interface, client-side state management, and backend processing. The mechanism allows you to define key-value pairs in JSON format, which the system then substitutes into placeholder markers within your pattern text.

The flow follows this execution path:

1. **UI Input** – Users enter JSON into a dedicated textarea in the chat interface
2. **Store Update** – The application parses the JSON into a reactive Svelte store called `patternVariables`
3. **Request Assembly** – `ChatService.createChatPrompt()` retrieves the current store value and attaches it to the `ChatPrompt` object
4. **Backend Substitution** – The server receives the variables map and performs string replacement on `{{variable_name}}` placeholders before sending the final prompt to the LLM

## The Technical Architecture

### Pattern Store Definition

The variable state management begins in [`web/src/lib/store/pattern-store.ts`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/store/pattern-store.ts), where the application defines a writable store with strict typing:

```typescript
patternVariables: writable<Record<string, string>>({})

```

This store maintains a flat dictionary of string keys and values, ensuring type safety across the application. When updated, the store triggers reactive changes throughout the component tree.

### User Interface Components

The primary interface for variable input resides in [`web/src/lib/components/chat/DropdownGroup.svelte`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/components/chat/DropdownGroup.svelte). This component provides a textarea bound to the `updateVariables()` function, which handles JSON parsing and validation:

- The function attempts `JSON.parse` on user input
- Valid objects are written to the `patternVariables` store via `patternVariables.set(parsed)`
- Malformed JSON is silently ignored during typing to prevent UI interruption

### Service Layer Integration

When constructing chat requests, [`web/src/lib/services/ChatService.ts`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/services/ChatService.ts) integrates the stored variables into the network payload. The `createChatPrompt()` method retrieves the current store value using Svelte's `get()` utility and injects it into the request contract defined in [`chat-interface.ts`](https://github.com/danielmiessler/fabric/blob/main/chat-interface.ts):

```typescript
variables: get(patternVariables)

```

This ensures every chat request carries the latest variable context without manual synchronization.

## Implementing Pattern Variables

### Step 1: Configure Variables in the UI

To inject variables into Fabric patterns, enter valid JSON in the "Pattern Variables" textarea within the chat interface. The underlying Svelte component processes your input reactively:

```svelte
<script lang="ts">
  import { patternVariables } from '$lib/store/pattern-store';
  let variablesJsonString = '';

  function updateVariables() {
    try {
      if (!variablesJsonString.trim()) {
        patternVariables.set({});
      } else {
        const parsed = JSON.parse(variablesJsonString);
        if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
          patternVariables.set(parsed);
        }
      }
    } catch (_) {
      // ignore malformed JSON while typing
    }
  }
</script>

<textarea
  bind:value={variablesJsonString}
  on:input={updateVariables}
  placeholder='{"lang_code":"fr","role":"expert"}'>
</textarea>

```

*Source:* [`web/src/lib/components/chat/DropdownGroup.svelte`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/components/chat/DropdownGroup.svelte)

### Step 2: Build the Chat Prompt

The service layer automatically attaches variables when constructing requests. The `createChatPrompt()` method in [`ChatService.ts`](https://github.com/danielmiessler/fabric/blob/main/ChatService.ts) assembles the complete payload:

```typescript
private createChatPrompt(userInput: string, systemPromptText?: string): ChatPrompt {
  const config = get(modelConfig);
  const language = get(languageStore);

  const finalSystemPrompt = (language !== 'en' ? `You MUST respond in ${language} language. ` : '')
    + (systemPromptText ?? get(systemPrompt));

  return {
    userInput,
    systemPrompt: finalSystemPrompt,
    model: config.model,
    patternName: get(selectedPatternName),
    strategyName: get(selectedStrategy),
    sessionName: get(currentSession) ?? undefined,
    variables: get(patternVariables),   // injected variables
  };
}

```

*Source:* [`web/src/lib/services/ChatService.ts`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/services/ChatService.ts)

### Step 3: Create Template Patterns

To utilize injected variables, author your pattern files using double-brace placeholder syntax. The backend replaces these markers with values from the `variables` field before LLM processing:

```text
You are a translation assistant.
Translate the following text to {{lang_code}} and adopt the tone of a {{role}}.

{{input}}

```

When you supply `{"lang_code":"fr","role":"expert"}`, the system generates a fully-expanded prompt substituting `"fr"` for `{{lang_code}}` and `"expert"` for `{{role}}`.

## Summary

- **Pattern variables** in Fabric are implemented through a reactive Svelte store (`patternVariables`) defined in [`web/src/lib/store/pattern-store.ts`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/store/pattern-store.ts)
- The **UI layer** in [`DropdownGroup.svelte`](https://github.com/danielmiessler/fabric/blob/main/DropdownGroup.svelte) provides JSON parsing and validation through the `updateVariables()` function
- **ChatService.ts** automatically injects stored variables into `ChatPrompt` requests via `get(patternVariables)`
- Variables are transmitted to the backend and substituted into **double-brace placeholders** (`{{key}}`) within pattern templates
- The system supports **type-safe**, **reactive** updates without requiring pattern file modifications

## Frequently Asked Questions

### What is the syntax for pattern variables in Fabric?

Pattern variables use double-brace syntax: `{{variable_name}}`. In the web interface, you supply values as a JSON object where keys match the placeholder names. For example, `{"tone": "formal"}` replaces `{{tone}}` in your pattern text.

### Where are pattern variables stored in the Fabric codebase?

Variables are stored in a Svelte writable store named `patternVariables` located in [`web/src/lib/store/pattern-store.ts`](https://github.com/danielmiessler/fabric/blob/main/web/src/lib/store/pattern-store.ts). The store is typed as `Record<string, string>` and is accessed by the chat service to populate the `variables` field in the `ChatPrompt` interface.

### Can I use pattern variables without the web interface?

The variable injection mechanism described here is specific to the Fabric web interface implementation. However, the backend API accepts a `variables` field in the request payload, so custom clients can implement similar functionality by sending a `Record<string, string>` map to the chat endpoint.

### What happens if I provide invalid JSON for variables?

The UI gracefully handles malformed JSON by silently catching parse errors during typing, leaving the store in its previous valid state. Only successfully parsed objects are written to `patternVariables`, preventing runtime crashes while allowing incremental editing.