{
  "$type": "site.standard.document",
  "content": {
    "$type": "blog.pckt.content",
    "items": [
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://github.com/github/markup"
              }
            ],
            "index": {
              "byteEnd": 196,
              "byteStart": 183
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://github.com/rust-lang/mdBook"
              }
            ],
            "index": {
              "byteEnd": 204,
              "byteStart": 198
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://jekyllrb.com/"
              }
            ],
            "index": {
              "byteEnd": 215,
              "byteStart": 209
            }
          }
        ],
        "plaintext": "As a software developer, when I'm learning a new language, framework, or tool, more of my time is spent reading documentation than actually writing something.\nMany doc renderers like GitHub Markup, mdBook, or Jekyll make the experience great for everyone.\nDocumentation authors get to write in Markdown and readers get to consume it like a web page."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "One very convenient feature of many Markdown renderers is a little \"copy\" button in the top right corner of code blocks.\nIt automatically copies the code to your clipboard so you can quickly paste it in your terminal or code editor.\nHere's an example of some code blocks in GitHub with the wonderful copy button."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "Some sites (like Whtwnd apparently) do not include a copy button, which is unfortunate but it's not a huge deal.\nI can still easily triple click to select the whole line and copy it.\nTry it yourself."
      },
      {
        "$type": "blog.pckt.block.codeBlock",
        "attrs": {
          "language": "bash"
        },
        "plaintext": "npm install -D typescript\n"
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 2,
        "plaintext": "The problem"
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#bold"
              }
            ],
            "index": {
              "byteEnd": 195,
              "byteStart": 192
            }
          }
        ],
        "plaintext": "Markdown is amazing and it makes everyone's lives easier.\nBut it's only as convenient as the authors choose to make it, and some authors neglect the user experience. Here's an example of what not to do, in my opinion."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "(Try to triple click this one too)"
      },
      {
        "$type": "blog.pckt.block.codeBlock",
        "attrs": [],
        "plaintext": "$ npm install pino\n"
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 140,
              "byteStart": 139
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 278,
              "byteStart": 277
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://superuser.com/questions/57575/what-is-the-origin-of-the-unix-dollar-prompt"
              }
            ],
            "index": {
              "byteEnd": 409,
              "byteStart": 391
            }
          }
        ],
        "plaintext": "Authors that want to indicate that a line of code is a command to be run in a terminal will often do that by prepending the command with a $.\nIt looks pretty innocent, you've probably seen dozens of examples of it, and it may as well be industry-standard to include the little $ to communicate a bash command.\nIf you want to know more about why it's a dollar sign, you can read more on this superuser question asked over 15 years ago."
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 244,
              "byteStart": 243
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 363,
              "byteStart": 337
            }
          }
        ],
        "plaintext": "My problem with it is that it completely eliminates the usefulness of the copy button.\nThe dollar sign is included in the text of the code block, meaning it's copyable and selectable.\nSo I also can't triple-click because it'd still select the $ at the front.\nIf I were to paste that text in my terminal, I'd get an error that looks like bash: command not found: $."
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 341,
              "byteStart": 337
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 351,
              "byteStart": 345
            }
          }
        ],
        "plaintext": "The frustrating next step is to press the up arrow in your terminal to recall the previous command, then move the cursor all the way to the left just to delete that ridiculous character.\nMost terminals do not allow you to use your mouse to move the cursor around, and some terminals don't even allow you skip over whole words by holding Ctrl or Option, depending on your OS.\nSo if you've just pasted a long or multi-line command, you must suffer."
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#italic"
              }
            ],
            "index": {
              "byteEnd": 27,
              "byteStart": 22
            }
          }
        ],
        "plaintext": "In these situations I could just carefully select only the command I want to copy."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#italic"
              }
            ],
            "index": {
              "byteEnd": 50,
              "byteStart": 47
            }
          }
        ],
        "plaintext": "But I'm lazy, and authors could just as easily not include the symbol in the first place.\nSites like GitHub have recognized that it's annoying to manually select text in a code block to copy it, so that's why the copy button exists.\nCatering to the lazy developers is part of the point of docs, tutorials, and quickstart guides."
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 1,
        "plaintext": "The solution"
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 5,
              "byteStart": 4
            }
          }
        ],
        "plaintext": "The $ only exists to communicate that it's a bash command.\nThere are other ways to communicate this without including the symbol in the code block text."
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 70,
              "byteStart": 69
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://nextui.org/docs/components/snippet#usage"
              }
            ],
            "index": {
              "byteEnd": 100,
              "byteStart": 81
            }
          },
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 111,
              "byteStart": 110
            }
          }
        ],
        "plaintext": "I've seen some sites that render the code block with an unselectable $.\nHere's a NextUI code snippet with the $ built into the UI."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "This is a fine solution, but unfortunately it isn't very common and it's made with a React component, not standard Markdown."
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#code"
              }
            ],
            "index": {
              "byteEnd": 13,
              "byteStart": 12
            }
          }
        ],
        "plaintext": "I think the $ is outdated and it doesn't communicate anything to newer developers anyway.\nCan we just get rid of it completely?"
      },
      {
        "$type": "blog.pckt.block.text",
        "facets": [
          {
            "features": [
              {
                "$type": "blog.pckt.richtext.facet#link",
                "uri": "https://spec.commonmark.org/0.31.2/#info-string"
              }
            ],
            "index": {
              "byteEnd": 101,
              "byteStart": 90
            }
          }
        ],
        "plaintext": "Yes.\nCommonMark code blocks allow the author to specify the language of the code using an info string.\nMost Markdown renderers include syntax highlighting for all the popular languages, you just have to tell it which language.\nCode blocks are created by surrounding a block of text with a pair of triple backticks (```).\nAfter the first pair, you can include the name of the language."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.codeBlock",
        "attrs": {
          "language": "bash"
        },
        "plaintext": "echo Hello World\n"
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "Some renderers also bake the info string into the code block UI component so there's no ambiguity."
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": "This is my favorite solution.\nIt requires the author to be more precise about what kind of code it is without contaminating the selectable text of the code block.\nWhile it's not widely adopted among Markdown renderers yet, it totally could be.\nIt uses a basic syntax feature that nearly every Markdown flavor supports and it makes code easier for readers to consume."
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 1,
        "plaintext": "My plea"
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 2,
        "plaintext": "To Markdown authors"
      },
      {
        "$type": "blog.pckt.block.bulletList",
        "content": [
          {
            "$type": "blog.pckt.block.listItem",
            "content": [
              {
                "$type": "blog.pckt.block.text",
                "plaintext": "Always include the language info string on your code blocks.\nThere's no reason not to."
              }
            ]
          },
          {
            "$type": "blog.pckt.block.listItem",
            "content": [
              {
                "$type": "blog.pckt.block.text",
                "facets": [
                  {
                    "features": [
                      {
                        "$type": "blog.pckt.richtext.facet#code"
                      }
                    ],
                    "index": {
                      "byteEnd": 16,
                      "byteStart": 15
                    }
                  },
                  {
                    "features": [
                      {
                        "$type": "blog.pckt.richtext.facet#code"
                      }
                    ],
                    "index": {
                      "byteEnd": 19,
                      "byteStart": 18
                    }
                  },
                  {
                    "features": [
                      {
                        "$type": "blog.pckt.richtext.facet#code"
                      }
                    ],
                    "index": {
                      "byteEnd": 22,
                      "byteStart": 21
                    }
                  },
                  {
                    "features": [
                      {
                        "$type": "blog.pckt.richtext.facet#code"
                      }
                    ],
                    "index": {
                      "byteEnd": 25,
                      "byteStart": 24
                    }
                  }
                ],
                "plaintext": "Stop including $, >, %, #, or any other prompt symbol that a reader wouldn't want to copy."
              }
            ]
          }
        ]
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 2,
        "plaintext": "To Markdown renderer devs"
      },
      {
        "$type": "blog.pckt.block.bulletList",
        "content": [
          {
            "$type": "blog.pckt.block.listItem",
            "content": [
              {
                "$type": "blog.pckt.block.text",
                "plaintext": "Add the \"copy\" button to the code block if you haven't already."
              }
            ]
          },
          {
            "$type": "blog.pckt.block.listItem",
            "content": [
              {
                "$type": "blog.pckt.block.text",
                "plaintext": "Include the info string somewhere too."
              }
            ]
          }
        ]
      },
      {
        "$type": "blog.pckt.block.heading",
        "level": 2,
        "plaintext": "To readers of Markdown docs"
      },
      {
        "$type": "blog.pckt.block.bulletList",
        "content": [
          {
            "$type": "blog.pckt.block.listItem",
            "content": [
              {
                "$type": "blog.pckt.block.text",
                "plaintext": "Keep being lazy."
              }
            ]
          }
        ]
      },
      {
        "$type": "blog.pckt.block.text",
        "plaintext": ""
      }
    ]
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreigufcgi2lh75fqvem3okjt7zinqkax2ljul4zieozk7hgbbov3egq"
    },
    "mimeType": "image/png",
    "size": 71341
  },
  "description": "As a software developer, when I'm learning a new language, framework, or tool, more of my time is spent reading documentation than actually writing something. Many doc renderers like GitHub Markup, mdBook, or Jekyll make the experience great for everyone. Documentation authors get to write in Markdown and readers get to consume it like a web page. One very convenient feature of many Markdown renderers is a little copy button in the top right corner of code blocks. It automatically copies the cod...",
  "path": "/stop-using-in-code-blocks-grd55y6",
  "publishedAt": "2025-01-29T05:04:23+00:00",
  "site": "at://did:plc:fgdxbgj53uq3km3jiovqb3ex/site.standard.publication/3mcqnrjpw42ej",
  "tags": [],
  "textContent": "As a software developer, when I'm learning a new language, framework, or tool, more of my time is spent reading documentation than actually writing something.\nMany doc renderers like GitHub Markup, mdBook, or Jekyll make the experience great for everyone.\nDocumentation authors get to write in Markdown and readers get to consume it like a web page.\nOne very convenient feature of many Markdown renderers is a little \"copy\" button in the top right corner of code blocks.\nIt automatically copies the code to your clipboard so you can quickly paste it in your terminal or code editor.\nHere's an example of some code blocks in GitHub with the wonderful copy button.\nSome sites (like Whtwnd apparently) do not include a copy button, which is unfortunate but it's not a huge deal.\nI can still easily triple click to select the whole line and copy it.\nTry it yourself.\nnpm install -D typescript\n\nThe problem\nMarkdown is amazing and it makes everyone's lives easier.\nBut it's only as convenient as the authors choose to make it, and some authors neglect the user experience. Here's an example of what not to do, in my opinion.\n(Try to triple click this one too)\n$ npm install pino\n\nAuthors that want to indicate that a line of code is a command to be run in a terminal will often do that by prepending the command with a $.\nIt looks pretty innocent, you've probably seen dozens of examples of it, and it may as well be industry-standard to include the little $ to communicate a bash command.\nIf you want to know more about why it's a dollar sign, you can read more on this superuser question asked over 15 years ago.\nMy problem with it is that it completely eliminates the usefulness of the copy button.\nThe dollar sign is included in the text of the code block, meaning it's copyable and selectable.\nSo I also can't triple-click because it'd still select the $ at the front.\nIf I were to paste that text in my terminal, I'd get an error that looks like bash: command not found: $.\nThe frustrating next step is to press the up arrow in your terminal to recall the previous command, then move the cursor all the way to the left just to delete that ridiculous character.\nMost terminals do not allow you to use your mouse to move the cursor around, and some terminals don't even allow you skip over whole words by holding Ctrl or Option, depending on your OS.\nSo if you've just pasted a long or multi-line command, you must suffer.\nIn these situations I could just carefully select only the command I want to copy.\nBut I'm lazy, and authors could just as easily not include the symbol in the first place.\nSites like GitHub have recognized that it's annoying to manually select text in a code block to copy it, so that's why the copy button exists.\nCatering to the lazy developers is part of the point of docs, tutorials, and quickstart guides.\nThe solution\nThe $ only exists to communicate that it's a bash command.\nThere are other ways to communicate this without including the symbol in the code block text.\nI've seen some sites that render the code block with an unselectable $.\nHere's a NextUI code snippet with the $ built into the UI.\nThis is a fine solution, but unfortunately it isn't very common and it's made with a React component, not standard Markdown.\nI think the $ is outdated and it doesn't communicate anything to newer developers anyway.\nCan we just get rid of it completely?\nYes.\nCommonMark code blocks allow the author to specify the language of the code using an info string.\nMost Markdown renderers include syntax highlighting for all the popular languages, you just have to tell it which language.\nCode blocks are created by surrounding a block of text with a pair of triple backticks (```).\nAfter the first pair, you can include the name of the language.\necho Hello World\n\nSome renderers also bake the info string into the code block UI component so there's no ambiguity.\nThis is my favorite solution.\nIt requires the author to be more precise about what kind of code it is without contaminating the selectable text of the code block.\nWhile it's not widely adopted among Markdown renderers yet, it totally could be.\nIt uses a basic syntax feature that nearly every Markdown flavor supports and it makes code easier for readers to consume.\nMy plea\nTo Markdown authors\nAlways include the language info string on your code blocks.\nThere's no reason not to.\nStop including $, >, %, #, or any other prompt symbol that a reader wouldn't want to copy.\nTo Markdown renderer devs\nAdd the \"copy\" button to the code block if you haven't already.\nInclude the info string somewhere too.\nTo readers of Markdown docs\nKeep being lazy.",
  "title": "Stop Using '$' in Code Blocks",
  "updatedAt": "2026-06-12T16:27:14+00:00"
}