Prose

Installation

import { Prose } from "@o/pipeline/experimental/components/prose";

Usage

Default

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Comfortable

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Sensible Max Width

By default, Prose, doesn’t impose any width constraints, but it does offer a max-width optimized for legibility.

<Prose maxWidth />

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Removing Default Color

By default, Prose sets opinionated defaults. This can be overridden where necessary.

<Prose color={false} className="text-cornflower" />

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Sandboxing

To isolate content from the outer Prose, you can use the unset prop to opt out of prose styling.

Because each .prose element roots its own scope, you can nest a new <Prose /> (or anything that renders one internally, like Editor) inside a <Prose unset /> block — it starts a fresh scope and styles normally, and nesting can continue to any depth (prosenot-proseprose → …).

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Sandbox Inception

Unlike @tailwindcss/typography, Prose can be unset and redefined within itself, infinitely.

View deep nested example

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Heading 1

Heading 2

Heading 3

Paragraph with bold, italic, underlined, and strikethrough text.

Paragraph with code, bold code, italic code, bold italic code, underline code, strikethrough code, and linked code.

Paragraph with link, bold link, italic link, bold italic link, underline link, strikethrough link, followed by a horizontal rule.


  • List item
  • List item
  • List item
    • List item
    • List item
      1. List item
      2. List item
  • List item

  1. List item
  2. List item
    1. List item
    2. List item
      • List item
      • List item
  3. List item

Blockquote

import { Prose } from "@o/pipeline/experimental/components/prose";

export default function Example() {
  return <Prose />;
}

Implementation Details

Parity with @tailwindcss/typography

prose.css is a handwritten replacement for the @tailwindcss/typography plugin — every element the plugin’s default theme styled is carried over, including ones we don’t otherwise use (see Unsupported Elements below). The exception is ol[type] numbering, which never had any visible effect (see below). Not carried over, because nothing in the app ever used them: the prose-sm/base/lg/xl/2xl size modifiers (replaced by the comfortable prop), the color themes (prose-gray, prose-slate, …), prose-invert dark mode, and the consumer-facing prose-*: element variants (e.g. prose-h1:) — style descendants with plain selectors instead ([&_h1]:…).

“Unsupported” Elements

The following elements work with Prose, but aren’t styled according to our branding guidelines — use with caution.

  • code
  • pre
  • kbd
  • h4, h5, and h6
  • dl, dt, and dd
  • figure, figcaption, and picture
  • img
  • video
  • table, thead, tr, th, td, and tbody
  • <p class="lead"> (a larger intro paragraph)

<ol type="A" | "a" | "I" | "i" | "1"> numbering isn’t supported — Slack-style ordered lists always number 1 → a → i by nesting depth.

See OP-2192: Design for (or disable) additional elements within Prose for more details.

A lead paragraph that introduces the section below.

Heading 4

Heading 5
Heading 6

Press K to open the command menu, then a bold link follows.

Term
The definition of the term.
Another term
Its definition.
  1. Upper-alpha item
  2. Upper-alpha item
  1. Lower-alpha item
  2. Lower-alpha item
  1. Upper-roman item
  2. Upper-roman item
  1. Lower-roman item
  2. Lower-roman item
  1. Decimal item
  2. Decimal item

Adjacent element resets

NameRole
Ada with inline codeEngineer
GraceAdmiral
Total2

After an hr
Cell
Placeholder
A figure caption.