This is (and possibly forever will be) a work in progress
- Meaningful choice of:
- Frontend code (javascript, typescript...)
- Frontend framework (Vue, React...)
- Backend code (node.js, java, php, Solidity, ...)
- Backend framework (express.js, springboot, laravel, Nuxt...)
- Testing suites
- Application type: SSG, SSR, SPA...
- Software architecture
- Database schema (if any)
- Deployment strategy (e.g. push code to master branch, release to staging and production from weekly release branches)
- Code base hosting service (gitlab, github...)
- Hosting / server provider (AWS, Heroku, DigitalOcean, Netlify, Vercel...)
- Domain vendor
- Useful:
- Write new code
- While doing so, write any comments that help understand why the code was written that way
- Write the tests that validate the use cases involved in the new code, in a per commit basis
- Debug: when finding bugs, fix them and write tests that catch these bugs
- Refactor the code if it needs refactor, or set a task to refactor it ASAP
- Have the code reviewed by someone else
- Write any necessary documentation, update the release notes for the project
- Do code reviews of someone else's code
- Decide initial content and basic layout:
- What pages
- What sections per page
- What content per section
- Create "design-less" layout / wireframe, based on standard web elements, do mobile first, then desktop
- Create html / jsx without styles
- Apply basic styles to create wireframe
- Create design (branding, styles, theme) >> style guide
- Apply theme and styles to complete design
- Release to production
- Optimize in terms of performance (80/20 principle)
- Sketch wireframe
- Write HTML in your choice framework (only semantic, no styles)
- Write CSS styles
- Use media queries to make component look good in different screen sizes
- https://github.com/thedaviddias/Front-End-Design-Checklist
- Refactoring-ui and my notes https://github.com/luismartinezs/web-design-ux-ui-cheatsheet
- Feature first design
- Design + code in small cycles
- Use predefined spacing, sizing, font, color, shadow...
- Design by hierarchy using color, weight, position, spacing, size, shape...
- User actions provide instant feedback
- A spinner is displayed while the server confirms an action, or result is displayed optimistically before server returns a response
- https://frontendchecklist.io/
- Use a skeleton CSS like https://cdnjs.com/libraries/skeleton
- API error handling: https://blog.restcase.com/rest-api-error-codes-101/
- Maintain a good folder structure:
- One folder per service
- One folder for reusable services, e.g. common/api/, common/component/
- Fractal folder structure for nested components
- Tracking cookies require user permission in form of a modal
- Identification cookies (to store form-submitted data) require the user to check a checkbox before submitting a form
window.onbeforeunload
hook prevents form data loss on accidentally closing the tab- Terms in different languages use the
lang
attribute - Dates use the
<time>
element
- https://github.com/thedaviddias/Front-End-Performance-Checklist
- Pass chrome audit
- Any DNS-hosted fonts use:
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
- Any registered event listeners are removed when the page is unloaded / destroyed
- Consider using a frontend caching mechanism, e.g. Data Fetching using Vue Hooks | Darren Jennings
- https://web.dev/pwa-checklist/
- Service workers: https://codelabs.developers.google.com/codelabs/offline/#0
- Manifest: https://developers.google.com/web/fundamentals/web-app-manifest/
- Requests use HTTPS
- E2e tests test main use cases
- Integration tests test connections between services
- Unit tests test complex functions
- When a bug is caught and fixed, a test that covers it is written
- Do not trust anyone, act as if Darth Vader is everywhere in the network
- Always sanitize and validate user input
- Do not use innerHTML, use createTextNode from input
- Use libraries like knex to communicate to a database, instead of direct SQL commands
- Production accounts should not be able to execute DDL, only DML
- Always store passwords as salted hashes
- Outsource auth workflow when possible
- Take care of outdated dependencies
- Be aware of attacks as soon as they happen, (winston, morgan...)
- Never transfer any secret through HTTP (i.e. no HTTPS): letsencrypt.org, cloudflare CDN
- Prevent XSS and XSRF: Use
Content-Security-Policy
header,secure
andHTTPOnly
headers for cookies - Do not use
eval()
- Do not use
document.write()
- Always put any secrets in
.env
files and have git ignore them - Secure http headers
- helmet package
- Run yor site here: https://securityheaders.com/
- Principle of least privilege
- Always have backups of any data or code
- Encrypt sensitive data in any transaction: bcrypt
- Login and register forms always give an ambiguous message in the same response time to prevent user enumeration.
- Sensitive data are never stored as such in a DB, it is stored as a salted hash (bcrypt)
- Any secrets required by the app are stored as environment variables in the server and never exposed in the remote code base or the client
- In development, a docker container or orchestrated set of docker containers launches all backend services with a single command
- Use a service that runs containers and takes care of managing servers and clusters automatically (e.g. AWS Fargate)
- Routing redirection points external traffic to a specific URL as needed, e.g.: HTTP to HTTPS, www domain to naked domain...
- Load balancers point traffic to specific targets inside a VPC or to different servers if traffic numbers are huge
- Services that only run occasionally or on seasonal bursts are handled by lambda functions
- A CDN caches and serves the website
- Source code is linted, formatted consistently and tested
- A precommit hook auto-formats the code and runs unit tests
- When code is pushed to the remote repo, e2e tests and integration tests are run automatically. If e2e tests fail, the push fails. resources: circleci
- If working in a team, before merging a feature branch into master, a peer reviews the code
- Development environment: automatic deployment from master whenever a new commit is pushed
- Staging environment: automatic deployment from release branch tag
- Production environment: manual deployment from release branch tag
- Smoke tests are set into place to be alerted if something goes wrong on production (e.g. Sentry)