writing-client-code

Applies Bitwarden Angular and TypeScript conventions when writing client application code.

13.7k|2.0k|Updated Mar 9, 2016
One-click install
npx skills add https://github.com/bitwarden/clients --skill writing-client-code
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: writing-client-code
Source: https://github.com/bitwarden/clients/tree/main/.claude/skills/writing-client-code
Command: npx skills add https://github.com/bitwarden/clients --skill writing-client-code

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Bitwarden's client monorepo spans web, browser, desktop, and CLI apps with strict architectural rules that are easy to violate. This Skill ensures new code follows the correct Angular patterns, dependency injection style, and cross-client constraints so contributions pass review without rework.

Core Features & Use Cases

  • Angular conventions enforcement: Guides creation of standalone components with OnPush change detection, control flow syntax, inject()-based DI, and Reactive Forms.
  • Cross-client architecture rules: Explains why libs/common must avoid Angular imports, when to use Signals versus RxJS, and how abstract service interfaces work across CLI and Angular clients.
  • Style and naming standards: Covers kebab-case file naming, tw- prefixed Tailwind classes, frozen const objects instead of TypeScript enums (ADR-0025), and Jest testing with jest-mock-extended.
  • Use Case: When asked to add a new vault settings component to the web app, the Skill produces a standalone OnPush component using @if/@for control flow, inject() for services, and tw- prefixed Tailwind classes.

Quick Start

Ask the assistant to create a new Angular component or service for the Bitwarden web, browser, or desktop app following the repository's coding conventions.

Frequently Asked Questions about writing-client-code

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I write a new Angular component for Bitwarden clients?

New components must be standalone with ChangeDetectionStrategy.OnPush, use control flow syntax (@if, @for, @switch) in templates, and prefer the inject() function for dependency injection. Use the host property in the decorator instead of @HostBinding or @HostListener.

Should I use Signals or RxJS for state management in Angular?

Use Signals for component local state and Angular-only services. Use RxJS for cross-client services in libs/common because the CLI client has no Angular Signals support. Prefer the async pipe over manual subscriptions, and use takeUntilDestroyed() when subscribing.

Why can't libs/common import Angular code?

The CLI is a first-class Bitwarden client, so any code in libs/common must run without Angular's dependency injection, decorators, or lifecycle hooks. Cross-client services use abstract classes as interfaces, with concrete implementations living in each app.

Can I use TypeScript enums in Bitwarden client code?

No. Per ADR-0025, use frozen const objects with Object.freeze() and as const, plus a companion type alias. TypeScript enums have runtime behavior that creates subtle tree-shaking bugs.

Should I modernize legacy Angular code when editing existing files?

No. Follow the patterns already present in the file you are modifying. Only migrate to standalone components, control flow, or signals when explicitly asked, and then follow the documented migration order ending with OnPush.

Why are my Tailwind classes not applying in Bitwarden components?

All Tailwind classes require the tw- prefix, such as tw-flex or tw-mt-2. Classes without the prefix like flex or mt-2 are stripped and will not render.