$npx -y skills add addyosmani/web-quality-skills --skill best-practicesApply 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".
| 1 | # Best practices |
| 2 | |
| 3 | Modern web development standards based on Lighthouse best practices audits. Covers security, browser compatibility, and code quality patterns. |
| 4 | |
| 5 | ## Security |
| 6 | |
| 7 | ### HTTPS everywhere |
| 8 | |
| 9 | **Enforce HTTPS:** |
| 10 | ```html |
| 11 | <!-- ❌ Mixed content --> |
| 12 | <img src="http://example.com/image.jpg"> |
| 13 | <script src="http://cdn.example.com/script.js"></script> |
| 14 | |
| 15 | <!-- ✅ HTTPS only --> |
| 16 | <img src="https://example.com/image.jpg"> |
| 17 | <script src="https://cdn.example.com/script.js"></script> |
| 18 | ``` |
| 19 | |
| 20 | Avoid protocol-relative URLs (`//example.com/...`) — they're an HTTP-era pattern with no benefit on HTTPS-only sites and hide the actual scheme from reviewers. |
| 21 | |
| 22 | **HSTS Header:** |
| 23 | ``` |
| 24 | Strict-Transport-Security: max-age=31536000; includeSubDomains; preload |
| 25 | ``` |
| 26 | |
| 27 | ### Content Security Policy (CSP) |
| 28 | |
| 29 | ```html |
| 30 | <!-- Basic CSP via meta tag --> |
| 31 | <meta http-equiv="Content-Security-Policy" |
| 32 | content="default-src 'self'; |
| 33 | script-src 'self' https://trusted-cdn.com; |
| 34 | style-src 'self' 'unsafe-inline'; |
| 35 | img-src 'self' data: https:; |
| 36 | connect-src 'self' https://api.example.com;"> |
| 37 | |
| 38 | <!-- Better: HTTP header --> |
| 39 | ``` |
| 40 | |
| 41 | **CSP Header (recommended):** |
| 42 | ``` |
| 43 | Content-Security-Policy: |
| 44 | default-src 'self'; |
| 45 | script-src 'self' 'nonce-abc123' https://trusted.com; |
| 46 | style-src 'self' 'nonce-abc123'; |
| 47 | img-src 'self' data: https:; |
| 48 | connect-src 'self' https://api.example.com; |
| 49 | frame-ancestors 'self'; |
| 50 | base-uri 'self'; |
| 51 | form-action 'self'; |
| 52 | ``` |
| 53 | |
| 54 | **Using nonces for inline scripts:** |
| 55 | ```html |
| 56 | <script nonce="abc123"> |
| 57 | // This inline script is allowed |
| 58 | </script> |
| 59 | ``` |
| 60 | |
| 61 | ### Trusted Types (modern DOM-XSS defense) |
| 62 | |
| 63 | A strict CSP blocks loading untrusted *script files*, but it doesn't stop a string from reaching `innerHTML`, `eval`, or other DOM-XSS sinks. Trusted Types — Baseline across all major browsers since early 2026 — closes that hole by making sinks reject raw strings and accept only typed objects produced by a named policy. |
| 64 | |
| 65 | ``` |
| 66 | Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default; |
| 67 | ``` |
| 68 | |
| 69 | ```javascript |
| 70 | // One central policy that does the sanitization |
| 71 | const escape = trustedTypes.createPolicy('default', { |
| 72 | createHTML: (s) => DOMPurify.sanitize(s, { RETURN_TRUSTED_TYPE: true }) |
| 73 | }); |
| 74 | |
| 75 | // ❌ This now throws TypeError under enforcement |
| 76 | element.innerHTML = userInput; |
| 77 | |
| 78 | // ✅ Goes through the policy |
| 79 | element.innerHTML = escape.createHTML(userInput); |
| 80 | ``` |
| 81 | |
| 82 | Roll out with `Content-Security-Policy-Report-Only` first to find every sink usage in your app, then flip to enforcement. Angular has built-in Trusted Types support; React 19+ produces TrustedHTML when Trusted Types are enforced; for everything else, [DOMPurify](https://github.com/cure53/DOMPurify) is the de-facto sanitizer. |
| 83 | |
| 84 | ### Subresource Integrity (SRI) for third-party scripts |
| 85 | |
| 86 | Pin every `<script>` and `<link rel="stylesheet">` you load from a CDN you don't control. If the CDN is compromised — as happened to polyfill.io in 2024 — the browser refuses to execute a file whose hash doesn't match. |
| 87 | |
| 88 | ```html |
| 89 | <script src="https://cdn.example.com/lib@1.2.3/dist/lib.js" |
| 90 | integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" |
| 91 | crossorigin="anonymous"></script> |
| 92 | ``` |
| 93 | |
| 94 | `integrity` accepts space-separated hashes; include the next version's hash before rotating to avoid downtime. Generate with `openssl dgst -sha384 -binary file.js | openssl base64 -A`. SRI requires `crossorigin` and an `Access-Control-Allow-Origin` response header from the CDN. |
| 95 | |
| 96 | ### Security headers |
| 97 | |
| 98 | ``` |
| 99 | # Prevent clickjacking — prefer CSP `frame-ancestors` (above); X-Frame-Options |
| 100 | # is the legacy fallback for older browsers. |
| 101 | X-Frame-Options: DENY |
| 102 | |
| 103 | # Prevent MIME type sniffing |
| 104 | X-Content-Type-Options: nosniff |
| 105 | |
| 106 | # Do NOT send X-XSS-Protection. The legacy browser XSS auditor was deprecated |
| 107 | # and removed (Chrome 78, Edge 17), and in some cases it introduced its own |
| 108 | # vulnerabilities. Use a strict CSP + Trusted Types (below) instead. |
| 109 | |
| 110 | # Control referrer information |
| 111 | Referrer-Policy: strict-origin-when-cross-origin |
| 112 | |
| 113 | # Permissions policy (formerly Feature-Policy) |
| 114 | Permissions-Policy: geolocation=(), microphone=(), camera=() |
| 115 | ``` |
| 116 | |
| 117 | ### No vulnerable libraries |
| 118 | |
| 119 | ```bash |
| 120 | # Check for vulnerabilities |
| 121 | npm audit |
| 122 | yarn audit |
| 123 | |
| 124 | # Auto-fix when possible |
| 125 | npm audit fix |
| 126 | |
| 127 | # Check specific package |
| 128 | npm ls lodash |
| 129 | ``` |
| 130 | |
| 131 | **Keep dependencies updated:** |
| 132 | ```json |
| 133 | // package.json |
| 134 | { |
| 135 | "scripts": { |
| 136 | "audit": "npm audit --audit-level=moderate", |
| 137 | "update": "npm update && npm audit fix" |
| 138 | } |
| 139 | } |
| 140 | ``` |
| 141 | |
| 142 | **Known vulnerable patterns to avoid:** |
| 143 | ```javascript |
| 144 | // ❌ Recursive merges of untrusted input can pollute Object.prototype |
| 145 | // via __proto__, constructor, or prototype ke |