⚡️ A tmux plugin giving you a hackable status bar consisting of dynamic & beautiful looking powerline segments, written purely in bash.
Shell
3,841
1,145 commits
updated Oct 8, 2026
Empowering your tmux (status bar) experience!
including these top contributors:
tmux-powerline is a tmux tpm plugin that gives you a slick and hackable powerline status bar consisting of segments. It's easily extensible with custom segments and themes. The plugin itself is implemented purely in bash, thus minimizing system requirements. However, you can make segments in any language you want (with a shell wrapper).
Some examples of segments available that you can add to your tmux status bar are (full list here):
Full screenshot
left-status
Current tmux session, window, pane, hostname, and LAN & WAN IP address.

right-status
New mails, now playing, average load, weather, date, and time.

Now I've read my inbox, thus the mail segment disappears!

After pausing the music, there's no need to show the Now Playing segment anymore. Also, the weather has become much nicer!

Laptop mode: a battery segment.

dual-line status

@xx4h is helping out with developing, maintaining, and managing this project!
Requirements for the lib to work are:
tmux -V >= 2.9bash --version >= 3.2 (Does not have to be your default shell.)config.sh.Some segments have their own requirements. If you enable them in your theme, make sure all requirements are met for those.
jq, curl and ccusage (only if you enable the accumulated cost display)lm_sensors for Linux, smctemp for Macosdropbox-clijq, curlifstat (there is a simpler segment ifstat_sys.sh not using ifstat)wgetjq, curljq, curl >= 7.55, and a dedicated free Live Tennis API keycurljq, curlAdd "tennis 24 255" to your theme's status segments and set
TMUX_POWERLINE_SEG_TENNIS_API_KEY in your private configuration file. Optionally set
TMUX_POWERLINE_SEG_TENNIS_PLAYER to a player or doubles-team name substring. This
filter is applied locally. Protect the configuration file with chmod 600.
The segment shows the first matching live match, its set scores and available points,
plus the snapshot age in minutes. TB marks tiebreak points; a tiebreak score
repeated in the current set slot is shown once in brackets. [stale score]
preserves the provider's staleness warning. Additional matches on
this page are counted; [more] indicates that the API has another page. The segment
fetches only the first 100 matches and does not paginate. An unknown score is shown
as unavailable, rather than as 0-0.
This is a snapshot refreshed at most every 15 minutes. It uses only the free live
matches endpoint and needs no paid plan. All instances for the same local user share
one cache at ${TMUX_POWERLINE_DIR_TEMPORARY}/tennis, alongside the other segments.
The fixed 900-second minimum between attempts includes failed requests, limiting the
segment to 96 requests/day. When the temporary cache is missing (including after a
reboot or cleanup), the segment waits a full 15 minutes before requesting a snapshot
and shows Tennis: waiting for request window. Clearing the cache therefore cannot
force an early update. Use a dedicated key: requests from other applications or
computers also consume the key's 100/day allowance.
Network requests run in the background. If the first fetch fails the segment shows
Tennis: unavailable; later failures retain the last snapshot with its age.
No key means no output or network request. If a process is forcibly killed and leaves
refresh.lock behind, stop the segment and remove that empty directory to resume;
keep last_attempt so the budget remains intact.
Run the offline regression checks with bash tests/tennis.sh.
weather.sh refreshes in the background and shares its cache between all local tmux
clients. It makes at most one GeoIP or MET Weather API attempt per configured
TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD (600 seconds by default). Shorter,
zero, negative, and invalid values cannot reduce the 600-second MET minimum.
Response cache headers can defer a refresh further; failed requests use a
conservative retry delay, retain the last successfully displayed weather, and leave
the segment blank until the first successful refresh.
Weather data and request eligibility are stored under
${TMUX_POWERLINE_DIR_TEMPORARY}. The segment records eligibility before making a
request, so a missing or unwritable local state directory suppresses requests rather
than retrying for every status render. Removing local state can cause one recovery
request once state can be written; it does not bypass the provider's minimum
interval.
Install tpm and make sure it's working.
Install tmux-powerline as a plugin by adding a line to tmux.conf:
set -g @plugin 'erikw/tmux-powerline'
Install the plugin with <prefix>I, unless you changed tpm's keybindings.
Continue to the Configuration section below.
[!NOTE] Note that tpm plugins should be at the bottom of your
tmux.conf. This plugin will then override some tmux settings likestatus-left,status-right, etc. If you had already set those in your tmux config, it is a good opportunity to remove or comment them out. Take a look at main.tmux for exactly which settings are overridden.
tmux-powerline stores the custom config, themes, and segments at $XDG_CONFIG_HOME/tmux-powerline/.
To make the following example easier, let's assume the following:
$XDG_CONFIG_HOME has the default value of ~/.config~/.config/tmux/plugins/tmux-powerlineAdapt the commands below if your paths differ from this.
Start by generating your own configuration file:
~/.config/tmux/plugins/tmux-powerline/generate_config.sh
mv ~/.config/tmux-powerline/config.sh.default ~/.config/tmux-powerline/config.sh
$EDITOR ~/.config/tmux-powerline/config.sh
Go through the default config and adjust it to your needs!
The theme is specified by setting the environment variable $TMUX_POWERLINE_THEME in the config file above. It will use a default theme, and you probably want to use your own. The default config has set the custom theme path to be ~/.config/tmux-powerline/themes/.
Make a copy of the default theme and make your own, say my-theme:
mkdir -p ~/.config/tmux-powerline/themes
cp ~/.config/tmux/plugins/tmux-powerline/themes/default.sh ~/.config/tmux-powerline/themes/my-theme.sh
$EDITOR ~/.config/tmux-powerline/themes/my-theme.sh
[!IMPORTANT] Remember to update the configuration file to use the new theme by setting
TMUX_POWERLINE_THEME=my-theme
In the same way as themes, you can create your own segments at TMUX_POWERLINE_DIR_USER_SEGMENTS which defaults to ~/.config/tmux-powerline/segments.
To get started, copy an existing segment that is similar to the segment that you want to create.
mkdir -p ~/.config/tmux-powerline/segments
cp ~/.config/tmux/plugins/tmux-powerline/segments/date.sh ~/.config/tmux-powerline/segments/my-segment.sh
$EDITOR ~/.config/tmux-powerline/segments/my-segment.sh
Now you can add my-segment to your own theme!
Also see How to make a segment below for more details.
Some segments might not work on your system for various reasons, such as missing programs or different versions not having the same options. To find out which segment is not working, it may help to enable the debug setting in ~/.config/tmux-powerline/config.sh.
Next step would be to enable the error logging in general or even with a scope, see TMUX_POWERLINE_ERROR_LOGS_ENABLED and TMUX_POWERLINE_ERROR_LOGS_SCOPES in your config.
However, this may not be enough to determine the error, so you can inspect all executed bash commands (will be a long output) by doing
bash -x powerline.sh (left|right)
For a quick diagnostics snapshot of your local setup, run:
./doctor.sh
This prints resolved tmux-powerline paths and settings, active segment/theme configuration, and live tmux status options when a tmux server is reachable.
To debug smaller portions of code, say if you think the problem lies in a specific segment, insert these lines at the top and bottom of the relevant code portions e.g., inside a function:
set -x
exec 2>/tmp/tmux-powerline.log
<code to debug>
set +x
and then inspect the outputs like
less /tmp/tmux-powerline.log
tail -f /tmp/tmux-powerline.log # or follow output like this.
You can also enable the debug mode in your config file. Look for the TMUX_POWERLINE_DEBUG_MODE_ENABLED environment variable and set it to true.
If you can not solve the problems, you can post an issue and be sure to include relevant information about your system and script output (from ./doctor.sh and/or bash -x) and/or screenshots if needed.
Be sure to search in the resolved issues section for similar problems you're experiencing before posting.
You have edited ~/.tmux.conf, but no powerline is displayed. This might be because tmux is not aware of the changes, so you have to restart your tmux session or reload that file by typing this on the command line (or in tmux command mode with prefix :)
tmux source-file ~/.tmux.conf
If your tmux looks like this, then you may have to, in iTerm, uncheck [Unicode East Asian Ambiguous characters are wide] in Preferences -> Settings -> Advanced.
[!IMPORTANT] Please read and follow the CONTRIBUTING.md guidelines!
This project can only gain positively from contributions. Fork today and make your own enhancements and segments to share back!
You can fork this project and then start coding right away with GitHub Codespaces, as this project is set up to install all development dependencies and install tmux-powerline on the devcontainer. See devcontainer.json and devcontainer_postCreateCommand.sh. After starting the devcontainer, just type tmux in the terminal, and you should see a working tmux-powerline already to start playing with.
[!IMPORTANT] If you have set up your own dotfiles to be installed with GitHub Codespaces, and there were some tmux config files installed from your dotfiles to the devcontainer, then you might have to run this script to wipe your config in favour of the setup provided by this repo's initialization:
./scripts/devcontainer_postCreateCommand.sh
Please section How To Make a Segment at CONTRIBUTING.md.
Create a new version of this project by using semver-cli.
vi CHANGELOG.md
semver up minor
ver=$(semver get release)
git commit -am "Bump version to $ver" && git tag $ver && git push --atomic origin main $ver
I have another tmux plugin that might interest you:
(top 24 of 45)
1,980 followers · starred Dec 2015
1,030 followers · starred Jun 2012
1,674 followers · starred May 2025
124 followers · starred Aug 2019
⚡️ A tmux plugin giving you a hackable status bar consisting of dynamic & beautiful looking powerline segments, written purely in bash.
Shell
3,841
1,145 commits
updated Oct 8, 2026
Empowering your tmux (status bar) experience!
including these top contributors:
tmux-powerline is a tmux tpm plugin that gives you a slick and hackable powerline status bar consisting of segments. It's easily extensible with custom segments and themes. The plugin itself is implemented purely in bash, thus minimizing system requirements. However, you can make segments in any language you want (with a shell wrapper).
Some examples of segments available that you can add to your tmux status bar are (full list here):
Full screenshot
left-status
Current tmux session, window, pane, hostname, and LAN & WAN IP address.

right-status
New mails, now playing, average load, weather, date, and time.

Now I've read my inbox, thus the mail segment disappears!

After pausing the music, there's no need to show the Now Playing segment anymore. Also, the weather has become much nicer!

Laptop mode: a battery segment.

dual-line status

@xx4h is helping out with developing, maintaining, and managing this project!
Requirements for the lib to work are:
tmux -V >= 2.9bash --version >= 3.2 (Does not have to be your default shell.)config.sh.Some segments have their own requirements. If you enable them in your theme, make sure all requirements are met for those.
jq, curl and ccusage (only if you enable the accumulated cost display)lm_sensors for Linux, smctemp for Macosdropbox-clijq, curlifstat (there is a simpler segment ifstat_sys.sh not using ifstat)wgetjq, curljq, curl >= 7.55, and a dedicated free Live Tennis API keycurljq, curlAdd "tennis 24 255" to your theme's status segments and set
TMUX_POWERLINE_SEG_TENNIS_API_KEY in your private configuration file. Optionally set
TMUX_POWERLINE_SEG_TENNIS_PLAYER to a player or doubles-team name substring. This
filter is applied locally. Protect the configuration file with chmod 600.
The segment shows the first matching live match, its set scores and available points,
plus the snapshot age in minutes. TB marks tiebreak points; a tiebreak score
repeated in the current set slot is shown once in brackets. [stale score]
preserves the provider's staleness warning. Additional matches on
this page are counted; [more] indicates that the API has another page. The segment
fetches only the first 100 matches and does not paginate. An unknown score is shown
as unavailable, rather than as 0-0.
This is a snapshot refreshed at most every 15 minutes. It uses only the free live
matches endpoint and needs no paid plan. All instances for the same local user share
one cache at ${TMUX_POWERLINE_DIR_TEMPORARY}/tennis, alongside the other segments.
The fixed 900-second minimum between attempts includes failed requests, limiting the
segment to 96 requests/day. When the temporary cache is missing (including after a
reboot or cleanup), the segment waits a full 15 minutes before requesting a snapshot
and shows Tennis: waiting for request window. Clearing the cache therefore cannot
force an early update. Use a dedicated key: requests from other applications or
computers also consume the key's 100/day allowance.
Network requests run in the background. If the first fetch fails the segment shows
Tennis: unavailable; later failures retain the last snapshot with its age.
No key means no output or network request. If a process is forcibly killed and leaves
refresh.lock behind, stop the segment and remove that empty directory to resume;
keep last_attempt so the budget remains intact.
Run the offline regression checks with bash tests/tennis.sh.
weather.sh refreshes in the background and shares its cache between all local tmux
clients. It makes at most one GeoIP or MET Weather API attempt per configured
TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD (600 seconds by default). Shorter,
zero, negative, and invalid values cannot reduce the 600-second MET minimum.
Response cache headers can defer a refresh further; failed requests use a
conservative retry delay, retain the last successfully displayed weather, and leave
the segment blank until the first successful refresh.
Weather data and request eligibility are stored under
${TMUX_POWERLINE_DIR_TEMPORARY}. The segment records eligibility before making a
request, so a missing or unwritable local state directory suppresses requests rather
than retrying for every status render. Removing local state can cause one recovery
request once state can be written; it does not bypass the provider's minimum
interval.
Install tpm and make sure it's working.
Install tmux-powerline as a plugin by adding a line to tmux.conf:
set -g @plugin 'erikw/tmux-powerline'
Install the plugin with <prefix>I, unless you changed tpm's keybindings.
Continue to the Configuration section below.
[!NOTE] Note that tpm plugins should be at the bottom of your
tmux.conf. This plugin will then override some tmux settings likestatus-left,status-right, etc. If you had already set those in your tmux config, it is a good opportunity to remove or comment them out. Take a look at main.tmux for exactly which settings are overridden.
tmux-powerline stores the custom config, themes, and segments at $XDG_CONFIG_HOME/tmux-powerline/.
To make the following example easier, let's assume the following:
$XDG_CONFIG_HOME has the default value of ~/.config~/.config/tmux/plugins/tmux-powerlineAdapt the commands below if your paths differ from this.
Start by generating your own configuration file:
~/.config/tmux/plugins/tmux-powerline/generate_config.sh
mv ~/.config/tmux-powerline/config.sh.default ~/.config/tmux-powerline/config.sh
$EDITOR ~/.config/tmux-powerline/config.sh
Go through the default config and adjust it to your needs!
The theme is specified by setting the environment variable $TMUX_POWERLINE_THEME in the config file above. It will use a default theme, and you probably want to use your own. The default config has set the custom theme path to be ~/.config/tmux-powerline/themes/.
Make a copy of the default theme and make your own, say my-theme:
mkdir -p ~/.config/tmux-powerline/themes
cp ~/.config/tmux/plugins/tmux-powerline/themes/default.sh ~/.config/tmux-powerline/themes/my-theme.sh
$EDITOR ~/.config/tmux-powerline/themes/my-theme.sh
[!IMPORTANT] Remember to update the configuration file to use the new theme by setting
TMUX_POWERLINE_THEME=my-theme
In the same way as themes, you can create your own segments at TMUX_POWERLINE_DIR_USER_SEGMENTS which defaults to ~/.config/tmux-powerline/segments.
To get started, copy an existing segment that is similar to the segment that you want to create.
mkdir -p ~/.config/tmux-powerline/segments
cp ~/.config/tmux/plugins/tmux-powerline/segments/date.sh ~/.config/tmux-powerline/segments/my-segment.sh
$EDITOR ~/.config/tmux-powerline/segments/my-segment.sh
Now you can add my-segment to your own theme!
Also see How to make a segment below for more details.
Some segments might not work on your system for various reasons, such as missing programs or different versions not having the same options. To find out which segment is not working, it may help to enable the debug setting in ~/.config/tmux-powerline/config.sh.
Next step would be to enable the error logging in general or even with a scope, see TMUX_POWERLINE_ERROR_LOGS_ENABLED and TMUX_POWERLINE_ERROR_LOGS_SCOPES in your config.
However, this may not be enough to determine the error, so you can inspect all executed bash commands (will be a long output) by doing
bash -x powerline.sh (left|right)
For a quick diagnostics snapshot of your local setup, run:
./doctor.sh
This prints resolved tmux-powerline paths and settings, active segment/theme configuration, and live tmux status options when a tmux server is reachable.
To debug smaller portions of code, say if you think the problem lies in a specific segment, insert these lines at the top and bottom of the relevant code portions e.g., inside a function:
set -x
exec 2>/tmp/tmux-powerline.log
<code to debug>
set +x
and then inspect the outputs like
less /tmp/tmux-powerline.log
tail -f /tmp/tmux-powerline.log # or follow output like this.
You can also enable the debug mode in your config file. Look for the TMUX_POWERLINE_DEBUG_MODE_ENABLED environment variable and set it to true.
If you can not solve the problems, you can post an issue and be sure to include relevant information about your system and script output (from ./doctor.sh and/or bash -x) and/or screenshots if needed.
Be sure to search in the resolved issues section for similar problems you're experiencing before posting.
You have edited ~/.tmux.conf, but no powerline is displayed. This might be because tmux is not aware of the changes, so you have to restart your tmux session or reload that file by typing this on the command line (or in tmux command mode with prefix :)
tmux source-file ~/.tmux.conf
If your tmux looks like this, then you may have to, in iTerm, uncheck [Unicode East Asian Ambiguous characters are wide] in Preferences -> Settings -> Advanced.
[!IMPORTANT] Please read and follow the CONTRIBUTING.md guidelines!
This project can only gain positively from contributions. Fork today and make your own enhancements and segments to share back!
You can fork this project and then start coding right away with GitHub Codespaces, as this project is set up to install all development dependencies and install tmux-powerline on the devcontainer. See devcontainer.json and devcontainer_postCreateCommand.sh. After starting the devcontainer, just type tmux in the terminal, and you should see a working tmux-powerline already to start playing with.
[!IMPORTANT] If you have set up your own dotfiles to be installed with GitHub Codespaces, and there were some tmux config files installed from your dotfiles to the devcontainer, then you might have to run this script to wipe your config in favour of the setup provided by this repo's initialization:
./scripts/devcontainer_postCreateCommand.sh
Please section How To Make a Segment at CONTRIBUTING.md.
Create a new version of this project by using semver-cli.
vi CHANGELOG.md
semver up minor
ver=$(semver get release)
git commit -am "Bump version to $ver" && git tag $ver && git push --atomic origin main $ver
I have another tmux plugin that might interest you:
(top 24 of 45)
1,980 followers · starred Dec 2015
1,030 followers · starred Jun 2012
1,674 followers · starred May 2025
124 followers · starred Aug 2019