Install the CLI
The CLI is the bw command, published as @bitwarden/cli on npm and as standalone binaries for Windows, macOS and Linux under the cli-v* tags of the bitwarden/clients releases. The releases page on this site tracks the current version.
| Method | Command | Notes |
|---|---|---|
| npm | npm install -g @bitwarden/cli | Needs Node 20 or later |
| Homebrew (macOS, Linux) | brew install bitwarden-cli | Formula, not a cask |
| Snap (Linux) | sudo snap install bw | Confined; cannot read files outside your home |
| Chocolatey (Windows) | choco install bitwarden-cli | Run PowerShell as administrator |
| AUR (Arch) | bitwarden-cli | Or bitwarden-cli-bin |
| Binary | bw-<os>-<version>.zip from the release | No runtime needed; put bw on your PATH |
npm install -g @bitwarden/cli brew install bitwarden-cli sudo snap install bw choco install bitwarden-cli Check it with bw --version. The CLI is independent of the desktop app; if you want that too, the one-command install is on the home page.
Log in, unlock and the session key
The CLI has two states. Logged in means it holds your encrypted vault on disk. Unlocked means it also has the key to decrypt it, as a session key that you pass to every command.
- Log in with your email address, master password and two-step code. Add
--apikeyto authenticate instead with a personal API key from the web vault’s Security settings, read fromBW_CLIENTIDandBW_CLIENTSECRET.
bw login - Unlock. The CLI prints a session key and the exact
exportline to paste.
bw unlock - Export the key so later commands find it, either by pasting that line or in one step:
export BW_SESSION="$(bw unlock --raw)" - Sync, then read a password.
bw sync bw get password github.com - Lock when finished.
bw lockinvalidates the session key but keeps you logged in;bw logoutalso removes the local vault copy.
bw lock Without the export, every command needs --session <key>. EU accounts run bw config server https://vault.bitwarden.eu before the first login.
The commands you will use most
| Task | Command |
|---|---|
| Pull the latest changes | bw sync |
| Search items | bw list items --search github |
| Get a password | bw get password <name-or-id> |
| Get a username | bw get username <name-or-id> |
| Get a TOTP code | bw get totp <name-or-id> |
| Full item as JSON | bw get item <id> | jq |
| Random password | bw generate -ulns --length 24 |
| Passphrase | bw generate -p --words 4 --separator - |
| Check state | bw status |
| List folders or collections | bw list folders, bw list collections |
bw list items --search github bw generate -ulns --length 24 bw get accepts an item name or its UUID; if a name matches several items the command fails and lists them, so copy the ID from that output. -ulns means uppercase, lowercase, numbers and symbols. list and get item output JSON, which is why jq appears in every Bitwarden script.
Create, edit and delete items
Items are created from a JSON template that you fill in, base64-encode and pass to bw create:
bw get template item | jq \
--arg name "Example" \
--arg user "me@example.com" \
--arg pass "$(bw generate -ulns --length 24)" \
'.name = $name
| .login = {username: $user, password: $pass, uris: [{uri: "https://example.com"}]}' \
| bw encode | bw create item
Editing starts from the existing item instead of the template:
ID="$(bw get item example | jq -r .id)"
bw get item "$ID" | jq '.login.password = "new-password"' | bw encode | bw edit item "$ID"
Deleting moves an item to the trash; add --permanent to skip it.
bw delete item <id> Import, export and server URL
The CLI imports the same formats as the web vault. List them, then import:
bw import --formats bw import lastpasscsv export.csv Delete the export file afterwards. The web vault route is described in import from LastPass and the other migration guides.
Exports go to the current directory unless you pass --output. Prefer the encrypted format; plain json and csv are readable by anything.
bw export --format encrypted_json To use the EU cloud or your own server, log out, set the URL, then log in again:
bw config server https://vault.bitwarden.eu For a self-hosted Bitwarden or Vaultwarden instance use its HTTPS address, for example bw config server https://vault.example.com; setting one up is covered in self-host Bitwarden or Vaultwarden.
bw serve: a local REST API
bw serve starts an HTTP server on localhost:8087 exposing the unlocked vault as REST endpoints (GET /object/item/<id>, POST /unlock and so on). It suits tools that cannot shell out repeatedly and avoids the Node start-up cost of each call.
bw serve --port 8087 Treat it with care: any process on the machine that can reach that port can read every item while the vault is unlocked, with no further authentication. Never bind it to a non-loopback address, never run it on a shared machine, and stop it when the job is done.
Scripting safely
- Never put the master password in a script, a crontab or a command line argument; arguments show up in
psoutput and shell history. - Authenticate non-interactively with an API key: export
BW_CLIENTIDandBW_CLIENTSECRET, thenbw login --apikey. The API key can log in but cannot decrypt anything by itself. - Unlock with
--passwordenv VAR(the master password in a variable your secret store injects) or--passwordfile /pathon a file with mode600owned by the job’s user. - Use
--rawso output is only the value you asked for,--nointeractionso a missing input fails instead of prompting, and--responsefor structured JSON including error details. - Keep
BW_SESSIONout of history: read it frombw unlock --rawin a subshell as shown above, or setHISTCONTROL=ignorespaceand start the line with a space. - Lock at the end of the script. CLI state lives under
~/.config/Bitwarden CLI/on Linux,~/Library/Application Support/Bitwarden CLI/on macOS and%APPDATA%\Bitwarden CLI\on Windows; restrict access to it.
For secrets that servers read, Bitwarden’s separate Secrets Manager and its bws CLI are built for machine access tokens with scoped projects; the password manager CLI is best for secrets that people also use.
Shell integration ideas
A picker that searches your logins with fzf and copies the password to the clipboard:
# Requires jq and fzf. Replace pbcopy with wl-copy or xclip -selection clipboard on Linux.
bw list items \
| jq -r '.[] | select(.type == 1) | "\(.name)\t\(.login.username // "")\t\(.id)"' \
| fzf --with-nth=1,2 --delimiter='\t' \
| cut -f3 \
| xargs bw get password \
| pbcopy
Other useful patterns: a shell function that runs bw unlock --raw and exports the key once per terminal, bw get totp piped to the clipboard for two-step prompts, and bw list items --folderid to load a project’s credentials into environment variables.
On Linux, rbw is an unofficial Rust client with a background agent that holds the decrypted key and re-locks on a timer, so there is no session variable to manage and each call starts in milliseconds. It is not from Bitwarden and lacks some features, but it is popular for exactly this use.
Troubleshooting
npm install -gfails with EACCES. The global prefix is owned by root. Use a Node version manager (nvm, fnm, volta) so the global directory is in your home, or setnpm config set prefix ~/.localand add~/.local/bintoPATH. Do notsudo npm install.- “You are not logged in.” You never ran
bw loginon this machine, or the data directory was cleared. Log in again. - “Vault is locked.”
BW_SESSIONis not set in this shell. Unlock and export the key, or pass--session. - “mac failed” or “Invalid session key.” The key you are passing belongs to an older unlock. Unlock again and export the new key.
bwis slow to start. Each call starts a Node runtime, roughly a second. Batch work withbw list itemsandjq, or usebw serveor rbw.- Node version error. The current release needs Node 20 or later and distribution packages are often older. Use a version manager or the standalone binary. Ubuntu users who also want the desktop app will find the package options in install on Ubuntu.
Frequently asked questions
Is the Bitwarden CLI free to use?
Yes. The CLI is part of the open-source clients (GPL-3.0) and works with the free plan, including unlimited items, sync and the generator. Reading TOTP codes with bw get totp needs Premium (about US$10 per year) or an organisation plan, the same as in the apps.
How do I keep the Bitwarden CLI unlocked between commands?
Export the session key that bw unlock prints as BW_SESSION in the current shell. Every later command reads it. The key stays valid until you run bw lock or bw logout, or the machine restarts, so lock when you are done.
Does the Bitwarden CLI work with Vaultwarden or a self-hosted server?
Yes. Run bw logout, then bw config server https://vault.example.com and log in again. Vaultwarden is API-compatible, so the same commands work. See self-hosting Bitwarden for setting up the server.
What does the error mac failed mean in the Bitwarden CLI?
The session key in BW_SESSION does not match the encrypted data on disk, usually because you unlocked again in another shell or logged out and back in. Run bw unlock once more and export the new key, or run bw logout and start over.
Can I use the Bitwarden CLI in a CI pipeline or cron job?
Yes, with an API key: set BW_CLIENTID and BW_CLIENTSECRET, run bw login --apikey, then bw unlock --passwordenv BW_PASSWORD --raw. For machine secrets such as API tokens, Bitwarden Secrets Manager and its bws CLI are built for that job.