@nicklambourne/slackblocks
v2.2.0
Published
Typed Block Kit construction with eager, path-aware validation
Maintainers
Readme
@nicklambourne/slackblocks
Build Slack messages in TypeScript — without writing JSON by hand.
slackblocks is a typed, validating TypeScript wrapper around the Slack
Block Kit API. It exists because Block Kit JSON is
verbose, easy to get subtly wrong, and unpleasant to maintain in source control.
This release conforms to the shared cross-language slackblocks specification.
Why slackblocks?
- Concise —
SectionBlock().text("Hello, *world*!").build()instead of a 10-line JSON object. - Validated — character limits, required fields, mutually-exclusive options, and
element-type restrictions are enforced at construction time, with a typed error
hierarchy (
LengthError,MissingRequiredError, …), so you find out before hitting Slack's API. - Typed — chainable setters reject typo'd properties and invalid values at compile time;
.build()returns the plain Slack-shaped object, ready for the wire. - Drop-in compatible with the official
@slack/web-apiand Bolt — pass aMessage().build()payload straight toclient.chat.postMessage(payload). - The same library in two languages — the Python
slackblocksshares the blocks, the validation rules, and the version number; a shared conformance corpus keeps both emitting the same Slack JSON. - Self-contained — a single ESM module with no runtime imports.
Installation
npm install @nicklambourne/slackblocksRequires Node 20.19+ or 22.12+. The package ships as ESM; CommonJS consumers
can load it with dynamic import().
Quickstart
import {
ActionsBlock,
Button,
DividerBlock,
HeaderBlock,
Message,
SectionBlock,
} from "@nicklambourne/slackblocks";
const payload = Message()
.channel("#general")
.text("Build #482 passed") // plain-text fallback for notifications
.blocks(
HeaderBlock().text("Build #482 passed :white_check_mark:"),
SectionBlock().fields(
"*Branch*\n`main`",
"*Author*\n@nick",
"*Duration*\n3m 12s",
"*Tests*\n1,247 passed",
),
DividerBlock(),
ActionsBlock().elements(
Button().text("View build").actionId("view").url("https://ci.example.com/482"),
Button().text("Re-run").actionId("rerun").value("482").style("primary"),
),
)
.build();payload can be sent in one line with the official Slack SDK:
import { WebClient } from "@slack/web-api";
const client = new WebClient(process.env.SLACK_API_TOKEN);
await client.chat.postMessage(payload);Builders use idiomatic camelCase setters and return plain Slack-shaped objects with
snake_case keys from .build(). Validation runs when the complete object is built;
pass { validate: false } to .build() only when Slack has moved ahead of this
package's limits registry.
Documentation
- Full docs: https://nicklambourne.github.io/slackblocks/
- Installation
- Using Blocks — every block type with code in both languages, the JSON it produces, and screenshots.
- Sending Messages
- Recipe Book — end-to-end recipes for build notifications, approval requests, modals, and more.
- TypeScript API Reference
- Troubleshooting & FAQ
- Changelog
- Roadmap
Licensing
slackblocks is dual-licensed under
MIT and
BSD-3-Clause.
Use whichever fits your project — this makes it safe to vendor into projects under
either license.
Contributing
Contributions are welcome. The package lives in the typescript/ directory of the
slackblocks monorepo and uses
pnpm:
git clone https://github.com/nicklambourne/slackblocks.git
cd slackblocks
pnpm install
pnpm --filter @nicklambourne/slackblocks testFor the full development guide — testing conventions, the conformance-fixture workflow, and the release process — see the Contributing page.
Bug reports and feature requests: https://github.com/nicklambourne/slackblocks/issues.
