A Better Bitwarden CLI

In this post I'm going to show you how the Bitwarden CLI client's UX for humans is lacking and how I wrote some scripts to improve it. I wrote these for my own use, but I'm sharing them with you in hopes other my find them useful.

The Problem

I use Bitwarden as my password manager. I switched to it from LastPass years ago because it's open source and works great. Sometimes I want to use Bitwarden from the command line. Fortunately, Bitwarden has a CLI client! Unfortunately, it's not very nice to use. All of the functionally it there, but the UX is lacking. When you want to unlock your vault, after you've entered your password, it just spits out this and expects you to copy and paste the session token!?

$ bw unlock
? Master password: [hidden]
Your vault is now unlocked!

To unlock your vault, set your session key to the `BW_SESSION` environment variable. ex:

But even worse than that, if you actually want to get you login details out of it, you're just hit with a wall of JSON. I get JSON output is good for machine readability, but not for humans. It's pretty obvious that the Bitwarden CLI was intended to be used by other programs and not directly by a human.

Scripts to the Rescue!

I've written two shell snippets to help improve the UX of using Bitwarden on the command line. The first makes unlocking your vault smoother and the second make searching for account details a breeze.


To unlock the vault we need to run the bw unlock command then save the session key in the BW_SESSION environment variable. We can run bw unlock with the --raw flag to just get session key. I added these two alias to my shell's rc file. bwu unlocks my vault and bwl locks it again.

alias bwu='export BW_SESSION="$(bw unlock --raw)"'
alias bwl='export BW_SESSION='


For searching my account details I've written a shell script called bwc for "Bitwarden copy". Here's the script:


# Exit on error
set -e

# Command to copy to clipboard
COPY="xclip -sel clip"

# Get list of all logins as json
logins="$(bw list items)"
# Grab the name of every login and pip them into fzf
name="$(echo $logins | jq -r '.[].name' | fzf)"
# Find the login with the selected name (as a json)
selected="$(echo $logins | jq -r ".[] | select(.name == \"$name\")")"
# Print the name of the selected login
echo "Name: $(echo $selected | jq -r '.name')"
echo "> Copying Username"
# Copy the username to the clipboard
printf '%s' "$(echo $selected | jq -r '.login.username')" | $COPY
echo "Press any key to copy password..."
# Wait for user input before coping the password
echo "> Copying Password"
# Copy the password to the clipboard
printf '%s' "$(echo $selected | jq -r '.login.password')" | $COPY

In addition to the Bitwarden CLI client, this script also uses jq to parse Bitwarden's JSON output, fzf let the user search their logins, and xclip to copy the login details to the clipboard. I'd demo the script but I don't want to show off a list of my online accounts. They way the script works is it lets you search through a list of your logins in fzf, then for whichever one you pick, it copies your username to your clipboard, then waits for you to press enter. Then it copies you password to your clipboard.

Final Thoughts

These script are only really good for logging in and grabbing your login details and can't do other stuff like adding new stuff to your vault, but I find that 99% of the time this is what I need. And I prefer to use the GUI for more complex management anyway. I wrote these scripts for my own use, but I thought I'd share them in case someone else might find them useful.

If you want to see all of my dot files and scripts they're in my dotfiles repo here git.sr.ht/~zethra/dotfiles.