Lightweight, zero-dependency JavaScript library for Slack Block Kit UI.
View the Docs »
Quick Start Guide
·
Request Feature
·
Report Bug
Block Builder helps you keep your Slack app code for UI maintainable, testable, and reusable. It has a simple builder syntax inspired by SwiftUI and lets you code the way you want to code.
printPreviewURL()
method that outputs to the console a link to preview your UI on Slack's Block Kit Builder website.Feedback – love it! Aside from GitHub Issues, there are Slack channels available in popular bot communities to discuss Block Builder – we'll see you there! 🙌
npm install --save slack-block-builder
yarn add slack-block-builder
For full documentation, make sure you head over to https://blockbuilder.dev.
At the top level of the library, there are a few objects exposed for import. You'll be using these to build out your UI:
import { Message, Blocks, Elements, Bits } from 'slack-block-builder';
In place of Message
, you can also import Modal
, HomeTab
, or WorkflowStep
.
Modal
– Used to create a modal surface.
Message
– Used to create a message surface.
HomeTab
– Used to create a home tab surface.
WorkflowStep
– Used to create a workflow step surface.
Note that since you'll more often only be working with one surface per file, they are exposed individually, whereas the rest of the objects are grouped into categories.
Blocks
– Layout blocks used to organize the UI.
Elements
– UI elements that are used to capture user interaction.
Bits
– These are composition objects and other bits and pieces from Slack's docs. Included are Attachment
, Options
, OptionGroup
, and ConfirmationDialog
. They felt like they were deserving of their own category.
Below is a list of supported objects and how to access them in Block Builder:
Name | Type | Support | Accessed Via |
---|---|---|---|
Home Tab | Surface | ✅ | HomeTab() |
Message | Surface | ✅ | Message() |
Modal | Surface | ✅ | Modal() |
Workflow Step | Surface | ✅ | WorkflowStep() |
Actions | Block | ✅ | Blocks.Actions() |
Context | Block | ✅ | Blocks.Context() |
Divider | Block | ✅ | Blocks.Divider() |
File | Block | ✅ | Blocks.File() |
Header | Block | ✅ | Blocks.Header() |
Image | Block | ✅ | Blocks.Image() |
Input | Block | ✅ | Blocks.Input() |
Section | Block | ✅ | Blocks.Section() |
Button | Element | ✅️ | Elements.Button() |
Checkboxes | Element | ✅ | Elements.Checkboxes() |
Date Picker | Element | ✅ | Elements.DatePicker() |
Time Picker | Element | ✅ | Elements.TimePicker() |
Image | Element | ✅ | Elements.Img() |
Overflow Menu | Element | ✅ | Elements.OverflowMenu() |
Radio Buttons | Element | ✅ | Elements.RadioButtons() |
Plain-Text Input | Element | ✅ | Elements.TextInput() |
Select Menus | Element | ✅ | Elements.[Type]Select() |
Multi-Select Menus | Element | ✅ | Elements.[Type]MultiSelect() |
Option | Composition Object | ✅ | Bits.Option() |
Confirm Dialog | Composition Object | ✅ | Bits.ConfirmationDialog() |
Option Group | Composition Object | ✅ | Bits.OptionGroup() |
Attachment | Legacy Feature | ✅ | Bits.Attachment() |
Let's take a look at how to compose an interactive message. Even though Slack now has modals, these have always been the basis for Slack apps.
We can create a piece of UI using only the setter methods:
import { Message, Blocks, Elements } from 'slack-block-builder';
const myMessage = ({ channel }) => {
return Message()
.channel(channel)
.text('Alas, my friend.')
.blocks(
Blocks.Section()
.text('One does not simply walk into Slack and click a button.'),
Blocks.Section()
.text('At least that\'s what my friend Slackomir said ⚔️'),
Blocks.Divider(),
Blocks.Actions()
.elements(
Elements.Button()
.text('Sure One Does')
.actionId('gotClicked')
.danger(),
Elements.Button()
.text('One Does Not')
.actionId('scaredyCat')
.primary()))
.asUser()
.buildToJSON();
};
Alternatively (and preferably), we can combine both the setter methods and the params to shorten it:
import { Message, Blocks, Elements } from 'slack-block-builder';
const myShorterMessage = ({ channel }) => {
return Message({ channel, text: 'Alas, my friend.' })
.blocks(
Blocks.Section({ text: 'One does not simply walk into Slack and click a button.' }),
Blocks.Section({ text: 'At least that\'s what my friend Slackomir said ⚔️' }),
Blocks.Divider(),
Blocks.Actions()
.elements(
Elements.Button({ text: 'Sure One Does', actionId: 'gotClicked' })
.danger(),
Elements.Button({ text: 'One Does Not', actionId: 'scaredyCat' })
.primary()))
.asUser()
.buildToJSON();
};
Both of these examples render the message below. And the best part? It only took 15 lines of code, as opposed to the 44 lines of JSON generated as a result.
View Example on Slack Block Kit Builder Website
Let's take a look at how modals are created.
Here we'll also take a look at working with Bits. You'll see in this example that we're hardcoding the options in the select menu. There are, of course, better ways to handle that, by using the Array.map()
method, but they are listed here separately to demonstrate the usage.
First, an example using just our setter methods:
import { Modal, Blocks, Elements, Bits } from 'slack-block-builder';
const myModal = () => {
return Modal()
.title('PizzaMate')
.blocks(
Blocks.Section()
.text('Hey there, colleague!'),
Blocks.Section()
.text('Hurray for corporate pizza! Let\'s get you fed and happy 🍕'),
Blocks.Input()
.label('What can we call you?')
.element(
Elements.TextInput()
.placeholder('Hi, my name is... (What?!) (Who?!)')
.actionId('name')),
Blocks.Input()
.label('Which floor are you on?')
.element(
Elements.TextInput()
.placeholder('HQ – Fifth Floor')
.actionId('floor')),
Blocks.Input()
.label('What\'ll you have?')
.element(
Elements.StaticSelect()
.placeholder('Choose your favorite...')
.actionId('item')
.options(
Bits.Option().text(':cheese_wedge: With Cheeze').value('012'),
Bits.Option().text('🐟 With Anchovies').value('013'),
Bits.Option().text('🍪 With Scooby Snacks').value('014'),
Bits.Option().text('🍺 I Prefer Steak and Beer').value('015'))))
.submit('Get Fed')
.buildToJSON();
};
Alternatively (and preferably), we can combine both the setter methods and the params to shorten it:
import { Modal, Blocks, Elements, Bits } from 'slack-block-builder';
const myShorterModal = () => {
return Modal({ title: 'PizzaMate', submit: 'Get Fed' })
.blocks(
Blocks.Section({ text: 'Hey there, colleague!' }),
Blocks.Section({ text: 'Hurray for corporate pizza! Let\'s get you fed and happy 🍕' }),
Blocks.Input({ label: 'What can we call you?' })
.element(
Elements.TextInput({ placeholder: 'Hi, my name is... (What?!) (Who?!)' })
.actionId('name')),
Blocks.Input({ label: 'Which floor are you on?' })
.element(
Elements.TextInput({ placeholder: 'HQ – Fifth Floor' })
.actionId('floor')),
Blocks.Input({ label: 'What\'ll you have?' })
.element(
Elements.StaticSelect({ placeholder: 'Choose your favorite...' })
.actionId('item')
.options(
Bits.Option({ text: ':cheese_wedge: With Cheeze', value: '012' }),
Bits.Option({ text: '🐟 With Anchovies', value: '013' }),
Bits.Option({ text: '🍪 With Scooby Snacks', value: '014' }),
Bits.Option({ text: '🍺 I Prefer Steak and Beer', value: '015' }))))
.buildToJSON();
};
Both of these examples render the modal below.
View Example on Slack Block Kit Builder Website
Bolt for JavaScript – A simple framework for building Slack apps, developed by Slack themselves.
Node Slack SDK – A great and powerful SDK for building Slack Apps from the ground up.
JSX-Slack – Awesome way to create Slack Block Kit UIs using JSX.
Taras Neporozhniy (@bravecow) - For mentorship over the years!
Alexey Chernyshov (@ft502 on Dribbble) - For such a beautiful logo!
SlackHQ (@slackhq) - For such a wonderful product and API!
Ray East (@raycharius) - Huge Fan of Slack and Block Builder Maintainer