Claude explains exactly as much as you need.
Three built-in output styles nobody talks about. Explanatory mode justifies every decision. Learning mode teaches while building. Plus: write your own.
The 3 built-in styles
Select one to see the difference in output
Adding rate limiting using express-rate-limit. Applied at the login route level with a 15-minute window and 5 attempts per IP.
File edited: src/routes/auth.ts
Approach chosen: express-rate-limit (route-level)
Why this library: Minimal setup, battle-tested, integrates with Redis for distributed systems later.
Configuration decisions
- 15-minute window: Standard for auth endpoints
- 5 attempts: OWASP recommendation for login endpoints
- IP-based keying: Prevents attackers rotating IPs
Adding rate limiting using express-rate-limit. Applied at the login route level with a 15-minute window and 5 attempts per IP.
Approach chosen: express-rate-limit (route-level)
Why this library: Minimal setup, battle-tested, integrates with Redis for distributed systems later. Alternatives considered: custom middleware (more control but reinventing the wheel), nginx-level rate limiting (more robust but out of scope).
Configuration decisions
- 15-minute window: Standard for auth endpoints. Short enough to mitigate brute force, long enough to not frustrate legit users with typos.
- 5 attempts: OWASP recommendation for login endpoints.
- IP-based keying: Changed to username+IP to prevent attackers rotating IPs. Trade-off: adds complexity, needed for real security.
What this does NOT protect against
- Distributed attacks across many IPs — needs a WAF for that
- Credential stuffing — needs breach detection (HaveIBeenPwned API)
Adding rate limiting using express-rate-limit...
What is rate limiting?
Rate limiting restricts how many requests a client can make in a time window. On auth endpoints, this stops brute-force attacks — where an attacker tries thousands of password combinations automatically.
How express-rate-limit works
The middleware intercepts each request, checks a counter for the client's IP, and either allows the request or returns a 429 Too Many Requests response. By default it stores counters in memory.
Key concept: rate limiting vs throttling
- Rate limiting: Hard block after X requests
- Throttling: Slow down responses instead of blocking
Learn more: expressjs.com/en/guide/using-middleware, OWASP auth testing guide.
How to switch styles
Three ways to activate a style
/output-style explanatory # applies to this session only # resets when you close
# CLAUDE.md output-style: learning # applies to all sessions
{
"outputStyle": "explanatory",
// applies to all projects
}Write a custom output style
Define exactly how Claude responds — tone, format, depth
# .claude/styles/senior-review.md --- name: senior-review description: Senior engineer reviewing production code --- When reviewing or writing code: - Start with the riskiest issue immediately - State what's wrong and WHY it matters - Give the fix in 1-3 lines, not paragraphs - Label severity: [CRITICAL] [HIGH] [MEDIUM] [LOW] - End with: "everything else looks fine" - Never compliment working code
When to use each style
A practical guide
- → Daily development work
- → You know what you want
- → Speed over explanation
- → Senior devs, experienced users
- → Security audits
- → Architecture decisions
- → Code reviews for clients
- → Justify implementation choices
- → Onboarding junior devs
- → New tech stack
- → Teaching sessions
- → Client workshops