Claude Agent Skill · by Addyosmani

Best Practices

The best-practices skill helps developers apply modern web development standards by providing guidance on security, browser compatibility, and code quality patt

Install
Terminal · npx
$npx skills add https://github.com/addyosmani/web-quality-skills --skill best-practices
Works with Paperclip

How Best Practices fits into a Paperclip company.

Best Practices drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md583 lines
Expand
---name: best-practicesdescription: Apply modern web development best practices for security, compatibility, and code quality. Use when asked to "apply best practices", "security audit", "modernize code", "code quality review", or "check for vulnerabilities".license: MITmetadata:  author: web-quality-skills  version: "1.0"--- # Best practices Modern web development standards based on Lighthouse best practices audits. Covers security, browser compatibility, and code quality patterns. ## Security ### HTTPS everywhere **Enforce HTTPS:**```html<!-- ❌ Mixed content --><img src="http://example.com/image.jpg"><script src="http://cdn.example.com/script.js"></script> <!-- ✅ HTTPS only --><img src="https://example.com/image.jpg"><script src="https://cdn.example.com/script.js"></script> <!-- ✅ Protocol-relative (will use page's protocol) --><img src="//example.com/image.jpg">``` **HSTS Header:**```Strict-Transport-Security: max-age=31536000; includeSubDomains; preload``` ### Content Security Policy (CSP) ```html<!-- Basic CSP via meta tag --><meta http-equiv="Content-Security-Policy"       content="default-src 'self';                script-src 'self' https://trusted-cdn.com;                style-src 'self' 'unsafe-inline';               img-src 'self' data: https:;               connect-src 'self' https://api.example.com;"> <!-- Better: HTTP header -->``` **CSP Header (recommended):**```Content-Security-Policy:   default-src 'self';  script-src 'self' 'nonce-abc123' https://trusted.com;  style-src 'self' 'nonce-abc123';  img-src 'self' data: https:;  connect-src 'self' https://api.example.com;  frame-ancestors 'self';  base-uri 'self';  form-action 'self';``` **Using nonces for inline scripts:**```html<script nonce="abc123">  // This inline script is allowed</script>``` ### Security headers ```# Prevent clickjackingX-Frame-Options: DENY # Prevent MIME type sniffingX-Content-Type-Options: nosniff # Enable XSS filter (legacy browsers)X-XSS-Protection: 1; mode=block # Control referrer informationReferrer-Policy: strict-origin-when-cross-origin # Permissions policy (formerly Feature-Policy)Permissions-Policy: geolocation=(), microphone=(), camera=()``` ### No vulnerable libraries ```bash# Check for vulnerabilitiesnpm audityarn audit # Auto-fix when possiblenpm audit fix # Check specific packagenpm ls lodash``` **Keep dependencies updated:**```json// package.json{  "scripts": {    "audit": "npm audit --audit-level=moderate",    "update": "npm update && npm audit fix"  }}``` **Known vulnerable patterns to avoid:**```javascript// ❌ Prototype pollution vulnerable patternsObject.assign(target, userInput);_.merge(target, userInput); // ✅ Safer alternativesconst safeData = JSON.parse(JSON.stringify(userInput));``` ### Input sanitization ```javascript// ❌ XSS vulnerableelement.innerHTML = userInput;document.write(userInput); // ✅ Safe text contentelement.textContent = userInput; // ✅ If HTML needed, sanitizeimport DOMPurify from 'dompurify';element.innerHTML = DOMPurify.sanitize(userInput);``` ### Secure cookies ```javascript// ❌ Insecure cookiedocument.cookie = "session=abc123"; // ✅ Secure cookie (server-side)Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/``` --- ## Browser compatibility ### Doctype declaration ```html<!-- ❌ Missing or invalid doctype --><HTML><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <!-- ✅ HTML5 doctype --><!DOCTYPE html><html lang="en">``` ### Character encoding ```html<!-- ❌ Missing or late charset --><html><head>  <title>Page</title>  <meta charset="UTF-8"></head> <!-- ✅ Charset as first element in head --><html><head>  <meta charset="UTF-8">  <title>Page</title></head>``` ### Viewport meta tag ```html<!-- ❌ Missing viewport --><head>  <title>Page</title></head> <!-- ✅ Responsive viewport --><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1">  <title>Page</title></head>``` ### Feature detection ```javascript// ❌ Browser detection (brittle)if (navigator.userAgent.includes('Chrome')) {  // Chrome-specific code} // ✅ Feature detectionif ('IntersectionObserver' in window) {  // Use IntersectionObserver} else {  // Fallback} // ✅ Using @supports in CSS@supports (display: grid) {  .container {    display: grid;  }} @supports not (display: grid) {  .container {    display: flex;  }}``` ### Polyfills (when needed) ```html<!-- Load polyfills conditionally --><script>  if (!('fetch' in window)) {    document.write('<script src="/polyfills/fetch.js"><\/script>');  }</script> <!-- Or use polyfill.io --><script src="https://polyfill.io/v3/polyfill.min.js?features=fetch,IntersectionObserver"></script>``` --- ## Deprecated APIs ### Avoid these ```javascript// ❌ document.write (blocks parsing)document.write('<script src="..."></script>'); // ✅ Dynamic script loadingconst script = document.createElement('script');script.src = '...';document.head.appendChild(script); // ❌ Synchronous XHR (blocks main thread)const xhr = new XMLHttpRequest();xhr.open('GET', url, false); // false = synchronous // ✅ Async fetchconst response = await fetch(url); // ❌ Application Cache (deprecated)<html manifest="cache.manifest"> // ✅ Service Workersif ('serviceWorker' in navigator) {  navigator.serviceWorker.register('/sw.js');}``` ### Event listener passive ```javascript// ❌ Non-passive touch/wheel (may block scrolling)element.addEventListener('touchstart', handler);element.addEventListener('wheel', handler); // ✅ Passive listeners (allows smooth scrolling)element.addEventListener('touchstart', handler, { passive: true });element.addEventListener('wheel', handler, { passive: true }); // ✅ If you need preventDefault, be explicitelement.addEventListener('touchstart', handler, { passive: false });``` --- ## Console & errors ### No console errors ```javascript// ❌ Errors in productionconsole.log('Debug info'); // Remove in productionthrow new Error('Unhandled'); // Catch all errors // ✅ Proper error handlingtry {  riskyOperation();} catch (error) {  // Log to error tracking service  errorTracker.captureException(error);  // Show user-friendly message  showErrorMessage('Something went wrong. Please try again.');}``` ### Error boundaries (React) ```jsxclass ErrorBoundary extends React.Component {  state = { hasError: false };    static getDerivedStateFromError(error) {    return { hasError: true };  }    componentDidCatch(error, info) {    errorTracker.captureException(error, { extra: info });  }    render() {    if (this.state.hasError) {      return <FallbackUI />;    }    return this.props.children;  }} // Usage<ErrorBoundary>  <App /></ErrorBoundary>``` ### Global error handler ```javascript// Catch unhandled errorswindow.addEventListener('error', (event) => {  errorTracker.captureException(event.error);}); // Catch unhandled promise rejectionswindow.addEventListener('unhandledrejection', (event) => {  errorTracker.captureException(event.reason);});``` --- ## Source maps ### Production configuration ```javascript// ❌ Source maps exposed in production// webpack.config.jsmodule.exports = {  devtool: 'source-map', // Exposes source code}; // ✅ Hidden source maps (uploaded to error tracker)module.exports = {  devtool: 'hidden-source-map',}; // ✅ Or no source maps in productionmodule.exports = {  devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',};``` --- ## Performance best practices ### Avoid blocking patterns ```javascript// ❌ Blocking script<script src="heavy-library.js"></script> // ✅ Deferred script<script defer src="heavy-library.js"></script> // ❌ Blocking CSS import@import url('other-styles.css'); // ✅ Link tags (parallel loading)<link rel="stylesheet" href="styles.css"><link rel="stylesheet" href="other-styles.css">``` ### Efficient event handlers ```javascript// ❌ Handler on every elementitems.forEach(item => {  item.addEventListener('click', handleClick);}); // ✅ Event delegationcontainer.addEventListener('click', (e) => {  if (e.target.matches('.item')) {    handleClick(e);  }});``` ### Memory management ```javascript// ❌ Memory leak (never removed)const handler = () => { /* ... */ };window.addEventListener('resize', handler); // ✅ Cleanup when doneconst handler = () => { /* ... */ };window.addEventListener('resize', handler); // Later, when component unmounts:window.removeEventListener('resize', handler); // ✅ Using AbortControllerconst controller = new AbortController();window.addEventListener('resize', handler, { signal: controller.signal }); // Cleanup:controller.abort();``` --- ## Code quality ### Valid HTML ```html<!-- ❌ Invalid HTML --><div id="header"><div id="header"> <!-- Duplicate ID --> <ul>  <div>Item</div> <!-- Invalid child --></ul> <a href="/"><button>Click</button></a> <!-- Invalid nesting --> <!-- ✅ Valid HTML --><header id="site-header"></header> <ul>  <li>Item</li></ul> <a href="/" class="button">Click</a>``` ### Semantic HTML ```html<!-- ❌ Non-semantic --><div class="header">  <div class="nav">    <div class="nav-item">Home</div>  </div></div><div class="main">  <div class="article">    <div class="title">Headline</div>  </div></div> <!-- ✅ Semantic HTML5 --><header>  <nav>    <a href="/">Home</a>  </nav></header><main>  <article>    <h1>Headline</h1>  </article></main>``` ### Image aspect ratios ```html<!-- ❌ Distorted images --><img src="photo.jpg" width="300" height="100"><!-- If actual ratio is 4:3, this squishes the image --> <!-- ✅ Preserve aspect ratio --><img src="photo.jpg" width="300" height="225"><!-- Actual 4:3 dimensions --> <!-- ✅ CSS object-fit for flexibility --><img src="photo.jpg" style="width: 300px; height: 200px; object-fit: cover;">``` --- ## Permissions & privacy ### Request permissions properly ```javascript// ❌ Request on page load (bad UX, often denied)navigator.geolocation.getCurrentPosition(success, error); // ✅ Request in context, after user actionfindNearbyButton.addEventListener('click', async () => {  // Explain why you need it  if (await showPermissionExplanation()) {    navigator.geolocation.getCurrentPosition(success, error);  }});``` ### Permissions policy ```html<!-- Restrict powerful features --><meta http-equiv="Permissions-Policy"       content="geolocation=(), camera=(), microphone=()"> <!-- Or allow for specific origins --><meta http-equiv="Permissions-Policy"       content="geolocation=(self 'https://maps.example.com')">``` --- ## Audit checklist ### Security (critical)- [ ] HTTPS enabled, no mixed content- [ ] No vulnerable dependencies (`npm audit`)- [ ] CSP headers configured- [ ] Security headers present- [ ] No exposed source maps ### Compatibility- [ ] Valid HTML5 doctype- [ ] Charset declared first in head- [ ] Viewport meta tag present- [ ] No deprecated APIs used- [ ] Passive event listeners for scroll/touch ### Code quality- [ ] No console errors- [ ] Valid HTML (no duplicate IDs)- [ ] Semantic HTML elements used- [ ] Proper error handling- [ ] Memory cleanup in components ### UX- [ ] No intrusive interstitials- [ ] Permission requests in context- [ ] Clear error messages- [ ] Appropriate image aspect ratios ## Tools | Tool | Purpose ||------|---------|| `npm audit` | Dependency vulnerabilities || [SecurityHeaders.com](https://securityheaders.com) | Header analysis || [W3C Validator](https://validator.w3.org) | HTML validation || Lighthouse | Best practices audit || [Observatory](https://observatory.mozilla.org) | Security scan | ## References - [MDN Web Security](https://developer.mozilla.org/en-US/docs/Web/Security)- [OWASP Top 10](https://owasp.org/www-project-top-ten/)- [Web Quality Audit](../web-quality-audit/SKILL.md)