From bitwarden-software-engineer
Bitwarden server code conventions for C# and .NET. Use when working in the server repo, creating commands, queries, services, or API endpoints.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bitwarden-software-engineer:writing-server-codeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The `server` repo contains:
The server repo contains:
src/Api — REST API endpointssrc/Identity — Authentication/identity servicesrc/Core — Business logic, commands, queries, servicessrc/Infrastructure — Data access, repositoriesNew features should use the CQS pattern — discrete action classes instead of large entity-focused services. See ADR-0008.
Why CQS matters at Bitwarden: The codebase historically grew around entity-focused services (e.g., CipherService) that accumulated hundreds of methods. CQS breaks these into single-responsibility classes (CreateCipherCommand, GetOrganizationApiKeyQuery), making code easier to test, reason about, and modify without unintended side effects.
Commands = write operations. Change state, may return result. Named after the action: RotateOrganizationApiKeyCommand.
Queries = read operations. Return data, never change state.
When NOT to use CQS: When modifying existing service-based code, follow the patterns already in the file. Don't refactor to CQS unless explicitly asked. If asked to refactor, apply the pattern only to the scope requested.
When caching is needed, follow the conventions in CACHING.md. Use IFusionCache instead of IDistributedCache.
Don't implement caching unless requested. If a user describes a performance problem where caching might help, suggest it — but don't implement without confirmation.
Always use CoreHelpers.GenerateComb() for entity IDs — never Guid.NewGuid(). Sequential COMBs prevent SQL Server index fragmentation that random GUIDs cause on clustered indexes, which is critical for Bitwarden's database performance at scale.
These are the most frequently violated conventions. Claude cannot fetch the linked docs at runtime, so these are inlined here:
TryAdd* for DI registration (TryAddScoped, TryAddTransient) — prevents duplicate registrations when multiple modules register the same servicenamespace Bit.Core.Vault; not namespace Bit.Core.Vault { ... }! (null-forgiving) when you know a value isn't null; use required modifier for properties that must be set during constructionAsync suffix on all async methods — CreateAsync, not Create, when the method returns TaskActionResult<T> — not IActionResult or bare T[Theory, BitAutoData] (not [AutoData]), SutProvider<T> for automatic SUT wiring, and Substitute.For<T>() from NSubstitute for mocking// CORRECT — sequential COMB prevents index fragmentation
var id = CoreHelpers.GenerateComb();
// WRONG — random GUIDs fragment clustered indexes
var id = Guid.NewGuid();
// CORRECT — idempotent, won't duplicate
services.TryAddScoped<ICipherService, CipherService>();
// WRONG — silently duplicates registration, last-wins causes subtle bugs
services.AddScoped<ICipherService, CipherService>();
// CORRECT — file-scoped
namespace Bit.Core.Vault.Commands;
// WRONG — block-scoped
namespace Bit.Core.Vault.Commands
{
// ...
}
npx claudepluginhub bitwarden/ai-plugins --plugin bitwarden-software-engineerBitwarden client code conventions for Angular and TypeScript. Use when working in the clients mono-repo, creating components, services, or modifying web/browser/desktop apps.
Provides C#/.NET patterns for production-grade APIs, MCP servers, and enterprise backends with DI, async, caching, EF Core/Dapper optimization, resilience, and testing.
Applies opinionated conventions for C# 12 and .NET 8+ code: ASP.NET Core minimal/controller APIs, Blazor, EF Core, async patterns, CQRS with MediatR.