Skip to content

Formatters

@lunibee/formatters provides pure functions for generating Discord-flavoured markdown strings, mention formats, and timestamp displays.

import {
bold, italic, underline, strikethrough, spoiler, inlineCode, codeBlock,
blockQuote, heading, subtext, link, masked,
orderedList, bulletList, escapeMarkdown,
userMention, channelMention, roleMention,
timestamp,
} from "lunibee";
// or directly:
import { bold } from "@lunibee/formatters";

Wraps text in **...**.

bold("Hello, World!") // → "**Hello, World!**"

Wraps text in _..._.

italic("Important note") // → "_Important note_"

Wraps text in __...__.

underline("Underlined") // → "__Underlined__"

Wraps text in ~~...~~.

strikethrough("Deleted") // → "~~Deleted~~"

Wraps text in ||...||.

spoiler("Secret content") // → "||Secret content||"

Wraps text in backticks.

inlineCode("process.env.TOKEN") // → "`process.env.TOKEN`"

Wraps text in a fenced code block.

codeBlock("const x = 1;", "ts") // → "```ts\nconst x = 1;\n```"
codeBlock("plain text") // → "```\nplain text\n```"

Prefixes each line with > .

blockQuote("This is quoted.") // → "> This is quoted."

Creates a markdown heading (level 1–3, default 1).

heading("Server Status", 2) // → "## Server Status"

Creates Discord-style subtext (wraps in -# ...).

subtext("Last updated 3 hours ago") // → "-# Last updated 3 hours ago"

Masks text using the backtick escape for display without markdown parsing.

Escapes all Discord markdown special characters in a string. Useful for displaying user-supplied content.

escapeMarkdown("**Bold** and ~~strikethrough~~")
// → "\\*\\*Bold\\*\\* and \\~\\~strikethrough\\~\\~"

Creates a numbered list.

orderedList("First item", "Second item", "Third item")
// → "1. First item\n2. Second item\n3. Third item"

Creates a bulleted list.

bulletList("Apples", "Oranges", "Bananas")
// → "- Apples\n- Oranges\n- Bananas"

Creates a Markdown hyperlink.

link("Lunibee Docs", "https://lunibee.js.org")
// → "[Lunibee Docs](https://lunibee.js.org)"
link("Hover me", "https://lunibee.js.org", "Official documentation")
// → "[Hover me](https://lunibee.js.org 'Official documentation')"

Creates a <@userId> mention string.

userMention("123456789") // → "<@123456789>"

Creates a <#channelId> mention string.

channelMention("987654321") // → "<#987654321>"

Creates a <@&roleId> mention string.

roleMention("111222333") // → "<@&111222333>"

Creates a Discord timestamp that renders dynamically in each user’s local timezone.

timestamp(Date.now()) // → "<t:1700000000>"
timestamp(new Date(), "R") // → "<t:1700000000:R>"
timestamp(1700000000, "F") // → "<t:1700000000:F>"
Style Example output
"t" 9:30 PM
"T" 9:30:00 PM
"d" 11/14/2023
"D" November 14, 2023
"f" November 14, 2023 9:30 PM
"F" Tuesday, November 14, 2023 9:30 PM
"R" 2 hours ago (relative)

import { bold, italic, codeBlock, timestamp, userMention, bulletList } from "lunibee";
await channel.send({
content: [
`${bold("Welcome")} to the server, ${userMention(userId)}!`,
italic("Please read the rules before chatting."),
"",
`You joined: ${timestamp(joinedAt, "R")}`,
"",
bold("Quick links:"),
bulletList("#rules", "#announcements", "#general"),
].join("\n"),
});