| | |

Prettier 23 ๐ŸŽจ The –require-pragma Option โ€” Gradual adoption for large codebases

โฑ๏ธ Estimated read: 12 min | |

The --require-pragma flag inverts Prettier’s default behavior. Instead of formatting every file it is given, it formats only the files that carry a specific marker in their first block comment. The marker is either @format or @prettier, and it must appear in a docblock-style comment at the top of the file . A file without the marker is returned unchanged, with no error and no warning. The flag exists for one scenario: introducing Prettier to a large, unformatted codebase without a single commit that rewrites every file and destroys git blame for the entire repository.

The flag was introduced in Prettier v1.7.0, and its companion --insert-pragma followed in v1.8.0 . The two are designed to be used in tandem during a migration, but they are not used at the same time. The --insert-pragma flag adds the marker to files that Prettier formats, and --require-pragma restricts formatting to files that already have the marker. When both are set, --require-pragma takes priority, and --insert-pragma is ignored . The migration workflow uses them in separate phases: --insert-pragma for the files a developer is actively migrating, and --require-pragma for the rest of the team and the CI tooling, which should only touch files that have already been opted in.

Key point: --require-pragma makes Prettier format only files whose first block comment contains @format or @prettier. Files without the marker are left untouched. The flag is for gradual adoption, not for permanent configuration. When the migration is complete, both --require-pragma and --insert-pragma should be removed, or new files will silently escape formatting.


Why the flag exists

The big-bang adoption problem. Running prettier --write . on a mature codebase produces a commit that touches every file. Every open pull request conflicts with the formatting commit, every line of git blame points to the formatting commit instead of the original author, and the reviewer has no way to distinguish a formatting change from a logic change in the diff . For a small project, this is an afternoon’s inconvenience. For a codebase with hundreds of thousands of lines and dozens of concurrent branches, it is enough to prevent adoption entirely.

The opt-in mechanism. --require-pragma changes the default from “format everything” to “format nothing unless the file explicitly agrees.” The agreement is a comment that the file’s author or the migrating developer adds. The comment is a content-based marker, not a path-based ignore. This distinction matters when files move: a renamed file keeps its pragma and keeps its formatting behavior, whereas a .prettierignore entry silently stops matching when the path changes . For a codebase in active refactoring, the content-based marker is the more robust choice.

The incremental growth. The formatted portion of the codebase grows in step with the code people are actually touching. A developer who opens a file to fix a bug runs Prettier on that file with --insert-pragma, and the file is formatted and marked in the same commit as the bug fix. The formatting change rides along with a change that was going to be reviewed anyway . Over time, the unmarked set shrinks, and the migration completes without a dedicated formatting sprint.

The trade-off. The flag introduces a split codebase. Some files are formatted, some are not, and the editor’s format-on-save silently does nothing on the unformatted ones . The contributing guide must explain the convention, and the CI pipeline must be configured to run Prettier only on the opted-in set. The migration ends when the split is no longer worth maintaining, and the flags are removed.


a. The pragma format and the block comment requirement

The pragma must be a block comment, and it must be the first block comment in the file. A line comment does not work, and a block comment that appears after the first one does not work . The valid forms depend on the language, because the comment syntax varies.

// โœ… A valid pragma in a JavaScript file
/**
 * @format
 */

// โœ… The alternative marker
/**
 * @prettier
 */

// โŒ A line comment is not a valid pragma
// @format

// โŒ A pragma in a later block comment is not valid
const x = 1;
/**
 * @format
 */

For JavaScript, TypeScript, and CSS, the pragma is written as /** @format */. For HTML and Vue templates, it is <!-- @format -->. For Markdown, it is also <!-- @format --> at the top of the document. For YAML, it is # @format . The marker has to be a comment in the language’s syntax, and Prettier writes the correct form for the file type it is formatting.

<!-- A valid pragma in a Markdown file -->
<!-- @format -->

# Title

Content.

The --require-pragma flag checks for the marker in the file’s first block comment. The check is per-language: a Markdown file’s pragma is an HTML comment, and a YAML file’s pragma is a hash comment. A search for pragmas across a mixed repository must cover all the forms, not just the JavaScript block comment .


b. The migration workflow with --insert-pragma

The migration uses the two flags in separate phases. The --insert-pragma flag is for the files a developer is actively migrating. The --require-pragma flag is for the team and the CI tooling, which should only touch files that have already been opted in.

# Phase 1: A developer formats a file they are already changing.
# The --insert-pragma flag adds the marker to the formatted output.
npx prettier src/app.js --insert-pragma --write

# Phase 2: The CI pipeline checks only the opted-in files.
# The --require-pragma flag skips the unmarked files.
npx prettier "src/**/*.js" --require-pragma --check

The CI check passes trivially for the unmarked files, because --require-pragma skips them. The check enforces formatting only on the files that have been migrated, which is the correct behavior during the transition . The formatted share of the codebase grows as developers touch files, and the CI enforcement grows with it.

// A Git-based script for the migration.
// The script formats only the files that changed in the current branch.
import { execSync } from "node:child_process";

const changedFiles = execSync(
  "git diff --name-only origin/main...HEAD",
  { encoding: "utf8" }
)
  .split("\n")
  .filter((f) => f.endsWith(".js") || f.endsWith(".ts"));

// The changed files are formatted and marked.
// The rest of the codebase is untouched.
for (const file of changedFiles) {
  execSync(`npx prettier "${file}" --insert-pragma --write`);
}

The Git-based script is the pattern for automating the migration. The git diff --name-only command lists the files that changed in the branch, and the Prettier command formats and marks them. The script runs on the developer’s machine or in a pre-commit hook, and the formatted set grows with the code that is actually being reviewed .


Complete Example Session

// ============================================
// PART 1: THE PROBLEM
// ============================================

// A codebase with 10,000 files.
// None of them are formatted.
// Running prettier --write . produces a 10,000-file commit.
// Every open PR conflicts.
// git blame is destroyed.
// The migration is abandoned.

// ============================================
// PART 2: THE PRAGMA
// ============================================

// A file that opts in:
/**
 * @format
 */

const user = { name: "Ada", "user-id": 7 };

// The marker is in the first block comment.
// Prettier formats the file when --require-pragma is set.

// ============================================
// PART 3: THE REQUIRE-PRAGMA FLAG
// ============================================

// npx prettier src/app.js --require-pragma
//
// If src/app.js has the @format marker:
//   The file is formatted.
//
// If src/app.js does not have the marker:
//   The file is returned unchanged.
//   No error, no warning.

// ============================================
// PART 4: THE INSERT-PRAGMA FLAG
// ============================================

// npx prettier src/app.js --insert-pragma --write
//
// The file is formatted.
// The @format marker is added to the first block comment.
// If the file has no block comment, one is created.

// ============================================
// PART 5: THE MIGRATION PHASE
// ============================================

// A developer opens a file to fix a bug.
// They run:
//   npx prettier src/app.js --insert-pragma --write
//
// The file is formatted and marked.
// The bug fix and the formatting are in the same commit.
// The reviewer sees both changes in the diff.

// ============================================
// PART 6: THE CI CHECK
// ============================================

// package.json
{
  "scripts": {
    "format:check": "prettier --require-pragma --check ."
  }
}

// The CI runs the check.
// Only the files with the pragma are checked.
// The unmarked files are skipped.
// The CI enforces formatting on the opted-in set.

// ============================================
// PART 7: THE COMPLETION
// ============================================

// When the unmarked set is small enough:
// 1. Remove --require-pragma from the CI script.
// 2. Run prettier --write . on the remaining files.
// 3. Remove --insert-pragma from the developer workflow.
// 4. Optionally, strip the pragmas with a mechanical commit.

// ============================================
// PART 8: THE EDITOR CAVEAT
// ============================================

// Format-on-save does nothing on unmarked files.
// The developer presses the format shortcut.
// Nothing happens.
// The contributing guide must explain the convention.

// ============================================
// PART 9: THE LANGUAGE VARIATION
// ============================================

// JavaScript:  /** @format */
// HTML:        <!-- @format -->
// Markdown:    <!-- @format -->
// YAML:        # @format
// CSS:         /** @format */

// The marker must be a comment in the language's syntax.

// ============================================
// PART 10: THE VERIFICATION CHECKLIST
// ============================================

// [ ] The pragma is a block comment in the file's first block comment.
// [ ] The --require-pragma flag is set in the CI script.
// [ ] The --insert-pragma flag is used by the migrating developers.
// [ ] The contributing guide explains the format-on-save caveat.
// [ ] The migration has an end date and a completion plan.
// [ ] The flags are removed when the migration is complete.

The ten parts covered the problem, the pragma, the two flags, the migration phase, the CI check, the completion, the editor caveat, the language variation, and the verification. The through-line is that the pragma is the opt-in marker, and the two flags are the migration mechanism.


Quick Reference

The flags

FlagDefaultEffect
--require-pragmafalseFormat only files with @format or @prettier
--insert-pragmafalseAdd @format to formatted files

The pragma forms

LanguageForm
JavaScript / TypeScript / CSS/** @format */
HTML / Vue / Markdown<!-- @format -->
YAML# @format

The migration phases

PhaseFlagWho uses it
Migration--insert-pragmaDevelopers touching files
Enforcement--require-pragmaCI and the rest of the team
CompletionNeitherEveryone

Best Practices

โœ… Do This:

# Use --insert-pragma when migrating a file
npx prettier src/app.js --insert-pragma --write                  // โœ…

# Use --require-pragma in CI during the migration
npx prettier "src/**/*.js" --require-pragma --check             // โœ…

# Remove both flags when the migration is complete
# The pragmas are inert after --require-pragma is removed.       // โœ…

โŒ Don’t Do This:

# Use a line comment as the pragma
// @format                                                      // โŒ

# Leave --require-pragma enabled indefinitely
# New files silently escape formatting.                         // โŒ

# Use both flags at the same time
# --require-pragma takes priority; --insert-pragma is ignored.  // โŒ

Common Pitfalls

PitfallWhy It HappensFix
Prettier appears broken--require-pragma is set and no files have the markerAdd the pragma or remove the flag
The pragma is not recognizedIt is a line comment or not the first block commentUse a block comment at the top of the file
Format-on-save does nothingThe file is unmarkedAdd the pragma or run with --insert-pragma
The migration never endsThe flag is left enabledSet a completion date and remove the flag

Real-World Examples

1. The pragma

/** @format */

2. The require flag

npx prettier src/app.js --require-pragma

3. The insert flag

npx prettier src/app.js --insert-pragma --write

4. The CI check

"format:check": "prettier --require-pragma --check ."

5. The Git script

git diff --name-only origin/main...HEAD | xargs npx prettier --insert-pragma --write

6. The Markdown pragma

<!-- @format -->

7. The YAML pragma

# @format

8. The completion

# Remove --require-pragma from the CI script

9. The editor caveat

// Format-on-save does nothing on unmarked files

10. The priority rule

# --require-pragma wins when both flags are set

Visual

The Migration Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  GRADUAL ADOPTION                                             โ”‚
โ”‚                                                              โ”‚
โ”‚  Before: 10,000 unformatted files                            โ”‚
โ”‚         โ”‚                                                    โ”‚
โ”‚         โ–ผ                                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ Developer touches   โ”‚                                    โ”‚
โ”‚  โ”‚ a file              โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ”‚             โ”‚                                                โ”‚
โ”‚             โ–ผ                                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ --insert-pragma     โ”‚  File formatted and marked         โ”‚
โ”‚  โ”‚ --write             โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ”‚             โ”‚                                                โ”‚
โ”‚             โ–ผ                                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ CI: --require-pragmaโ”‚  Only marked files checked         โ”‚
โ”‚  โ”‚ --check             โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ”‚             โ”‚                                                โ”‚
โ”‚             โ–ผ                                                    โ”‚
โ”‚  Repeat until the unmarked set is small                      โ”‚
โ”‚  Then remove the flags and format the rest                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Pragma Forms

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE MARKER IS LANGUAGE-SPECIFIC                              โ”‚
โ”‚                                                              โ”‚
โ”‚  JavaScript/TypeScript/CSS:  /** @format */                  โ”‚
โ”‚  HTML/Vue/Markdown:          <!-- @format -->                โ”‚
โ”‚  YAML:                       # @format                       โ”‚
โ”‚                                                              โ”‚
โ”‚  The marker must be the first block comment.                 โ”‚
โ”‚  A line comment is not recognized.                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Two Flags

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  --insert-pragma VS --require-pragma                          โ”‚
โ”‚                                                              โ”‚
โ”‚  --insert-pragma              --require-pragma               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚ Adds the marker     โ”‚     โ”‚ Requires the marker โ”‚        โ”‚
โ”‚  โ”‚ to formatted files  โ”‚     โ”‚ to format a file    โ”‚        โ”‚
โ”‚  โ”‚                     โ”‚     โ”‚                     โ”‚        โ”‚
โ”‚  โ”‚ Used by developers  โ”‚     โ”‚ Used by CI and the  โ”‚        โ”‚
โ”‚  โ”‚ during migration    โ”‚     โ”‚ rest of the team    โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚                                                              โ”‚
โ”‚  When both are set, --require-pragma wins.                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Flag--require-pragma
Introducedv1.7.0
Pragma markers@format or @prettier
Comment typeBlock comment, first in the file
Companion flag--insert-pragma (v1.8.0)
Priority--require-pragma wins when both are set
PurposeGradual adoption of large codebases
CompletionRemove both flags

Key takeaways:

  • --require-pragma makes Prettier format only files with a marker. The marker is @format or @prettier in the file’s first block comment. A file without the marker is returned unchanged. The flag exists for gradual adoption, not for permanent use .
  • The marker must be a block comment, and it must be the first one. A line comment does not work. The comment syntax depends on the language: /** @format */ for JavaScript, <!-- @format --> for HTML and Markdown, # @format for YAML .
  • --insert-pragma is the companion flag for the migration. It adds the marker to files that Prettier formats. The two flags are used in separate phases: --insert-pragma by the developers who are migrating files, and --require-pragma by the CI and the rest of the team .
  • The migration grows with the code that is actually touched. A developer who fixes a bug runs Prettier with --insert-pragma on the file, and the formatting rides along with the bug fix. The unmarked set shrinks without a dedicated formatting sprint .
  • The flag is temporary. When the migration is complete, both --require-pragma and --insert-pragma should be removed. A forgotten --require-pragma means new files silently escape formatting, and the codebase permanently contains two classes of files .

Remember: --require-pragma is a migration tool, not a formatting configuration. It inverts Prettier’s default so that files must opt in before they are formatted. The opt-in is a block comment with @format or @prettier. The companion flag --insert-pragma adds the marker when a file is formatted. The two flags are used in separate phases: the developers migrate files with --insert-pragma, and the CI enforces formatting on the marked set with --require-pragma. The migration ends when the unmarked set is small enough to format in one commit. The flags are then removed, and Prettier returns to its default behavior of formatting everything.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!