Best practices and coding guidelines
A guide for building better websites and applications.
Don't follow this guide thoughtlessly. Read the references to learn more about certain rules. Some practices become outdated as the web evolves.
This page is a continuous work in progress.
General
- Be an early evaluator, but late adopter.
- Provide 404 and 50x error pages.
- Inline all external resources on error pages (e.g. CSS, images).
- Test your website with ad blockers enabled.
- Monitor your website's availability, e.g. with Uptime Robot.
- Offer an RSS feed for any kind of articles. Include the full content instead of snippets.
HTML
- Do not use protocol-relative URLs, e.g.
//example.com. - Prefer
deferoverasyncwhen loading scripts. - Provide basic document metadata and boilerplate:
- Define a doctype at the beginning of an HTML page.
- Specify the document's language.
- Declare an explicit character encoding.
- Add mobile support.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page Title</title>- Define favicons:
- Place a
favicon.icoin the root document folder, containing at least 16×16 and 32×32 icons. - Consider using SVG favicons.
- Place a 180×180
apple-touch-icon.pngin the root document folder for iOS devices. - Create a 192x192 icon for Android devices:
- Place a
<link rel="icon" sizes="192x192" href="/favicon-192.png">- Place paragraphs in a
<p>tag. Do not use multiple<br>tags. - Do not write closing tag comments, e.g.
<!-- end .content -->. - Do not set values for boolean attributes, such as
disabled,selectedorchecked. - Provide
type, inputmode, autocomplete and enterkeyhint values to input fields if applicable. Test possible values here. - Use
translate="no"for content that should not be translated. - Avoid number inputs. If necessary, use number inputs only for real numeric values.
CSS
- Consider including normalize.css or sanitize.css before own stylesheets.
- Don't use @import.
- Avoid shorthand properties.
- Use
border-boxbox-sizing by default. - Place media queries close to their relevant rule sets. Do not bundle them in a separate stylesheet or at the end of the document.
- Provide a print layout.
- Emulate print media in Chrome.
- Support forced-colors with custom properties.
- Remove unused CSS.
- Consider a utility-first approach.
- Use CSS containment when appropriate.
- Use relative units.
- When using
scroll-behavior: smooth, provide a workaround for the browser search. - Ignore the performance impact of CSS selectors.
- Use
@media (hover: hover)instead of:hoverto prevent hover states on touch press.
JavaScript
- Test your website with JavaScript disabled, because not everyone has JavaScript.
- Add
<noscript>as fallback.
- Add
- Organize your files around features, not roles.
- Use subresource integrity for all external scripts.
- Use standardized keyboard event handling:
- Use
keyorcodeinstead ofcharCode,keyCodeorwhich. - Do not use the
keypressevent.
- Use
- Don't attach tooltips to
document.body.
ReactJS
- Consider using PureComponent over Component.
- For functional components, React.memo can be used since React 16.6.0.
- Use this method sparingly for components whose rendering time could be neglected. Others advise to memoize every component.
- Don't overuse useCallback.
- Pay attention to using
bindor arrow functions inrender()to avoid creating new values each render cycle.- For functional components, use useCallback to memoize the callback.
- For class components, define the callback outside the
render()method.
- As of React 16, functional components are slightly more performant than class components.
- Use code splitting to lazy load components that are not instantly needed with React.lazy and
React.Suspense. - Use React.StrictMode.
- Be aware that StrictMode components may render twice in development mode.
- Never mutate props.
- Don't use array indexes as keys.
- Render lists in dedicated components.
- Use multiple
useEffectcalls for independent concerns. - Use ternaries rather than
&&in JSX. - Prefer composition when creating reusable component abstractions.
- Use primitives in hook dependency arrays (
[name]instead of[user]whenuser.nameis being used).
Redux
- Do not mutate state.
- Do not put non-serializable values in state or actions.
- Prefer normalized state.
- Don't use isLoading booleans.
Images
- Consider using inline SVGs instead of icon fonts.
- Use WEBP/AVIF images with a fallback for older browsers.
- Use responsive images, especially for Retina displays.
- Use lazy loading for non-critical images:
loading="lazy".
Code quality
- Enforce a zero-warnings policy.
- Avoid handling code issues as warnings. Set linter rules to either "off" or "error".
- Invest time to come up with good names for variables, functions, etc.
- Follow a consistent naming of design tokens, including validation states.
- Don't fear long names, see German Naming Convention.
- Include units in variable names.
- Avoid hasty abstractions.
- Prefer duplication over the wrong abstraction.
- Avoid adding lava layers, i.e., introducing new patterns on top of existing ones that solve the same problem.
- Use consistent coding conventions, automatically enforced.
- Think globally, act locally: create reusable components, but don't cover all theoretical future enhancements.
- Make impossible states impossible.
- Don't rely on code coverage alone.
- Don't create a general
utilspackage.
Testing
- Use snapshot tests only when appropriate. Using snapshot tests for UI components is usually a bad idea.
Performance
- Find performance issues with Google's PageSpeed Insights.
- Enable gzip compression and test it.
- Choose readable code over micro performance optimizations such as performant CSS selectors or using a for loop over forEach.
- Serve videos instead of GIFs.
- Use priority hints (fetchpriority) to lower/increase the fetch priority of resources.
Fonts
- Test your website with custom fonts disabled.
- Consider avoiding web fonts.
- Use Google WebFonts helper to create an optimized font subset.
- Preload your most important font files. You probably don't need to preload italic/bold variants.
- Consider trade-offs of performance best practices.
- Don't use system-ui font family.
- Don't change font weight on hover to prevent layout shift.
Design
- Ensure a thumb-friendly navigational design.
- Remove unnecessary borders from design elements.
- Consider replacing borders with box shadows.
- Avoid floating labels
- Avoid messages under fields.
- Use at least a 16px font size for inputs. This will also prevent zooming issues with iOS Safari.
Accessibility
- Use semantic HTML.
- Provide an alt text for all images. Use
alt=""for decorative images. - Provide a
labelfor all form inputs. Theplaceholderattribute is not a usable alternative. - Write descriptive links.
- The contrast ratio between the background and the foreground should be as high as possible.
- Avoid low-contrast font colors.
- When using colors to communicate information (such as states or graphs), use different styles or add a text/icon to distinguish different states. This is important for both colorblind people and for printing a page in grayscale.
- The tab order should go from top to bottom, from left to right
- Do not use a
tabindexvalue greater than 0. - Do not hide the focus ring without providing an alternative.
- Do not use a
- Be aware of screen reader conflicts with accesskeys, making accesskeys mostly useless for blind users.
- Make sure zooming in/out doesn't break the page.
- Avoid using icons without labels
- Ensure that interactive controls have at least a 44×44px target click size.
View my accessibility notes for more information.
Security
- Use HTTPS everywhere. Yes, your site does need HTTPS.
- Test your SSL rating on SSL Labs.
- Define a Certificate Authority Authorization (CAA).
- Define a Referrer Policy.
- Define a Content Security Policy.
- Scan your website for security issues:
- Hash user passwords using a cryptographically strong algorithm, like Argon2, PBKDF2, Scrypt, or Bcrypt.
- Enable Two-Factor Authentication (2FA).
- Don't take
npm auditfindings at face value.
Privacy
- Include a privacy notice.
- Comply with the EU Cookie Law.
- Check the cookies for a domain with Cookie Metrix.
- Collect only the bare minimum amount of data needed for its purpose.
- Do not opt in into Google's FLoC network.
SEO
- Verify your site in Google Search Console.
- Use canonical URLs to prevent search engines from indexing duplicate content.
- Provide a sitemap.
- Provide a robots.txt file.
- Consider blocking AI data scrapers.
- Provide Open Graph attributes.
- The optimal size for
og:imageis 1200 × 630 px. The aspect ratio should be around 1.91:1.
- The optimal size for
- Provide JSON-LD information.
- Keep title 60 characters or fewer.
- Keep meta descriptions 160 characters or fewer.
User experience
- Be consistent. Use familiar conventions and apply them consistently.
- Provide a way to try the app without signing up:
- Public demo.
- Guest account, which can be easily turned into a full account.
- Show a different view when there is no data, e.g. a tutorial link or description (examples).
- Only provide choices when a good default does not exist.
- Options can be costlier than features.
- Provide smart defaults based on frequently chosen input.
- Include something funny/goofy.
- Hide easter-eggs.
- Send custom HTTP headers.
- Provide a search feature, e.g. using OpenSearch.
- Ensure good visual stability: elements on the page should not shift in ways that users don't expect.
- Know when (not) to split a form field into multiple inputs.
- Don't use flags to represent a language
- Don't set the language of your website based on user location.
- Test for unnecessary scrollbars.
- Tie the sign-up button text to your product.
- Use the ellipsis character in menus to indicate an additional user input.
- When adding links to downloadable files, include information about the file's size and its format.
- Mark required input fields.
- Redirect a request to
/.well-known/change-passwordto the change-passwords URL. - Provide screenshots in your web app manifest.
- Don't sort by average rating.
- Don't automatically focus the first input, e.g. via
autofocus. - Don't disable form controls.
- Avoid setting a maximum input length with
maxlength. - Do not use toasts, you can't make them accessible.
DevOps
- Avoid 2:00 and 3:00 am cron jobs
- Prefer the
~allSPF mechanism instead of-allor?all.
Server
Git
- Commit early and often. Perfect later.
- Copy/move a file in a different commit from any changes to it to retain the correct file history.
- Do not force-push public branches that other people are working on.
- Create a tag for each release using semantic versioning, e.g.
v1.4.8.- Using a prefix like
vis handy for shell completion. - Create a release for each tag on GitHub.
- Using a prefix like
GitHub
- Provide a social media image.
Code collaboration
- Include guidelines for contributors in CONTRIBUTING.MD.
- Include a humans.txt file to acknowledge project contributors.
- Use npm scripts so no further build tools have to be installed or used.
- Consider recording a screencast or a console demo to demonstrate the setup and usage.
Marketing
- Summarize your core idea in a single sentence (elevator pitch).
Business
- Consider the purchasing power parity on product/service pricing.
Writing
Documentation
- Keep technical documentation close to the code.
- Ensure documentation is easy to amend.
Style
- Prefer active voice to passive voice.
- Avoid ambiguous pronouns:
- In general, if more than five words separate your noun from your pronoun, consider repeating the noun instead of using the pronoun.
- If you introduce a second noun between your noun and your pronoun, reuse your noun instead of using a pronoun.
- it, they, them, their, this, that
- Pick specific verbs over vague ones. Reduce the usage of:
- be / is / are / am / was / were
- occur / happen
- there is / there are
- Keep list items parallel.
- Put conditional clauses before instructions, not after.
- Avoid unnecessary words:
- really, pretty much, quite a few, obviously, basically, simply, of course, clearly, just, everyone knows, very, a bit, a little, quite, too, though, sort of, kind of, rather
Grammar
thatvs.which:- use
thatfor defining (= non-optional) clauses (no comma) - use
whichfor non-defining (= optional) clauses (comma)
- use
- help (to) do:
tois optional- no
-ingon the infinitive
Typography
- Historically, typographical curly apostrophes (
’) are preferred. On the web, typewriter straight apostrophes (') are acceptable, too. - Use correct dashes:
- Hyphen (
-): Compound words (e.g. "sign-in", "cost-effective"). - En dash (
–): Ranges (e.g. "1985–2022", "Mon–Tue"). - Em dash (
—): Break between parts of a sentence. Stronger than a comma, weaker than a semicolon.
- Hyphen (
Work methods
Project management
- Effective teams need trust. Replacing trust with process is called bureaucracy.
- Start sprints on Wednesday to reduce the absence in sprint meetings due to days off and remote working.
- Use appropriate defect severities. Do not misuse them to express a (customer) prioritization.
- Severity 1 (Critical): System failure. No further processing is possible.
- Severity 2 (High): Unable to proceed with selected function or dependants.
- Severity 3 (Medium): Restricted function capability, however, processing can continue.
- Severity 4 (Low): Minor cosmetic deviance.
Remote work
- Go remote-first. Build your development team around a workflow that embraces the concepts of remote work, whether or not your employees are remote.
- Prefer asynchronous communication.
- Always use a camera in addition to audio during remote meetings.
Communication
- No well-actually: Do not correct someone about something that's not relevant to the conversation or tangential to what they're trying to say.
- No feigning surprise: Do not act surprised when someone doesn't know something.
- No backseat driving: Do not lob advice from across the room (or across the online chat) without joining or engaging in a conversation.
- Avoid oppressive language
- Don't just say "hello" in a chat. Don't ask to ask.
- Prefer number lists to bullets when listing questions.
Public speaking
- Plan for the worst-case scenario, e.g. your computer dying.
- Use a bright color theme on a beamer to improve readability (slides, console, editor/IDE).
- Have a (laser) pointer.
- Be prepared to zoom in your presentation
Win++/Win+-on Windows
- Prepare good verbal transitions between slides.
- Keep the things you say and the things you show in sync.
- Start with a "bang" to grab the audience attention.
- Explain why you have the authority to talk about your topic.
- Consider doing an audience poll to support your talk.
