Design an Expense App with Block Kit

By Shay DeWael

Published: January 14, 2020; Updated: January 31, 2022

This guide will walk you through designing an expense approval app for Slack that uses the Block Kit UI framework.

Whether you're a designer, developer, or just a Slack app enthusiast, we'll walk you through the process: defining your app’s audience, considering what surface areas a Slack app has access to, and laying out the expense approval app using first-party design tools like the Block Kit Builder.

What we'll be designing

Expense reporting app gif

Identifying a Slack app's use cases

Before you begin prototyping a Slack app, you should understand who you’re designing for and why. While we cover outlining a Slack app’s use cases in greater detail on the API site, one way to identify use cases is to reflect on the actions users take frequently with your app (or if your app is Slack-only, what you expect their most frequent actions will be).

For example, if you’re designing an app to submit expenses, you’ll have two primary users:

  1. Someone submitting expenses would want to use your app to quickly fill out an expense report. They’d want to include the amount of the expense, the nature of the expense, and any additional information that is required to submit the expense report, like attaching a receipt.

  2. Someone administering expenses would want to use your app to receive notifications when their reports submit a new expense report. They’d want to quickly look up the expense and have the ability to approve or deny the expense from within Slack. They may also want to navigate out of Slack to your expense app in order to see more details about the report.

Let’s take this example and see how we might design an expense reporting Slack app that aligns with the two users’ primary use cases.

Surface areas for Slack apps

Apps have three different canvases to design for: messages, home tabs, and modals. Each surface serves a unique purpose you should consider in relation to your app’s primary use cases:


Messages exist in the context of channels and direct messages. Whether you’re reaching out to a channel or an individual, apps can use messages to disseminate information and prompt user input.

Tips for designing messages:

  • Keep messages glanceable. Don’t try to fit too much information into a single message. Instead, give the user an option to see more information in a modal or on a 3rd-party site.

  • Include a call to action. What should a user do when they see this message? What action should they take? If they don’t need to take any action, is there any additional information they may want to dive deeper into?

See more tips for designing messages in the API documentation.

Messages can be sent to an expense approver when an expense report is submitted by the approvee (whether through Slack or a third-party app). To fit the approver use case, we’ll want to include approve and deny buttons on incoming expense reports, and give the approver an option to see more details about the report.

Expense approval notification

View in Block Kit Builder

Home tab

Home tabs are persistent, dynamic interfaces that are unique on a per-user basis. This is a great space to surface the main functionality of your app and display the information or data most relevant to an individual user.

Abstract home tab UI

Tips for designing home tabs:

  • Include information on how to use your app. At the top of the home tab, include information on what your app is and how to use it. If your app has many features, consider adding a help button that opens a modal and displays all of your app’s functionality (without crowding the home tab).

  • Surface the primary actions for your app. Near the top of the home tab, surface primary calls-to-action for the user using buttons or another interactive component. Perhaps even use an external select element to implement search for a third-party service.

  • Keep information hierarchical. Similar to other app surfaces, information should be glanceable and actionable. With the larger area of a home tab, you’ll also want to consider how information is ordered. And if there’s an extensive list of information, think about how you may paginate it or make it easier to parse through.

  • Add functionality to customize the home tab or app. If your app has settings like controlling the frequency of notifications sent to a user or togglable features, add a settings button that opens a modal to allow a user to customize how your app works best for them. You could also think about how the user may want to filter or change the information displayed in their home tab.

Now, let’s relate this surface to our expense approval app:

For users filing expense reports, the home tab can be used to prompt users to create expense reports, show pending reports, and list all past reports.

For users that manage and approve expense reports, the home tab can display a list of all pending approvals and a list of all reports and whether they’ve been approved or denied. An edge case here is that approvers may also want to submit their own expenses, so we should make the home tab dynamic enough to allow for a variety of user permissions and roles.

Here’s what a regular user might see in a home tab: Home tab of someone submitted an expense report

View in Block Kit Builder

Here’s what an approver may see in a home tab: Home tab of someone approving expense reports

View in Block Kit Builder


Modals are dedicated windows that allow your app to collect input from users and display dynamic information in a focused space. Modals must be initiated by a user (with features like buttons, slash commands, and other invocative actions).

Tips for designing modals:

  • Keep the goal of the modal in mind. Modals may be used to collect user input, or they may be used to display deeper information about something previewed in a message or in a home tab. When you’re designing a modal, make sure to be intentional about what the purpose of the modal is, and what the user would be hoping to achieve by opening the modal. Remember that a modal is a focused surface area, so users will want to achieve their goal then get back into the context of Slack as fast as possible.

  • Only collect necessary user input. While a modal is helpful for users to input a small amount of input, it may be burdensome to surface every field or customizable option of a form (depending on the use case). Keep the input you’re collecting down to a bare minimum, and employ pagination using buttons if necessary.

  • Use default select elements. Rather than relying on static and external select elements, take a shortcut by using users_select, conversations_select, datepicker, and channels_select elements. This presents an intuitive UI and makes your work easier.

Now, let’s relate this to our expense approval app:

Our app will have two modals: one to collect input from a user when they’re submitting an expense report, and another to display more information about an expense report to the expense approver.

Submit an expense report: Modal to submit expense report

View in Block Kit Builder

Display information about an expense report: Modal to display more information about an expense report

View in Block Kit Builder

Next steps

At this point, you should feel confident approaching different Slack surface areas, and have the real-world example of an expense approval app as a grounding example. To start designing your own Slack app, there are a few resources you may explore:

  • Block Kit Builder contains templates to start designing common use cases for Slack apps. They’re a great starting point to begin building your own Slack app.
  • The Start Hub gives you high-level guidelines to plan and design Slack apps, like defining voice and tone of an app and designing onboarding experiences.
  • Figma templates are Figma files that contain UI surfaces and components that can aid in prototyping your app in Figma.
  • Bolt is a lightweight development framework that streamlines building Slack apps using the newest platform features and surface areas, available in JavaScript, Python and Java.

This guide only covered the basics of designing with different surface areas of a Slack app. As more blocks are released and you iterate on your app’s design, keep your users in mind and your blocks aligned.

Questions? Comments? Contact our developer support at @SlackAPI or

Related documentation

Was this page helpful?