How to Escape Parentheses and Brackets in Markdown

To display a Markdown punctuation character literally, you can put a backslash before it: \(, \), \[, or \]. You usually do not need to escape ordinary parentheses in a sentence. The confusing cases involve link syntax, URLs, and strings that pass through JavaScript before reaching a Markdown renderer.

Open mdview.io and paste one of the examples below to check the rendered result. Check the link destination as well as its visible text.

Markdown source with escaped brackets shown in mdview.io before it is rendered

Ordinary Parentheses Usually Need No Escaping

This sentence is valid Markdown as written:

The staging environment (EU region) is ready.

Parentheses acquire a special role when they follow a link label. To show a complete link expression as literal text, inline code is often clearest:

Use `[label](destination)` to create a link.

If you want ordinary text rather than code styling, escape the brackets that would start the link:

The example is \[label\](destination).

The reader sees the brackets instead of a clickable link. Adding a backslash to every punctuation mark makes source harder to read; apply escaping to the expression that is actually being parsed as syntax.

Parentheses Inside a Link URL

Here are three forms to compare in a CommonMark-compatible renderer:

[Balanced URL](https://example.com/report_(draft))
[Escaped URL](https://example.com/report_\(draft\))
[Angle-bracket URL](<https://example.com/report_(draft)>)

These examples point to an illustrative URL, not a downloadable report. The balanced form can work without escaping. When a URL has unmatched parentheses, backslash escaping or the angle-bracket form makes the destination boundary explicit.

For example, if the destination really ends in a closing parenthesis:

[Report](https://example.com/report\))
[Report](<https://example.com/report)>)

The final parenthesis outside the destination closes the Markdown link. Do not remove punctuation from the real URL just to make the source look tidier.

The CommonMark link specification explains destination parsing and its limits. A renderer using a different dialect can behave differently, so verify in the tool where the document will be read.

Brackets Inside Link Text

Escaping is also useful when the label itself contains a bracket:

[Release \[candidate\]](https://example.com/release)

The rendered label should be “Release [candidate]”. If you only need to display a path, identifier, or short syntax example, use inline code instead of constructing a link.

For images, the same destination issue appears after ![alt text]. Keep the exclamation mark and label intact while fixing the URL. See the Markdown link and image guide for the other link forms.

JavaScript Strings Add Another Escaping Layer

A JavaScript string and a Markdown document are different inputs. To send a literal backslash from an ordinary JavaScript string into Markdown, escape that backslash for JavaScript:

const markdown = "Show \\[label\\](destination) as text.";
console.log(markdown);
// Show \[label\](destination) as text.

Inspect the string that reaches the renderer. Looking only at source code can hide the fact that an earlier step consumed a backslash. The same principle applies when Markdown passes through JSON: inspect the decoded value, not only its serialized representation.

The markdown-escape Package and parentheses

If your search includes the exact words markdown-escape and parentheses, you may be looking for the npm package rather than Markdown syntax. Its documented second argument is a list of character groups to skip escaping:

const escape = require('markdown-escape');

escape('phase (A)');
// Returns text with backslashes before the parentheses.

escape('phase (A)', ['parentheses']);
// Leaves the parentheses unchanged.

That option does not switch on parenthesis escaping; it excludes that group. See the package's own README. A general text escaper is not an HTML sanitizer and does not replace validation of untrusted link destinations.

A Short Debugging Routine

  1. Reduce the problem to one sentence or one link.
  2. Put it in a plain .md file, without a programming-language wrapper.
  3. Preview it and inspect the resulting text and link target.
  4. Add it back to your application and compare the actual string values.

If the plain file works but your application does not, investigate the string-processing step. If both fail, inspect the Markdown syntax and renderer dialect. For a quick visual check, preview the Markdown in your browser.