Node.js Best Practices

Structure, secure, observe, and scale maintainable Node.js services.

Lesson content

๐ŸŽฏ Goal By the end of this lesson, you'll understand: What are Node.js Best Practices? Why are they important? Project Structure Coding Standards Error Handling Security Performance Logging Environment Variables Interview Questions What are Node.js Best Practices? Best Practices are recommended techniques that help you write: Clean Code Secure Code Fast Applications Maintainable Projects Scalable Applications Simple Definition: Best Practices are proven ways to write better Node.js applications. Why Do We Need Best Practices? Without best practices: Code becomes messy Bugs increase Security risks increase Difficult to maintain Poor performance Real-Life Example ๐Ÿ—๏ธ Imagine building a house. Without Rules Bricks Anywhere Windows Anywhere Doors Anywhere โ†“ Unsafe House With Rules Proper Design Strong Foundation Correct Wiring โ†“ Safe House The same applies to Node.js applications. 1. Organize Your Project Properly Bad Structure project/ โ”‚ โ”œโ”€โ”€ app.js โ”œโ”€โ”€ user.js โ”œโ”€โ”€ order.js โ”œโ”€โ”€ payment.js Good Structure project/ โ”‚ โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ config/ โ”‚ โ”œโ”€โ”€ controllers/ โ”‚ โ”œโ”€โ”€ routes/ โ”‚ โ”œโ”€โ”€ services/ โ”‚ โ”œโ”€โ”€ models/ โ”‚ โ”œโ”€โ”€ middleware/ โ”‚ โ”œโ”€โ”€ utils/ โ”‚ โ”œโ”€โ”€ validators/ โ”‚ โ””โ”€โ”€ app.js โ”‚ โ”œโ”€โ”€ package.json โ””โ”€โ”€ .env 2. Use Environment Variables Don't write secrets inside code. โŒ Bad const JWT_SECRET = "mysecret123" ; โœ… Good require ( "dotenv" ) . config(); const JWT_SECRET = process . env . JWT_SECRET; .env PORT=3000 JWT_SECRET=mysecret123 DB_HOST=localhost 3. Handle Errors Properly โŒ Bad app . get( "/" , ( req , res ) => { throw new Error ( "Server Error" ); }); โœ… Good app . get( "/" , ( req , res , next ) => { try { res . send( "Hello" ); } catch ( err ) { next ( err ); } }); Error Middleware app . use(( err , req , res , next ) => { res . status( 500 ) . json({ message: err . message }); }); 4. Validate User Input Never trust client input. โŒ Bad const age = req . body . age; โœ… Good if ( ! req . body . email) { return res . status( 400 ) . json({ message: "Email Required" }); } Popular libraries: Joi Zod express-validator 5. Use Async/Await โŒ Callback fs . readFile( "file.txt" , ( err , data ) => { }); โœ… Async/Await const data = await fs . promises . readFile( "file.txt" ); 6. Use Proper HTTP Status Codes res . status( 200 ) . json( data ); res . status( 201 ) . json( user ); res . status( 400 ) . json( error ); res . status( 401 ) . json( error ); res . status( 404 ) . json( error ); res . status( 500 ) . json( error ); 7. Use Middleware Instead of repeating code: authenticate ( req ); authorize ( req ); validate ( req ); Use middleware. app . get( "/profile" , authenticate , authorize ( "admin" ), profileController ); 8. Separate Business Logic โŒ Bad app . post( "/users" , ( req , res ) => { // Database logic // Validation // Email // Response }); โœ… Good app . post( "/users" , userController . createUser ); Controller exports . createUser = async ( req , res ) => { }; Service exports . createUser = async () => { }; 9. Use Logging Instead of: console . log(); Use logging libraries. Examples: Winston Pino Morgan (HTTP request logging) Example logger . info( "Server Started" ); 10. Secure Your Application Use: Helmet CORS Rate Limiting HTTPS Strong Password Hashing (bcrypt) Example const helmet = require ( "helmet" ); app . use( helmet ()); 11. Keep Dependencies Updated Update packages regularly. npm update Check vulnerabilities. npm audit Fix automatically where possible. npm audit fix 12. Use a Process Manager Don't run production apps using: node app.js Use: pm2 start app.js Benefits: Auto Restart Monitoring Log Management Zero-Downtime Reloads 13. Graceful Shutdown Close resources before exiting. process . on( "SIGTERM" , () => { console . log( "Shutting down..." ); server . close(() => { console . log( "Server Closed" ); }); }); 14. Avoid Blocking the Event Loop โŒ Bad const data = fs . readFileSync( "file.txt" ); โœ… Good const data = await fs . promises . readFile( "file.txt" ); 15. Write Tests Use testing frameworks like: Jest Mocha Vitest Example test ( "sum" , () => { expect ( 2 + 2 ) . toBe( 4 ); }); 16. Use Version Control Use Git. git init git add . git commit -m "Initial Commit" Benefits: Track changes Collaboration Rollback Branching Request Flow Client โ”‚ โ–ผ Middleware โ”‚ โ–ผ Validation โ”‚ โ–ผ Controller โ”‚ โ–ผ Service โ”‚ โ–ผ Database โ”‚ โ–ผ Response Real-Life Example ๐Ÿฆ Bank System Customer โ”‚ โ–ผ Security Check โ”‚ โ–ผ Document Verification โ”‚ โ–ผ Manager Approval โ”‚ โ–ผ Transaction Every step follows rules to keep the system safe and reliable. Interview Question Why should we use environment variables? Answer To keep sensitive information like API keys, database credentials, and JWT secrets out of the source code. Why should we avoid synchronous methods? Answer Because they block the Node.js event loop, reducing application performance. Why should business logic be separated? Answer To improve code readability, maintainability, testing, and reusability. Which process manager is commonly used in Node.js? Answer PM2 Name some security middleware. Answer Helmet CORS Rate Limiting Best Practices Checklist โœ… Practice Recommended Use .env โœ… Validate Input โœ… Use Async/Await โœ… Error Middleware โœ… Logging โœ… HTTPS โœ… Helmet โœ… CORS โœ… Rate Limiting โœ… PM2 โœ… Git โœ… Automated Tests โœ… Key Points โœ… Organize your project with a clear folder structure. โœ… Store secrets in environment variables. โœ… Validate all user input. โœ… Use async/await instead of deeply nested callbacks. โœ… Handle errors with centralized error middleware. โœ… Keep controllers thin and business logic in services. โœ… Use logging instead of relying only on console.log() . โœ… Secure your application with Helmet, CORS, HTTPS, and password hashing. โœ… Avoid blocking the event loop with synchronous operations. โœ… Use PM2 and Git in production projects. ๐Ÿง  Easy Formula Start Project โ”‚ โ–ผ Good Folder Structure โ”‚ โ–ผ Environment Variables โ”‚ โ–ผ Middleware โ”‚ โ–ผ Validation โ”‚ โ–ผ Controller โ”‚ โ–ผ Service โ”‚ โ–ผ Database โ”‚ โ–ผ Error Handling โ”‚ โ–ผ Logging โ”‚ โ–ผ Response .env = Secrets Middleware = Common Logic Controller = Handle Request Service = Business Logic Database = Store Data PM2 = Production Process Manager Remember: ๐Ÿ“ Organize your project ๐Ÿ”’ Keep secrets in .env โœ… Validate every request โšก Use async/await ๐Ÿ›ก๏ธ Secure your application ๐Ÿ“ Log important events ๐Ÿš€ Use PM2 in production ๐Ÿงช Write tests for reliable code