New Component: Button Group

Hello everyone,

I created an Streamlit implementation of the BaseUI Button Group (

My main motivation was to be able to use FontAweseome Icons in Button Labels. Furthermore, it was important to me that I can align the buttons easily left, right, center.

GitHub: flucas96/st_btn_group (
PyPI: st-btn-group · PyPI
Example app: Streamlit Button Group Component · Streamlit (

Primarily, I use these buttons as download buttons. In this mode, they do not return a value and the page does not refresh. The return of a value can be controlled by the return_value parameter.

Some examples:

Button with FontAwesome Icon:

ButtonGroup with 3 Buttons:

Custom CSS Styling:

Example 1:

Example 2:

One thing to note:
The buttons offer three distinct modes, which can be configured through the mode parameter.

  • Default: Acts like a normal button, but unlike Streamlit Buttons, these buttons maintain their value after script re-execution.
  • Radio: Functions as a radio button, where only one button remains active at any given time.
  • Checkbox: Works like a checkbox, enabling the toggling of multiple buttons concurrently.

Maybe someone else will find this useful.

Best regards


Hi @Tian,

Awesome, thanks for sharing! :clap:t5:

1 Like

Hey @Tian,
I have started using your component and I want to ask you if it is possible to return the ‘value’ from the buttons dictionary instead of the index/position of the button that is being clicked on.

My case:

type_options = [{"label": "Bruto",
                     "value": "bruto"},
                    {"label": "Neto",
                     "value": "net"}]
                 align ='left',
                 disabled = False,
                 merge_buttons = True,
                 gap_between_buttons = 0,
                 display_divider = False,
                 return_value = True)


In my use case I would like the returned value to be ‘bruto’ instead of 0.


1 Like

Hi @pablochaure,

I have updated the component to have that behaviour:

You can download the latest version here:

st-btn-group · PyPI

Please let me know if it works for you!

Best regards

Yes!! It works for my use case, thanks for such quick work Tian.

Moreover, would it be hard to implement a default (preselected) value when the mode=‘radio’?

Hi @pablochaure,

I have added the parameter radio_default_index which takes in the index of the button that should be selected by default.

For instance when displaying these buttons:

buttons = [
    {   "label": "Button 1",
        "value": "1",
    {   "label": "Button 2",
        "value": "2",
    {   "label": "Button 3",
        "value": "3",
    {   "label": "Button 4",
        "value": "4",},
    {   "label": "Button 5",
        "value": "5",}

Setting radio_default_index = 1 would preselect Button 2 which means that the component return the value of Button 2 which is 2.

You can download the updated version here:

st-btn-group · PyPI

Best regards

Hey @Tian,

I am having trouble downloading the updated version.

ERROR: st-btn-group has an invalid wheel, st-btn-group has an invalid wheel, multiple .dist-info directories found: st_btn_group-0.0.10.dist-info, st_btn_group-0.0.9.dist-info

Is this something on my end or maybe an issue when uploading to pypi?

Hi @pablochaure,

I have uploaded it again with a new version. The installation seems to work for me now.

pip install st-btn-group==0.0.11

Best regards

Hey there @Tian,

Everything is working for me and those new features make the component great for my use case.

Thanks for your contribution!



1 Like

Glad to hear that you like it!


First of all thank you for your contribution and congratulations for doing such a useful component.

I have been playing with it, and works nicely.

My question is, Is it possible to use it in an streamlit empty()? How?

#I have been checking it and it's possible using
placeholder = st.empty()
with placeholder.container():
    buttons_selection = st_btn_group(...)



Hi @anigmo,

great that you found a solution!

Best regards

@Tian Hey, thanks a lot for this contribution!
I am using this in a chat bot (st.chat_input, st.chat_message) to show a like/dislike option after each response. The issue is, as soon as it reaches the code block for st_btn_group, the app reruns multiple times, that makes it very glitchy. Is there any possible solution for this?

Here I am attaching the code I’m using -

buttons = [
  {"label": "👍",
   "value": "like",
   "style": {"border-radius": "22px", "padding": "1px"}
  {"label": "👎",
   "value": "dislike",
   "style": {"border-radius": "22px", "padding": "1px"}

col = st.columns([92, 8])
with col[1]:
  returned = st_btn_group(buttons=buttons, key=message["query_id"], mode='radio',

Here if you try to store “returned” into a list, it will return “like” or “dislike” multiple times for 1 question.
How do I avoid rerunning?

Thanks in advance!

1 Like

Hey @Tian, thankyou for the solution. I have the case where I need to have st.rerun() once the button is clicked, but in your case the program runs in endless loop. Would it be possible to modify in a way that it behaves as st.button() so that it won’t go in a loop.
The following block creates a problem,

if st_btn_group(
    buttons=[{"label": "<i class='fas fa-home'></i>", "value":"home"}],
    group_style= {"margin-bottom":"22px"}   

while, the following seems working fine.

if st.button("abc"):

Thank you for your time!


Thanks a lot @Tian , Is there a way to customise the color after clicking a radio button? (I am fairly new to programming so I might have missed it.)

Kind regards,