Skip to content
cccskills
FreePublished on GitHub

best-practices

Review web code for security, browser compatibility, and code quality. Covers HTTPS, dependency vulnerabilities, security headers, outdated APIs, HTML structure, error handling, and cleanup of event listeners, with examples and audit checklists to guide improvements.

OriginalShow the original description

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". Do NOT use for accessibility (use web-accessibility), SEO (use seo), performance (use core-web-vitals), or comprehensive multi-area audits (use web-quality-audit).

See how to install

Good for

  • Review HTTPS, security headers, and cookies
  • Check dependencies and handling of user input
  • Replace outdated APIs and improve browser compatibility
  • Review HTML structure and error handling

Files included (1)

  • SKILL.md12.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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:

<!-- ❌ 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)

<!-- 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:

<script nonce="abc123">
  // This inline script is allowed
</script>

Security headers

# Prevent clickjacking
X-Frame-Options: DENY

# Prevent MIME type sniffing
X-Content-Type-Options: nosniff

# Enable XSS filter (legacy browsers)
X-XSS-Protection: 1; mode=block

# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin

# Permissions policy (formerly Feature-Policy)
Permissions-Policy: geolocation=(), microphone=(), camera=()

No vulnerable libraries

# Check for vulnerabilities
npm audit
yarn audit

# Auto-fix when possible
npm audit fix

# Check specific package
npm ls lodash

Keep dependencies updated:

// package.json
{
  "scripts": {
    "audit": "npm audit --audit-level=moderate",
    "update": "npm update && npm audit fix"
  }
}

Known vulnerable patterns to avoid:

// ❌ Prototype pollution vulnerable patterns
Object.assign(target, userInput)
_.merge(target, userInput)

// ✅ Safer alternatives
const safeData = JSON.parse(JSON.stringify(userInput))

Input sanitization

// ❌ XSS vulnerable
element.innerHTML = userInput
document.write(userInput)

// ✅ Safe text content
element.textContent = userInput

// ✅ If HTML needed, sanitize
import DOMPurify from 'dompurify'
element.innerHTML = DOMPurify.sanitize(userInput)

Secure cookies

// ❌ Insecure cookie
document.cookie = "session=abc123";

// ✅ Secure cookie (server-side)
Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/

Browser compatibility

Doctype declaration

<!-- ❌ Missing or invalid doctype -->
<html lang="en">
  <head>
    <title>Page</title>
  </head>
  <body></body>
</html>

<!-- ✅ HTML5 doctype -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Page</title>
  </head>
  <body></body>
</html>

Character encoding

<!-- ❌ Missing or late charset -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Page</title>
    <meta charset="UTF-8" />
  </head>
  <body></body>
</html>

<!-- ✅ Charset as first element in head -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Page</title>
  </head>
  <body></body>
</html>

Viewport meta tag

<!-- ❌ 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

// ❌ Browser detection (brittle)
if (navigator.userAgent.includes('Chrome')) {
  // Chrome-specific code
}

// ✅ Feature detection
if ('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)

<!-- 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

// ❌ document.write (blocks parsing)
document.write('<script src="..."></script>');

// ✅ Dynamic script loading
const 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 fetch
const response = await fetch(url);

// ❌ Application Cache (deprecated)
<html manifest="cache.manifest">

// ✅ Service Workers
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

Event listener passive

// ❌ 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 explicit
element.addEventListener('touchstart', handler, { passive: false })

Console & errors

No console errors

// ❌ Errors in production
console.log('Debug info') // Remove in production
throw new Error('Unhandled') // Catch all errors

// ✅ Proper error handling
try {
  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)

class 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

// Catch unhandled errors
window.addEventListener('error', (event) => {
  errorTracker.captureException(event.error)
})

// Catch unhandled promise rejections
window.addEventListener('unhandledrejection', (event) => {
  errorTracker.captureException(event.reason)
})

Source maps

Production configuration

// ❌ Source maps exposed in production
// webpack.config.js
module.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 production
module.exports = {
  devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',
}

Performance best practices

Avoid blocking patterns

// ❌ 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

// ❌ Handler on every element
items.forEach((item) => {
  item.addEventListener('click', handleClick)
})

// ✅ Event delegation
container.addEventListener('click', (e) => {
  if (e.target.matches('.item')) {
    handleClick(e)
  }
})

Memory management

// ❌ Memory leak (never removed)
const handler = () => {
  /* ... */
}
window.addEventListener('resize', handler)

// ✅ Cleanup when done
const handler = () => {
  /* ... */
}
window.addEventListener('resize', handler)

// Later, when component unmounts:
window.removeEventListener('resize', handler)

// ✅ Using AbortController
const controller = new AbortController()
window.addEventListener('resize', handler, { signal: controller.signal })

// Cleanup:
controller.abort()

Code quality

Valid HTML

<!-- ❌ Invalid HTML -->
<div id="header">
  <div id="header">
    <!-- Duplicate ID -->
  </div>

  <ul>
    <div>Item</div>
    <!-- Invalid child -->
  </ul>

  <a href="/"><button>Click</button></a>
  <!-- Invalid nesting -->
</div>

<!-- ✅ Valid HTML -->
<header id="site-header"></header>

<ul>
  <li>Item</li>
</ul>

<a href="/" class="button">Click</a>

Semantic 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

<!-- ❌ 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

// ❌ Request on page load (bad UX, often denied)
navigator.geolocation.getCurrentPosition(success, error)

// ✅ Request in context, after user action
findNearbyButton.addEventListener('click', async () => {
  // Explain why you need it
  if (await showPermissionExplanation()) {
    navigator.geolocation.getCurrentPosition(success, error)
  }
})

Permissions policy

<!-- 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

ToolPurpose
npm auditDependency vulnerabilities
SecurityHeaders.comHeader analysis
W3C ValidatorHTML validation
LighthouseBest practices audit
ObservatorySecurity scan

References

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

accessibility

FreeSummary

Audit and improve website accessibility using WCAG 2.1, guidelines for making web content usable by people with disabilities. Check image descriptions, contrast, forms, keyboard controls, and screen reader support with automated and manual testing.

  • Checking a site before launch
  • Fixing keyboard navigation and focus
  • Improving form labels and error messages
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

ai-cold-outreach

FreeSummary

Plan personalized sales emails to prospects you have not contacted before. This skill covers prospect selection, contact research, email drafts, follow-up sequences, inbox delivery, and reply handling, with guidance on tools and campaign improvements.

  • Drafting personalized sales emails for new prospects
  • Planning a sequence of emails and follow-ups
  • Investigating low reply rates or spam placement
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

ai-pricing

FreeSummary

Plan pricing for AI products by comparing charges based on usage, tasks, or results. Use customer value and computing costs to shape pricing tiers, usage limits, hybrid plans, and margin improvement strategies.

  • Choosing how to charge for an AI product
  • Designing pricing tiers and usage limits
  • Reviewing low margins
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

ai-sdr

FreeSummary

Plan AI sales development systems that qualify prospects, organize outreach, classify replies, and hand opportunities to people. Use customer criteria, budget, CRM setup, and sales goals to shape platform choices and a four-week rollout plan.

  • Planning an AI sales development rollout
  • Defining prospect scores and qualification criteria
  • Improving outreach with low reply or meeting conversion rates
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

ai-seo

FreeSummary

Plan AI-assisted SEO, from keyword research and competitor comparison pages to content production using data and templates. It also guides content changes for AI search citations, tool selection, quality checks, and ongoing performance tracking.

  • Planning competitor alternative and comparison pages
  • Designing page production using data and templates
  • Reviewing content for citations in AI Overviews
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

ai-ugc-ads

FreeSummary

Plan UGC campaigns, ads built around user-style content, from creator recruitment and production briefs to AI video variations. Organize organic testing, paid promotion, and creative refreshes for TikTok, Meta, and YouTube Shorts.

  • Recruiting creators for product videos
  • Writing a short video production brief
  • Planning AI-generated ad variations
tech-leads-club/agent-skills7.1KUpdated Oct 22, 2026

See all skills by tech-leads-club

Report a problem with this skill