best-practices
Apply modern web development best practices for security, compatibility, and code quality
Install / Use
npx skills add tech-leads-club/agent-skills --skill web-best-practicesInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
SecuritySupported Platforms
Our assessment of best-practices
best-practices scores 93/100 on our quality scale, 229th of 653 Security skills we index (top 36%).
Its SKILL.md is 12 KB long, well organised into 49 sections with 30 code examples: a thorough specification that gives an agent plenty to work with.
With 6,832 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 6 days ago, so best-practices is actively maintained.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 88/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.
Automated pattern scan on 2026-09-26. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
best-practices compared with similar skills
All 4 of these similar skills score higher than best-practices; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| best-practices (this skill)by tech-leads-club | 93 | 6.8k | 6d ago | SKILL.md |
| algorithmic-artby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 130.2k | 5d ago | SKILL.md |
| ui-ux-pro-maxby nextlevelbuilder | 100 | 130.2k | 5d ago | SKILL.md |
Frequently asked questions
- How do I install best-practices?
- Run
npx skills add tech-leads-club/agent-skills --skill best-practices. The install tabs above show the steps for each supported agent. - Which AI agents does best-practices work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is best-practices safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It declares no license and scores 88/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is best-practices still maintained?
- The repository was last updated 6 days ago, so best-practices is actively maintained.
Skill content
View source on GitHubname: best-practices 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). license: MIT metadata: 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:
<!-- ❌ 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
| Tool | Purpose | | ------------------------
Truncated for display — read the full file on GitHub.
Related Skills
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
130.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
ui-ux-pro-max
130.2kUI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
