# How to Create Custom Prompt Templates and Masks in NextChat

> Learn to create custom prompt templates and masks in NextChat by editing JSON files or using the Settings UI. Enhance your AI interactions with personalized prompts.

- Repository: [NextChat/NextChat](https://github.com/ChatGPTNextWeb/NextChat)
- Tags: how-to-guide
- Published: 2026-02-28

---

**You can create custom prompt templates by editing [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json) or using the Settings UI, and build custom masks by adding TypeScript modules under `app/masks/` and registering them in [`app/masks/index.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/masks/index.ts).**

NextChat (formerly ChatGPT-Next-Web) stores reusable prompt definitions and UI-level masks as JavaScript/TypeScript objects loaded at runtime. By modifying these data structures, you can tailor system behavior, inject custom system messages, or preset conversation styles for specific workflows.

## Understanding Prompt Templates in NextChat

Prompt templates are reusable text definitions that populate the model context. According to the NextChat source code, these objects follow a strict interface that supports optional model overrides and sampling parameters.

### Storage Architecture and Key Files

The default templates reside in **[`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json)**, which the application loads into the **[`app/store/prompt.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/prompt.ts)** store at startup. The prompt store exposes a `usePromptStore` hook that components like the chat sidebar use to retrieve specific prompts via `getPromptById(id)`.

### Template Schema Definition

Each prompt template adheres to the following TypeScript structure:

```typescript
{
  id: string;               // unique identifier
  name: string;             // shown in the UI
  description?: string;     // optional help text
  prompt: string;           // raw prompt sent to the model
  model?: string;           // optional model override
  temperature?: number;     // optional sampling temperature
}

```

### Methods for Adding Custom Templates

You have two primary methods to extend the prompt library.

**Option A: Settings UI (End-User Method)**

Navigate to *Settings → Prompts*, click **Add Prompt**, and complete the form fields. The UI persists the entry to `localStorage` and syncs it to the same shape expected by [`prompt.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/prompt.ts), as implemented in **[`app/components/Settings/PromptManager.tsx`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/components/Settings/PromptManager.tsx)**.

**Option B: Source Code Modification**

Fork the repository and edit [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json) directly. Add your object to the JSON array, then rebuild. On the next deployment, the new template will be available automatically.

## Creating Custom Masks in NextChat

Masks are higher-level UI presets that bundle a system prompt, default model, and optional avatar into a selectable persona. Unlike raw prompt templates, masks provide conversation context from the first message.

### Mask Architecture and Registration

Masks are defined as TypeScript modules under **`app/masks/`** and aggregated by **[`app/masks/index.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/masks/index.ts)**. The central mask store in **[`app/store/mask.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/mask.ts)** handles runtime state and persistence.

### Mask Interface Structure

As implemented in [`app/store/mask.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/mask.ts), the `Mask` interface requires:

```typescript
export interface Mask {
  id: string;                     // unique key
  name: string;                   // UI label
  avatar: string;                 // optional avatar URL
  description?: string;           // tooltip text
  prompt: string;                 // system prompt injected at start
  model?: string;                 // default model
  temperature?: number;           // default sampling temperature
}

```

### Step-by-Step Mask Creation

Follow these steps to register a custom mask.

1. **Create the module**: Add a new file at [`app/masks/my-mask.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/masks/my-mask.ts) with your mask definition:

```typescript
// app/masks/my-mask.ts
import type { Mask } from '../store/mask';

export const myMask: Mask = {
  id: 'my-mask',
  name: 'Research Assistant',
  avatar: '/mask-icons/research.svg',
  description: 'Provides concise, citation-rich answers.',
  prompt: `You are a research assistant. Answer briefly, cite sources, and ask clarifying questions.`,
  model: 'gpt-4o-mini',
  temperature: 0.2,
};

```

2. **Register the export**: Append the export to [`app/masks/index.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/masks/index.ts):

```typescript
// app/masks/index.ts
export * from './my-mask';

```

3. **Rebuild**: Run `npm run build` or restart the dev server. The mask will appear in the *Select Mask* dropdown.

### Persisting Masks for End Users

Users can select any mask from the dropdown and click **Save as Custom**, which stores a copy in browser `localStorage` using the same `Mask` interface structure defined in [`app/store/mask.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/mask.ts).

## Integrating Prompts with Masks

You can reference prompt templates within mask definitions to create reusable personas. For example, a "Code Reviewer" mask can reference guidelines stored in [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json):

```typescript
export const codeReviewerMask: Mask = {
  id: 'code-reviewer',
  name: 'Code Reviewer',
  avatar: '/mask-icons/code.svg',
  description: 'Reviews code and suggests improvements.',
  prompt: `You are an expert software engineer. Follow the style guidelines from the "Code Review Prompt" template.`,
  model: 'gpt-4o',
  temperature: 0.3,
};

```

When users select this mask, the conversation initializes with the mask's system prompt while retaining access to the standalone template library managed by `usePromptStore`.

## Summary

- **Prompt templates** are JSON objects in [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json) managed by [`app/store/prompt.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/prompt.ts), supporting optional `model` and `temperature` overrides.
- **Masks** are TypeScript objects in `app/masks/` that bundle system prompts with UI metadata, registered via [`app/masks/index.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/masks/index.ts).
- **UI method** allows end users to save prompts to `localStorage` through the Settings interface.
- **Code method** requires creating `.ts` files for masks or editing [`prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/prompts.json) for templates, followed by a rebuild to bake changes into the deployment.

## Frequently Asked Questions

### What is the difference between a prompt template and a mask in NextChat?

A **prompt template** is a reusable text snippet stored in [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json) that users can insert into any conversation via the `usePromptStore` hook. A **mask** is a higher-level preset defined in `app/masks/` that automatically injects a system prompt at the start of a new chat and can include default models, avatars, and temperature settings.

### How do I persist custom masks across browser sessions?

When users create or customize a mask through the UI, NextChat stores the `Mask` object in browser `localStorage`. For permanent deployment-wide masks, define them as TypeScript modules in `app/masks/` and rebuild the application so they ship with the default bundle.

### Can I override the model selection in a custom prompt template?

Yes. The prompt template structure includes an optional `model` field that specifies which LLM to use when that prompt is selected. If omitted, NextChat falls back to the global default model defined in the application's settings.

### Where does NextChat store user-created prompts when using the UI?

User-created prompts added through the Settings UI are persisted to `localStorage` and managed by the `usePromptStore` hook in [`app/store/prompt.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/store/prompt.ts). These client-side entries supplement the default templates loaded from [`public/prompts.json`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/public/prompts.json) at startup.