PageSourceSearch

https://contributing-docs.pages.dev/assets/js/97e7eb2c.4840a29e.js

js contributing-docs.pages.dev collected 2026-10-03 06:42:13 UTC 15,101 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunk_bitwarden_contributing_docs=globalThis.webpackChunk_bitwarden_contributing_docs||[]).push([[7131],{73468(e,s,i){i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"getting-started/tools/index","title":"Tools","description":"The tooling recommendations and instructions in this documentation assume that you\u2019re using macOS.","source":"@site/docs/getting-started/tools/index.md","sourceDirName":"getting-started/tools","slug":"/getting-started/tools/","permalink":"/getting-started/tools/","draft":false,"unlisted":false,"editUrl":"https://github.com/bitwarden/contributing-docs/tree/main/docs/getting-started/tools/index.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1},"sidebar":"getting_started","previous":{"title":"Overview","permalink":"/"},"next":{"title":"Setup Guide","permalink":"/getting-started/server/guide"}}');var t=i(74848),r=i(28453);const o={sidebar_position:1},l="Tools",a={},d=[{value:"IDEs",id:"ides",level:2},{value:"Local environment",id:"local-environment",level:2},{value:"Mobile",id:"mobile",level:2},{value:"Databases",id:"databases",level:2},{value:"Visual Studio Code extensions",id:"visual-studio-code-extensions",level:2},{value:"AI tools",id:"ai-tools",level:2},{value:"Claude Code",id:"claude-code",level:3},{value:"Installation",id:"installation",level:4},{value:"Basic usage",id:"basic-usage",level:4},{value:"Bitwarden AI plugin marketplace",id:"bitwarden-ai-plugin-marketplace",level:3},{value:"Optional tools",id:"optional-tools",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components},{Bitwarden:i}=s;return i||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Bitwarden",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"tools",children:"Tools"})}),"\n",(0,t.jsx)(s.admonition,{title:"Operating system assumptions",type:"warning",children:(0,t.jsx)(s.p,{children:"The tooling recommendations and instructions in this documentation assume that you\u2019re using macOS.\nThis may require some adaptation if you\u2019re using a different operating system."})}),"\n",(0,t.jsx)(s.p,{children:"The following tools make up the standard Bitwarden developer setup and should be installed as part\nof your local development environment."}),"\n",(0,t.jsx)(s.h2,{id:"ides",children:"IDEs"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://code.visualstudio.com/",children:"Visual Studio Code"})," - used for all Typescript projects.\nSuboptimal for C#. Be sure to install ",(0,t.jsx)(s.a,{href:"#visual-studio-code-extensions",children:"extensions"})]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.jetbrains.com/rider/download/",children:"JetBrains Rider"})," - fully featured IDE for C#, .NET &\nmore. Bitwarden developers should contact IT for a license"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://developer.apple.com/xcode/",children:"Xcode"})," - required for iOS Mobile development and Safari web\nextension"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"local-environment",children:"Local environment"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://brew.sh/",children:"Homebrew"})," - package manager for macOS"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://iterm2.com/",children:"Iterm2"})," (available via Homebrew) - a better terminal emulator"]}),"\n",(0,t.jsx)(s.li,{children:"Various browsers - It\u2019s nice to have a slew of browsers ready to test the extension in a host of\nscenarios. You can also use multiple browsers to have different browser extension version\ninstalled to compare them."}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"})," - required for server development only"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://dotnet.microsoft.com/download",children:".NET SDK"})," - required for server and other backend\ndevelopment environments"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://docs.microsoft.com/en-us
1/powershell/scripting/install/installing-powershell-core-on-macos",children:"PowerShell"}),"\n(available via Homebrew: ",(0,t.jsx)(s.code,{children:"brew install powershell"}),")"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://nodejs.org/",children:"NodeJS"})," v24 (preferably using a ",(0,t.jsx)(s.a,{href:"https://docs.npmjs.com/downloading-and-installing-node-js-and-npm",children:"node version manager"}),")"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.npmjs.com/",children:"NPM"})," v11 (included with Node)"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"})," latest stable version - (preferably installed via\n",(0,t.jsx)(s.a,{href:"https://rustup.rs/",children:"rustup"}),")"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://git-scm.com",children:"Git"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"/contributing/commit-signing",children:"Commit signing"})," is strongly recommended"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"mobile",children:"Mobile"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://developer.android.com/studio/",children:"Android Studio"})," - Nice for setting up and running Android\nSimulators"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://developer.android.com/studio/command-line/adb",children:"adb"})," - for interacting with Android sims"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://gist.github.com/brutella/0bcd671a9e4f63edc12e",children:"Apple Icons Generator Gist"})," - Script to\ngenerate Apple icons from an image"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"databases",children:"Databases"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql",children:"MSSQL VSCode Extension"})," for\nworking with your local SQL Server"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.pgadmin.org/",children:"PgAdmin4"})," - Useful for fiddling with PostgreSQL db"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.mysql.com/products/workbench/",children:"MySQLWorkbench"})," - Useful for fiddling with MySQL db"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.sqlitestudio.pl/",children:"SQLiteStudio"})," - Useful for fiddling with SQLite db"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"visual-studio-code-extensions",children:"Visual Studio Code extensions"}),"\n",(0,t.jsx)(s.p,{children:"There are some vs code extensions that are life-savers in our line of work. A list of highly\nrecommended ones include the following:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["General","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=nick-rudenko.back-n-forth",children:"Back & Forth"})," -\nAdds forward and back buttons to top right of your editor. Simple, but incredibly useful."]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker",children:"Code Spell Checker"})," -\ncan be annoying, but has saved me lots of ",(0,t.jsx)(s.code,{children:"tmes form writting oragnizations."})]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare",children:"LiveShare"})," -\nFor pair programming"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["C#","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp",children:"C#"})," - Omnisharp\nintegrations"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=formulahendry.dotnet-test-explorer",children:".NET Core Test Explorer"})," -\nTest explorer for .NET tests"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.user-secrets",children:".NET Core User Secrets"})," -\nEdit secrets files by right clicking on a .proj and selecting edit user -secrets"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["Git","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph",children:"Git Graph"})," - fantastic\ngit visualization tool"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory",children:"Git History"})," -\nMore Git history"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens",children:"Git Lens"})," - Even more Git\noptions"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["Typescript / Angular","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=Angular.ng-template",children:"Angular Language Service"})," -\nUnderstands Angular templates"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest",children:"Jest"})," - Jest test runner"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode",children:"Prettier"})," -\nintegrate with prettier code formatting"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint",children:"ESLint"})," -\nIntegrations for ESLint"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console",children:"Nx Console"})," - UI over\nthe Nx CLI"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["Rust","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer",children:"rust-analyzer"})," -\nGreat rust language server"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml",children:"Even Better TOML"})," -\nfor handling TOML (cargo config)"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb",children:"CodeLLDB"})," - for rust\ndebugging"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["Databases","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=jakebathman.mysql-syntax",children:"MySQL Syntax"})," -\nsyntax highlighting for MySQL"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres",children:"PostgreSQL"})," -\nsyntax highlighting for PostgreSQL"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(i,{children:[(0,t.jsx)(s.h2,{id:"ai-tools",children:"AI tools"}),(0,t.jsx)(s.admonition,{type:"tip",children:(0,t.jsxs)(s.p,{children:["To learn more about how we use AI tools at Bitwarden, see our ",(0,t.jsx)(s.a,{href:"/contributing/ai/",children:"AI"}),"\ndocumentation. This page specifies how to configure AI tooling for development."]})}),(0,t.jsx)(s.h3,{id:"claude-code",children:"Claude Code"}),(0,t.jsx)(s.p,{children:"We use Claude Code as our primary AI tool for development workflows."}),(0,t.jsx)(s.h4,{id:"installation",children:"Installation"}),(0,t.jsxs)(s.p,{children:["Follow the installation instructions ",(0,t.jsx)(s.a,{href:"https://code.claude.com/docs/en/quickstart",children:"here"}),". When\nprompted, sign into the Anthropic Console via SSO and authenticate your local client."]}),(0,t.jsxs)(s.p,{children:["We also recommend integrating Claude Code into your IDE. See\n",(0,t.jsx)(s.a,{href:"https://code.claude.com/docs/en/vs-code",children:"VS Code"})," for setup instructions."]}),(0,t.jsx)(s.h4,{id:"basic-usage",children:"Basic usage"}),(0,t.jsxs)(s.p,{children:["We recommend that you start with\n",(0,t.jsx)(s.a,{href:"https://code.claude.com/docs/en/common-workflows",children:"common workflows"})," and\n",(0,t.jsx)(s.a,{href:"https://code.claude.com/docs/en/best-practices",children:"best practices"})," from Anthropic for learning how to\nstart using Claude for development."]}),(0,t.jsx)(s.h3,{id:"bitwarden-ai-plugin-marketplace",children:"Bitwarden AI plugin marketplace"}),(0,t.jsxs)(s.p,{children:["Bitwarden maintains a curated set of AI plugins designed for our development workflows in our\n",(0,t.jsx)(s.a,{href:"https://github.com/bitwarden/ai-
1plugins",children:"marketplace"}),"."]}),(0,t.jsxs)(s.p,{children:["See the ",(0,t.jsx)(s.a,{href:"https://github.com/bitwarden/ai-plugins/tree/main?tab=readme-ov-file#usage",children:(0,t.jsx)(s.code,{children:"README"})})," in\nthe ",(0,t.jsx)(s.code,{children:"ai-plugins"})," repo for installation and setup instructions."]})]}),"\n",(0,t.jsx)(s.h2,{id:"optional-tools",children:"Optional tools"}),"\n",(0,t.jsx)(s.p,{children:"The following tools may be useful depending on your preferences or what you\u2019re developing."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://azure.microsoft.com/en-us/features/storage-explorer/",children:"Microsoft Azure Storage Explorer"})," -\nfor connecting to or working with local Azure table storage and queues"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.parallels.com/",children:"Parallels"})," - For running Windows VMs"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.sourcetreeapp.com/",children:"Sourcetree"})," - Git GUI. Note: For the git hooks to behave\ncorrectly on macOS when using nvm, please follow\n",(0,t.jsx)(s.a,{href:"https://typicode.github.io/husky/#/?id=command-not-found",children:"these instructions"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453(e,s,i){i.d(s,{R:()=>o,x:()=>l});var n=i(96540);const t={},r=n.createContext(t);function o(e){const s=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.