# System prompts for beginners: set the rules once

A system prompt is a standing instruction that tells the model who it is, what rules to follow, and how to shape its answers. It sits above the back-and-forth of the conversation and applies to every reply, not only the next one. Get it right once and every turn improves.

## The two kinds of message

Every exchange with Claude has two layers. Your typed question is a user message: a single request the model answers once. The system prompt is different. It is set before the conversation and stays in force for the whole session.

| Layer | When it is sent | How long it lasts |
|---|---|---|
| System prompt | Before the first reply | The whole session |
| User message | Each time you press enter | That one turn |
| Assistant message | The model's reply | A record in history |

The model reads the system prompt before it reads anything you type. So a rule like "answer in British English" or "never edit files without asking" is honoured on turn one and on turn fifty, without you repeating it.

## What is a system prompt for?

A good system prompt answers three questions the model would otherwise have to guess at.

- **Role.** Who is the model acting as? "A senior backend engineer reviewing a pull request" produces different output than "a patient tutor explaining to a beginner." Even [one sentence of role](/guides/give-claude-a-role) changes tone and depth.
- **Rules.** What must it always do, and never do? Style conventions, the language to write in, libraries to prefer, actions that need your sign-off.
- **Output shape.** How should the answer come back? Prose, a table, a numbered checklist, JSON. State it once and the model stops drifting between formats.

Keep these three in mind and your system prompt stays focused. Everything in it should serve one of the three. If a line does not set a role, a rule, or an output shape, it probably belongs in a user message for a single turn instead.

## A worked example

Here is a compact system prompt for a code-review assistant. Notice that it names a role, lists a few hard rules, and fixes the output format.

```text
You are a careful senior code reviewer.

Rules:
- Point out correctness bugs before style nits.
- Suggest the smallest change that fixes each issue.
- If you are unsure about intent, ask before assuming.

For each file you review, reply with a short summary line,
then a bullet list of findings ordered by severity.
```

The model now opens every review the same way, weighs bugs above style on its own, and asks instead of guessing. You did not have to restate any of that per file.

## How does a system prompt shape every reply?

A useful way to picture a session is two boxes. The system prompt is fixed at the top. The conversation grows underneath it. Before each reply the model reads the fixed box first, then the growing one.

Because the system prompt is read before every reply, it is the highest-impact text you can write. One sentence there outweighs the same sentence buried in a user message that the model sees once and then scrolls past.

## Should I tell the model what to do or what to avoid?

The single biggest improvement most beginners make is switching from negative rules to positive ones. Models follow a [clear instruction to do something](/guides/write-a-prompt-claude-can-follow) better than a ban on its opposite.

| Weaker | Stronger |
|---|---|
| Do not write long answers | Answer in three sentences or fewer |
| Never use markdown | Reply in flowing prose paragraphs |
| Stop apologising | State the fix directly, then move on |

A rule that describes the target leaves no room to misread. A rule that only forbids one path still leaves every other path open.

## Give a reason when the rule is unusual

If a rule would look odd without context, add the reason in one short clause. The model generalises from it and applies the spirit of the rule to cases you did not spell out.

```text
Never use ellipses in your replies. They will be read aloud by a
text-to-speech engine that cannot pronounce them.
```

With the reason attached, the model also avoids other punctuation the speech engine would mangle, not only the exact character you named.

## How do I set the system prompt in the Claude Code CLI?

In the Claude Code CLI you control the system prompt with flags. There are two replacement flags and two append flags. Replacement throws away the default prompt; append adds your text to the end of it.

```bash
# Append a rule to the built-in prompt for one session
claude --append-system-prompt "Always use TypeScript and prefer named exports"

# Replace the whole prompt with your own text
claude --system-prompt "You are a Python expert. Answer concisely."

# Load the prompt text from a file instead of typing it inline
claude --append-system-prompt-file ./style-rules.txt
claude --system-prompt-file ./review-prompt.txt
```

`--system-prompt` and `--system-prompt-file` are mutually exclusive: you replace the prompt with text or with a file, not both. The append flags can ride alongside either replacement flag. These flags apply to the current invocation only; they do not persist after the session ends.

For most coding work, prefer append. The default Claude Code prompt already knows how to read files, run commands, and use your tools. Replacing it strips that out. Append when you want to add a convention; replace only when you need a fundamentally different persona.Beginners reach for `--system-prompt` to add one rule and quietly break the agent: full replacement deletes the built-in instructions that teach Claude Code how to read files and run tools, so it suddenly cannot do the work it did yesterday. The fix is almost always `--append-system-prompt`, which keeps those defaults and tacks your rule on the end. Save the replace flag for when you want a different persona with no tool use.

## CLAUDE.md is a system prompt that persists

Typing a flag every session gets old. For rules that should always apply to a project, put them in a `CLAUDE.md` file at the repo root. Claude Code loads it at the start of every session and treats it as part of the standing instructions, so your conventions stick without any flags.Because `CLAUDE.md` applies to every session and every teammate, do not park one-off task notes in it ("refactor the auth module today"). They get read on unrelated turns and skew answers. Keep it to durable conventions and put single-task detail in that turn's message.

```markdown
# Project conventions

- Co-locate tests next to source, e.g. src/auth/session.test.ts
- Use async/await, never .then() chains
- Ask before deleting files or force-pushing
```

A flag is a one-session override. `CLAUDE.md` is the durable version of the same idea. The deep dive on the durable layer lives in [rules and memory files](/guides/rules-and-memory-files).

## How do I switch personas without retyping?

If you keep several standing personas, a reviewer, a tutor, a release manager, save each as a file and point the flag at it. The team can share the files in the repo so everyone runs the same setup.

```bash
claude --system-prompt-file ./prompts/reviewer.txt
claude --system-prompt-file ./prompts/tutor.txt
```

Persistent personas you switch between belong in their own files. Project conventions everyone shares belong in `CLAUDE.md`. A one-off tweak belongs in an append flag for that session.

## Keep it short and current

The system prompt is read on every reply, so every line costs attention and tokens on each turn. Two rules keep it healthy.

- **Cut anything stale.** A rule that no longer applies is not neutral. The model still reads it and still tries to honour it, which pulls answers in a direction you no longer want.
- **Resist the urge to over-instruct.** Recent Claude models follow plain instructions well. Shouting "CRITICAL: you MUST always..." can make the model overreact and apply the rule where it does not fit. Write "Use TypeScript for new files" rather than a wall of capitals.

Keep the system prompt to the small set of rules that should hold on every turn. Single-turn detail goes in the user message for that turn. For the wider discipline of deciding what goes into the model's view at all, see [context engineering](/guides/context-engineering).

## A starter you can adapt

Drop this into a file and point `--system-prompt-file` at it, then change the role and rules to fit your work.

```text
You are a precise pair-programmer for a TypeScript web app.

Always:
- Read a file before you claim anything about it.
- Make the smallest change that satisfies the request.
- Run the tests after editing and report the result.

Ask before:
- Deleting files, dropping tables, or force-pushing.

Reply format:
- Start with a one-line summary of what you changed.
- Then list the files you touched and why.
```

## Checklist

Before you settle on a system prompt, run through these.

- Does it name a role in one clear sentence?
- Are the rules phrased as "do this" rather than "never do that"?
- Does any unusual rule carry a one-clause reason?
- Have you fixed the output format you want back?
- Did you append to the default prompt rather than replace it, unless you need a new persona?
- Is every line still relevant, with stale rules deleted?
- For project-wide rules, are they in `CLAUDE.md` instead of a flag you retype?

A system prompt that passes this checklist sets the rules once and holds them for the rest of the session, so every reply lands closer to what you wanted without you having to ask twice.
