# How to Add a Custom Summary Template or Workflow to Meetily's Summary Engine

> Learn to add custom summary templates and workflows to Meetily's summary engine. Explore the JSON-based registry for easy customization without code changes.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-08-04

---

**Meetily supports custom summary templates through a JSON-based registry system that automatically loads user-defined templates from a designated directory, requiring no code changes for basic customization.**

Meetily's meeting summarization pipeline is built for extensibility. Whether you need a daily standup format, project retrospectives, or industry-specific output structures, you can inject custom templates without modifying core source code. This guide walks through adding a custom summary template or workflow to Meetily's Rust-based summary engine, using the actual implementation in `Zackriya-Solutions/meetily`.

## Meetily's Summary Pipeline Architecture

The summary engine consists of five coordinated components:

| Component | Role | Key Source File |
|-----------|------|---------------|
| **Template Registry** | Stores built-in templates (daily standup, standard meeting) | [`frontend/src-tauri/src/summary/templates/defaults.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/templates/defaults.rs) |
| **Template Loader** | Scans user templates directory and merges with built-ins | [`frontend/src-tauri/src/summary/templates/loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/templates/loader.rs) |
| **Command Bridge** | Tauri commands exposing templates to the frontend | [`frontend/src-tauri/src/summary/template_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/template_commands.rs) |
| **Processor** | Injects transcript into template and calls LLM | [`frontend/src-tauri/src/summary/processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/processor.rs) |
| **Service Layer** | Orchestrates end-to-end summary generation | [`frontend/src-tauri/src/summary/service.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/service.rs) |

## Creating a Custom Summary Template

### Step 1: Define Your Template JSON

Create a JSON file following Meetily's template schema. The file supports **title interpolation** (e.g., `{{date}}`) and **section-based LLM prompts**.

```json
{
  "title": "Project Sync – {{date}}",
  "sections": [
    {
      "heading": "Highlights",
      "prompt": "Summarize the most important points discussed."
    },
    {
      "heading": "Action Items",
      "prompt": "List any tasks that were assigned with owners."
    },
    {
      "heading": "Blockers",
      "prompt": "Identify any obstacles mentioned that need escalation."
    }
  ]
}

```

Save this file as [`frontend/src-tauri/src/summary/templates/custom/my_custom_template.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/templates/custom/my_custom_template.json). The [`loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/loader.rs) implementation recurses subdirectories, so you can organize templates into folders.

### Step 2: Register the Template (Automatic Loading)

The [`loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/loader.rs) implementation handles registration automatically. No code changes are required:

```rust
// Simplified excerpt from loader.rs
pub fn load_all_templates() -> Vec<(&'static str, &'static str)> {
    let mut templates = defaults::get_builtin_templates();
    
    // Scan user-provided directory
    if let Ok(entries) = std::fs::read_dir(custom_template_dir()) {
        for entry in entries.flatten() {
            if let Ok(content) = std::fs::read_to_string(entry.path()) {
                if let Some(id) = entry.path().file_stem().and_then(|s| s.to_str()) {
                    templates.push((id, Box::leak(content.into_boxed_str())));
                }
            }
        }
    }
    templates
}

```

The **template ID** is derived from the filename (without extension). In this example: `my_custom_template`.

**Action required:** Restart the application or trigger hot-reload for the loader to pick up new files.

## Exposing Templates to the Frontend

### Listing Available Templates

The frontend retrieves templates through Tauri commands defined in [`template_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/template_commands.rs):

```typescript
import { invoke } from '@tauri-apps/api/tauri';

async function loadSummaryTemplates() {
  const templates = await invoke<{ id: string; name: string }[]>(
    'list_summary_templates'
  );
  
  // Returns: [{ id: 'daily_standup', name: 'Daily Standup' }, ...]
  return templates;
}

```

### Generating a Summary with Your Template

Pass the `templateId` when invoking summary generation:

```typescript
await invoke('generate_summary', {
  meetingId: currentMeeting.id,
  templateId: 'my_custom_template',  // Must match filename exactly
});

```

The [`service.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/service.rs) layer receives this ID, retrieves the corresponding template from the registry, and delegates to [`processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/processor.rs) for LLM interaction.

## Adding a Custom Workflow (Advanced)

For scenarios requiring **pre-processing, multi-step prompts, or post-processing**, extend the processor directly.

In [`processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/processor.rs), add a match arm for your template ID:

```rust
match template_id {
    "my_custom_template" => {
        // Custom prompt composition logic
        let prompt = format!(
            "{}\n\nAdditional context: {}\n\nTranscript:\n{}",
            CUSTOM_INSTRUCTION,
            fetch_context(),  // e.g., pull related meeting history
            transcript
        );
        generate_summary(&prompt, model).await?;
    }
    _ => default_processing(template_id, transcript, model).await?,
}

```

**Required:** Recompile the Tauri app after modifying Rust source:

```bash
pnpm run tauri:dev

```

## Testing Your Custom Template

Meetily includes Jest tests for template validation. Add coverage for your custom template:

```typescript
test('custom template produces valid JSON structure', async () => {
  const content = await readFile(
    'src-tauri/src/summary/templates/custom/my_custom_template.json',
    'utf-8'
  );
  const parsed = JSON.parse(content);
  
  expect(parsed).toHaveProperty('title');
  expect(parsed).toHaveProperty('sections');
  expect(Array.isArray(parsed.sections)).toBe(true);
});

```

Run the test suite:

```bash
pnpm test

```

## Key Configuration Files

| File | Purpose |
|------|---------|
| [`defaults.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/defaults.rs) | Built-in templates (`daily_standup`, `standard_meeting`) |
| [`loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/loader.rs) | Dynamic template discovery and registration |
| [`template_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/template_commands.rs) | Tauri command API surface |
| [`processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/processor.rs) | LLM prompt construction and invocation |
| [`service.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/service.rs) | High-level workflow orchestration |

## Summary

- **Simple templates:** Create JSON in `templates/custom/` and restart — no code changes needed
- **Template IDs** match filenames without extension
- **Frontend integration** uses standard Tauri invoke calls to `list_summary_templates` and `generate_summary`
- **Complex workflows** require extending [`processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/processor.rs) with custom match arms and recompiling
- **Validate templates** with Jest tests before committing to production

## Frequently Asked Questions

### What is the exact directory path for custom templates?

Place JSON files in `frontend/src-tauri/src/summary/templates/custom/` or any subdirectory thereof. The [`loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/loader.rs) implementation recurses through all nested folders.

### Do I need to rebuild Meetily after adding a JSON template?

No — for JSON-only templates, a simple application restart suffices. Only modifications to Rust source files (like [`processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/processor.rs) for custom workflows) require recompilation with `pnpm run tauri:dev`.

### Can templates include dynamic variables beyond {{date}}?

The [`defaults.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/defaults.rs) built-ins demonstrate the available interpolation syntax. Custom variables require extending the processor to provide values during prompt construction.

### How does Meetily handle template conflicts with identical IDs?

The [`loader.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/loader.rs) implementation appends user templates after built-ins in the `Vec`. In case of ID collision, the last-defined template wins — typically the user-provided version.