Best practices and coding guidelines
A guide for building better applications.
Don't follow this guide blindly. 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.
Table of contents:
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 adblockers 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
. - Add
rel="noopener"
when usingtarget="_blank"
to improve performance and prevent security vulnerabilities. - Prefer
defer
overasync
when 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.ico
in the root document folder, containing at least 16×16 and 32×32 icons. - Consider using SVG favicons.
- Place a 180×180
apple-touch-icon.png
in 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
,selected
orchecked
. - 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-box
box-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:hover
to 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
key
orcode
instead ofcharCode
,keyCode
orwhich
. - Do not use the
keypress
event.
- 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
bind
or 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.
- Rethink your mental model regarding
useEffect
. - Use multiple
useEffect
calls 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.name
is 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
utils
package.
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
label
for all form inputs. Theplaceholder
attribute 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
tabindex
value 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 audit
findings 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.
- 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-password
to the change-passwords URL. - Provide screenshots in your web app manifest.
- Don't sort by average rating.
DevOps
- Avoid 2:00 and 3:00 am cron jobs
- Prefer the
~all
SPF mechanism instead of-all
or?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
v
is 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
that
vs.which
:- use
that
for defining (= non-optional) clauses (no comma) - use
which
for non-defining (= optional) clauses (comma)
- use
- help (to) do:
to
is optional- no
-ing
on 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.
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).
- 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.