Nestjs Best Practices
rolling-scopes/rsschool-app
NestJS best practices and architecture patterns for building production-ready applications.
Define coding rules, conventions, and standards for AI collaboration.
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-convention --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/phase-2-convention .claude/skills/phase-2-convention && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .claude/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-conventionType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-convention --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/phase-2-convention .agents/skills/phase-2-convention && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .agents/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-convention --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/phase-2-convention .cursor/skills/phase-2-convention && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .cursor/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ww-w-ai/bkit-claude-code.git --path skills/phase-2-convention--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-convention --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/phase-2-convention .gemini/skills/phase-2-convention && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .gemini/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-conventionInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/phase-2-convention .github/skills/phase-2-convention && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .github/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ww-w-ai/bkit-claude-code phase-2-convention --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ww-w-ai/bkit-claude-code.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/phase-2-convention .opencode/skills/phase-2-convention && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "phase-2-convention" agent skill from https://github.com/ww-w-ai/bkit-claude-code/tree/main/skills/phase-2-convention into .opencode/skills/phase-2-convention/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "phase-2-convention", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
phase-2-conventionDefine coding rules, conventions, and standards for AI collaboration.
Phase 2 Convention is an agent skill from ww-w-ai/bkit-claude-code. Define coding rules, conventions, and standards for AI collaboration. Triggers: convention, coding style, lint, rules
Its SKILL.md is about 3.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs. The repository describes itself as: bkit Vibecoding Kit - PDCA methodology + Claude Code mastery for AI-native development. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 85b4913. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteGlobGrepFrom allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript and bash).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
AUTH_SECRETDB_PASSWORDAPI_STRIPE_SECRETSMTP_PASSWORDAUTH_GOOGLE_SECRETFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Phase 2 Convention loads about 3.8k tokens when it runs. Until then it costs about 34 tokens; SKILL.md has 529 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
- Never commit sensitive info in .env files### .env File Structure├── .env.local # Local development (Git ignored)├── .env.development # Development env defaults├── .env.staging # Staging env defaults├── .env.production # Production defaults (no sensitive info)└── .env.test # Test environment# Set actual values in .env.local| Variable Type | .env.example | .env.local | CI/CD Secrets |- [ ] Register .env.local in .gitignoreAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from ww-w-ai/bkit-claude-code at commit 85b4913, republished under its Apache-2.0 licence (© ww-w-ai). 529 words, ~3,764 tokens.
.claude/skills/phase-2-convention/SKILL.md (or your agent's skills folder).Define code writing rules
Maintain consistent code style. Especially important when collaborating with AI - clarify what style AI should use when writing code.
Project Root/
├── CONVENTIONS.md # Full conventions
└── docs/01-plan/
├── naming.md # Naming rules
└── structure.md # Structure rules| Level | Application Level |
|---|---|
| Starter | Basic (essential rules only) |
| Dynamic | Extended (including API, state management) |
| Enterprise | Extended (per-service rules) |
src/
├── components/ # Reusable components
├── features/ # Feature modules
├── hooks/ # Custom hooks
├── utils/ # Utilities
└── types/ # Type definitions❌ Organizing env vars just before deployment
→ Missing variables, naming inconsistency, deployment delays
✅ Establish convention at design stage
→ Consistent naming, clear categorization, fast deployment| Prefix | Purpose | Exposure Scope | Example |
|---|---|---|---|
NEXT_PUBLIC_ | Client-exposed | Browser | NEXT_PUBLIC_API_URL |
DB_ | Database | Server only | DB_HOST, DB_PASSWORD |
API_ | External API keys | Server only | API_STRIPE_SECRET |
AUTH_ | Authentication | Server only | AUTH_SECRET, AUTH_GOOGLE_ID |
SMTP_ | Email service | Server only | SMTP_HOST, SMTP_PASSWORD |
STORAGE_ | File storage | Server only | STORAGE_S3_BUCKET |
⚠️ Security Principles
- Never expose anything except NEXT_PUBLIC_* to client
- API keys and passwords must be server-only variables
- Never commit sensitive info in .env filesProject Root/
├── .env.example # Template (in Git, values empty)
├── .env.local # Local development (Git ignored)
├── .env.development # Development env defaults
├── .env.staging # Staging env defaults
├── .env.production # Production defaults (no sensitive info)
└── .env.test # Test environment# .env.example - This file is included in Git
# Set actual values in .env.local
# ===== App Settings =====
NODE_ENV=development
NEXT_PUBLIC_APP_URL=http://localhost:3000
# ===== Database =====
DB_HOST=
DB_PORT=5432
DB_NAME=
DB_USER=
DB_PASSWORD=
# ===== Authentication =====
AUTH_SECRET= # openssl rand -base64 32
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
# ===== External Services =====
NEXT_PUBLIC_API_URL=
API_STRIPE_SECRET=
SMTP_HOST=
SMTP_USER=
SMTP_PASSWORD=| Variable Type | .env.example | .env.local | CI/CD Secrets |
|---|---|---|---|
| App URL | Template | Local value | Per-env value |
| API endpoints | Template | Local/dev | Per-env value |
| DB password | Empty | Local value | ✅ Secrets |
| API keys | Empty | Test key | ✅ Secrets |
| JWT Secret | Empty | Local value | ✅ Secrets |
// lib/env.ts - Validate env vars at app startup
import { z } from 'zod';
const envSchema = z.object({
// Required
DATABASE_URL: z.string().url(),
AUTH_SECRET: z.string().min(32),
// Optional (with defaults)
NODE_ENV: z.enum(['development', 'staging', 'production']).default('development'),
// Client-exposed
NEXT_PUBLIC_APP_URL: z.string().url(),
});
// Validation and type inference
export const env = envSchema.parse(process.env);
// Type-safe usage
// env.DATABASE_URL ← autocomplete supportedNaming Consistency
File Structure
Security
Clean Architecture = Code resilient to change
❌ Developing without architecture
→ Spaghetti code, multiple file changes for each modification
✅ Define layers at design stage
→ Separation of concerns, easy testing, easy maintenancesrc/
├── presentation/ # or app/, pages/
│ ├── components/ # UI components
│ ├── hooks/ # State management hooks
│ └── pages/ # Page components
│
├── application/ # or services/, features/
│ ├── use-cases/ # Business use cases
│ └── services/ # API service wrappers
│
├── domain/ # or types/, entities/
│ ├── entities/ # Domain entities
│ ├── types/ # Type definitions
│ └── constants/ # Domain constants
│
└── infrastructure/ # or lib/, api/
├── api/ # API clients
├── db/ # Database connections
└── external/ # External services| Layer | Responsibility | Can Depend On | Cannot Depend On |
|---|---|---|---|
| Presentation | UI rendering, user events | Application, Domain | Infrastructure directly |
| Application | Business logic orchestration | Domain, Infrastructure | Presentation |
| Domain | Core business rules, types | Nothing (independent) | All external layers |
| Infrastructure | External system connections | Domain | Application, Presentation |
// ❌ Bad: Presentation directly calls Infrastructure
// components/UserList.tsx
import { apiClient } from '@/lib/api/client'; // Direct import forbidden!
export function UserList() {
const users = apiClient.get('/users'); // ❌
}
// ✅ Good: Presentation → Application → Infrastructure
// hooks/useUsers.ts
import { userService } from '@/services/user.service';
export function useUsers() {
return useQuery({
queryKey: ['users'],
queryFn: userService.getList, // ✅ Call through Service
});
}
// components/UserList.tsx
import { useUsers } from '@/hooks/useUsers';
export function UserList() {
const { data: users } = useUsers(); // ✅ Call through Hook
}// ===== Allowed import directions =====
// In presentation/:
import { User } from '@/domain/types'; // ✅ Domain OK
import { useUsers } from '@/hooks/useUsers'; // ✅ Same layer OK
import { userService } from '@/services/user'; // ✅ Application OK
// In application/:
import { User } from '@/domain/types'; // ✅ Domain OK
import { apiClient } from '@/lib/api/client'; // ✅ Infrastructure OK
// In domain/:
// Minimize external imports (pure types/logic only)
// In infrastructure/:
import { User } from '@/domain/types'; // ✅ Domain OK
// ===== Forbidden imports =====
// In domain/:
import { apiClient } from '@/lib/api/client'; // ❌ Infrastructure forbidden
import { Button } from '@/components/ui/button'; // ❌ Presentation forbidden
// In infrastructure/:
import { useUsers } from '@/hooks/useUsers'; // ❌ Presentation forbidden| Level | Architecture Application |
|---|---|
| Starter | Simple structure (components, lib) |
| Dynamic | 3-4 layer separation (recommended structure) |
| Enterprise | Strict layer separation + DI container |
src/
├── components/ # UI components
├── lib/ # Utilities, API
└── types/ # Type definitionssrc/
├── components/ # Presentation
│ └── ui/
├── features/ # Feature modules (Application + Presentation)
│ ├── auth/
│ └── product/
├── hooks/ # Presentation (state management)
├── services/ # Application
├── types/ # Domain
└── lib/ # Infrastructure
└── api/src/
├── presentation/
│ ├── components/
│ ├── hooks/
│ └── pages/
├── application/
│ ├── use-cases/
│ └── services/
├── domain/
│ ├── entities/
│ └── types/
└── infrastructure/
├── api/
└── db/Conventions defined in this Phase are verified in later Phases:
| Definition (Phase 2) | Verification (Phase 8) |
|---|---|
| Naming rules | Naming consistency check |
| Folder structure | Structure consistency check |
| Environment variable convention | Env var naming check |
| Clean architecture principles | Dependency direction check |
See templates/pipeline/phase-2-convention.template.md
Phase 3: Mockup Development → Rules are set, now rapid prototyping
// ❌ Handles only specific case
function formatUserName(user: User) {
return `${user.firstName} ${user.lastName}`
}
// ✅ Generic
function formatFullName(firstName: string, lastName: string) {
return `${firstName} ${lastName}`
}
// Usage
formatFullName(user.firstName, user.lastName)
formatFullName(author.first, author.last)// ❌ Tied to specific type
function calculateOrderTotal(order: Order) {
return order.items.reduce((sum, item) => sum + item.price, 0)
}
// ✅ Generalized with interface
interface HasPrice { price: number }
function calculateTotal<T extends HasPrice>(items: T[]) {
return items.reduce((sum, item) => sum + item.price, 0)
}
// Can be used in various places
calculateTotal(order.items)
calculateTotal(cart.products)
calculateTotal(invoice.lineItems)// ❌ Hardcoded structure
function UserCard({ user }: { user: User }) {
return (
<div className="card">
<img src={user.avatar} />
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
)
}
// ✅ Composable
function Card({ children, className }: CardProps) {
return <div className={cn("card", className)}>{children}</div>
}
function Avatar({ src, alt }: AvatarProps) {
return <img src={src} alt={alt} className="avatar" />
}
// Use by combining
<Card>
<Avatar src={user.avatar} alt={user.name} />
<h3>{user.name}</h3>
<p>{user.email}</p>
</Card>// ❌ Limited props
interface ButtonProps {
label: string
onClick: () => void
}
// ✅ Extend HTML attributes
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'default' | 'outline' | 'ghost'
size?: 'sm' | 'md' | 'lg'
}
// All button attributes available
<Button type="submit" disabled={isLoading}>
Save
</Button>1. Same logic used 2+ times
2. Logic is complex enough to need a name
3. Logic that needs testing
4. Can be used in other files1. Same UI pattern repeats
2. Has independent state
3. Is a reusable unit
4. JSX over 50 lines// ❌ Listing conditionals
function getStatusColor(status: string) {
if (status === 'active') return 'green'
if (status === 'pending') return 'yellow'
if (status === 'error') return 'red'
return 'gray'
}
// ✅ Configuration object
const STATUS_CONFIG = {
active: { color: 'green', label: 'Active' },
pending: { color: 'yellow', label: 'Pending' },
error: { color: 'red', label: 'Error' },
} as const
function getStatusConfig(status: keyof typeof STATUS_CONFIG) {
return STATUS_CONFIG[status] ?? { color: 'gray', label: status }
}
// Adding new status = just add config// ❌ Listing switch statements
function processPayment(method: string, amount: number) {
switch (method) {
case 'card':
// Card payment logic
break
case 'bank':
// Bank transfer logic
break
}
}
// ✅ Strategy pattern
interface PaymentStrategy {
process(amount: number): Promise<Result>
}
const paymentStrategies: Record<string, PaymentStrategy> = {
card: new CardPayment(),
bank: new BankTransfer(),
}
function processPayment(method: string, amount: number) {
const strategy = paymentStrategies[method]
if (!strategy) throw new Error(`Unknown method: ${method}`)
return strategy.process(amount)
}
// Adding new payment method = just add strategy// Extensible system
interface Plugin {
name: string
init(): void
execute(data: unknown): unknown
}
class PluginManager {
private plugins: Plugin[] = []
register(plugin: Plugin) {
this.plugins.push(plugin)
}
executeAll(data: unknown) {
return this.plugins.reduce(
(result, plugin) => plugin.execute(result),
data
)
}
}
// New feature = add plugin© ww-w-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/phase-2-convention of ww-w-ai/bkit-claude-code.
Open the folder on GitHubat commit 85b4913
Phase 2 Convention next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Phase 2 Convention this skillww-w-ai/bkit-claude-code | 601 | — | ~3.8k | Automated safety check: Notes | Apache-2.0 | |
| Nestjs Best Practicesrolling-scopes/rsschool-app | 10k | 6 repos | ~1.2k | Automated safety check: Pass | MIT | |
| ToolJet Marketplace Plugin BuilderToolJet/ToolJet | 41k | — | ~2.1k | Automated safety check: Pass | AGPL-3.0 | |
| Payloadpayloadcms/payload | 45k | 5 repos | ~6.2k | Automated safety check: Pass | MIT | |
| Infer Conventionsanonaddy/anonaddy | 4.9k | 5 repos | ~3.1k | Automated safety check: Pass | MIT | |
| RuView CLI, API and WASMruvnet/RuView | 97k | — | ~1.2k | Automated safety check: Notes | MIT |
rolling-scopes/rsschool-app
NestJS best practices and architecture patterns for building production-ready applications.
ToolJet/ToolJet
Turns an API description, such as an OpenAPI file or a Postman collection, into a connector plugin for ToolJet's marketplace and checks it with the repo's validator.
payloadcms/payload
A skill your agent uses when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API).
anonaddy/anonaddy
A skill your agent uses to analyze how a Laravel application is actually written and record its conventions as shared rules.
ruvnet/RuView
Covers the RuView `wifi-densepose` command line binary, its Axum REST API and the WebAssembly builds for browsers and ESP32, for embedding or scripting RuView.
twentyhq/twenty
Contributor guide for step three of adding a syncable entity to the Twenty server: write the validator, the migration action builder and the orchestrator wiring.
ww-w-ai/bkit-claude-code
View audit logs, decision traces, and session history for AI transparency.
ww-w-ai/bkit-claude-code
bkend.ai authentication — email/social login, JWT tokens, RBAC, session management.
ww-w-ai/bkit-claude-code
bkend.ai project tutorials (todo to SaaS) and common error troubleshooting.
ww-w-ai/bkit-claude-code
bkend.ai onboarding — MCP setup, resource hierarchy, tenant/user model, first project.
ww-w-ai/bkit-claude-code
bkend.ai file storage — upload (presigned URL), download (CDN), visibility levels, buckets.
ww-w-ai/bkit-claude-code
bkit plugin help - list available functions including /pdca (9-phase feature cycle), /sprint (8-phase feature container, v2.1.13), /control (Trust L0-L4 + SPRINTAUTORUNSCOPE), /bkit-explore, and 40+…
Categories
Define coding rules, conventions, and standards for AI collaboration. Phase 2 Convention is an agent skill from ww-w-ai/bkit-claude-code. Define coding rules, conventions, and standards for AI collaboration.
Phase 2 Convention fits situations like: backend & APIs work in your project.
Run `npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a claude-code`. Or copy the skill folder (skills/phase-2-convention in ww-w-ai/bkit-claude-code) into .claude/skills/phase-2-convention in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a codex`. Or copy the skill folder (skills/phase-2-convention in ww-w-ai/bkit-claude-code) into .agents/skills/phase-2-convention in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ww-w-ai/bkit-claude-code --skill phase-2-convention -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/phase-2-convention, .gemini/skills/phase-2-convention, .github/skills/phase-2-convention and .opencode/skills/phase-2-convention in your project.
Going by SKILL.md and its folder, Phase 2 Convention needs credentials named AUTH_SECRET, DB_PASSWORD, API_STRIPE_SECRET and SMTP_PASSWORD. Our summary lists: A credential in API_STRIPE_SECRET; A credential in AUTH_SECRET. Its frontmatter pre-approves these tools: Read, Write, Glob, Grep.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Phase 2 Convention is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.8k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Phase 2 Convention: Nestjs Best Practices (rolling-scopes/rsschool-app, 10k stars), ToolJet Marketplace Plugin Builder (ToolJet/ToolJet, 41k stars), Payload (payloadcms/payload, 45k stars) and Infer Conventions (anonaddy/anonaddy, 4.9k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ww-w-ai (a GitHub organization) maintains it in ww-w-ai/bkit-claude-code, which has 601 GitHub stars. The repository holds 44 skills in this directory. The repository was last updated on September 27, 2026.
Source: ww-w-ai/bkit-claude-code on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.