<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Nirjan&apos;s Coding &amp; Tech Blog</title><description>I write about building fast, secure and user-friendly apps on the web and cover different web technologies like HTML &amp; CSS, JavaScript, TypeScript, Svelte, React.js, Golang, Postgres &amp; SQLite.</description><link>https://nirjan.dev/</link><language>en-us</language><item><title>Big life updates, Joy of simplicity, Coding &amp; AI and a New job: 2025 review.</title><link>https://nirjan.dev/blog/2025-yearly-review/</link><guid isPermaLink="true">https://nirjan.dev/blog/2025-yearly-review/</guid><description>2025 really felt like multiple years rolled up into one. Things seem to be moving so fast but I still feel cautiously optimistic.</description><pubDate>Sun, 04 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Big life update&lt;/h2&gt;
&lt;p&gt;I made some major decisions in my personal life in 2025. I decided to get married and to move to Spain.&lt;/p&gt;
&lt;p&gt;I knew I wanted to move from Nepal at some point but I hadn&apos;t decided where to move. I&apos;m a classic over-thinker so I might&apos;ve spent way too long deciding on which country to move to but ultimately Spain had a nice balance of everything I wanted (a safe country with great weather and a good quality of life).&lt;/p&gt;
&lt;p&gt;I realize how fortunate I am to be able to make this move at all and I hope it will turn out well.&lt;/p&gt;
&lt;h2&gt;Joining Athlos&lt;/h2&gt;
&lt;p&gt;I joined &lt;a href=&quot;https://Athlos.gg/&quot;&gt;Athlos&lt;/a&gt; in February and spent the year working on the Athlos tournament platform. Athlos lets game studios seamlessly integrate a complete tournament platform into their games (includes both a dashboard to manage tournaments and an embedded frontend that players can use to compete in tournaments).&lt;/p&gt;
&lt;p&gt;It was interesting to work exclusively as a frontend developer again. Having worked as a fullstack developer for the previous 3 years, I realized I still prefer having full ownership over the products that I&apos;m building and being able to ship a full feature from scratch feels great but I enjoyed collaborating with other people again as well. I got to work with lots of talented backend developers at Athlos so it was great to learn from them. It was also fun to collaborate with another frontend developer and designer too.&lt;/p&gt;
&lt;p&gt;These were some of the most fun and rewarding things I got to work on with Athlos this year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introducing the team to Storybook for documenting our in-house component library and redesigning our theming token system using css variables. This enabled us to make our themes more customizable for each client.&lt;/li&gt;
&lt;li&gt;Launching a few key features requested by our clients like:
&lt;ul&gt;
&lt;li&gt;Supporting player created events (which lets studios invite players who can then use event templates and host their own tournament event).&lt;/li&gt;
&lt;li&gt;Adding a billing section to the dashboard so studios can easily see their user metrics and get their billing estimates.&lt;/li&gt;
&lt;li&gt;Creating a new standalone web app product where players can take part in Counter-Strike 2 tournaments (previously we only had a webview embed that clients could add to their mobile game). It was an interesting challenge to extract our core logic for the webview embed into a shared package so we could use a monorepo for different platforms (webview and standalone web app).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Refactoring our lobby queue system (so players can seamlessly join a game lobby, find matches and accept a match with realtime notifications for each step).&lt;/li&gt;
&lt;li&gt;Making improvements to our developer experience with:&lt;/li&gt;
&lt;li&gt;Automatic language translations with the Google Cloud Translate API (our webview embed project needs to support multiple languages).&lt;/li&gt;
&lt;li&gt;Adding some end to end tests with Playwright so we could make new changes to our dashboard and webview project with more confidence.&lt;/li&gt;
&lt;li&gt;Introduced product analytics and error tracking (with screen-recordings) using Posthog analytics.&lt;/li&gt;
&lt;li&gt;Used Cloudflare workers and Grafana to create a request log dashboard so we could have better insights into all our frontend requests.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Clickout consulting&lt;/h2&gt;
&lt;p&gt;In my free time, I took on some consulting work for Clickout Marketing as well. Clickout is a global multi channel marketing company with a focus on SEO and affiliate marketing.&lt;/p&gt;
&lt;p&gt;I worked as a freelancer for them and was tasked with building some internal tools to help them be more productive with their day to day operations. I also built some automation-workflows to automate a lot of tedious manual work they were doing previously.&lt;/p&gt;
&lt;p&gt;These are some of the things that I worked on for Clickout this year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introducing the team to n8n workflows and building out some core reusable sub-workflows (better error tracking, markdown converters, WordPress data extraction, etc) and some custom agentic workflows (SEO brief generation, position tracking report generation, etc). This helped automate a significant amount of boring manual work. It has been a huge success within the internal teams and now they&apos;re automating 96+ hours of work every day (with more automation-workflows to come in 2026).&lt;/li&gt;
&lt;li&gt;Created a custom internal web app for the marketing team. It lets them track their partner outreach more efficiently (automatically getting stats about potential partner sites and their contact information, syncing the outreach status to Monday CRM, finding new partners to reach out to based on the tracked keywords, etc). It also helps them track the SEO rankings for their internal sites automatically without checking multiple SEO tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;AI-assisted coding and joy of simplicity&lt;/h2&gt;
&lt;p&gt;2025 was also the first year where I (along with many other developers) actually started using AI tools in my day to day work. I have mixed feelings about the state of AI-assisted coding currently.&lt;/p&gt;
&lt;p&gt;It can be incredibly helpful at times when you have a clear idea of what needs to be done and you just need to write a bunch of boilerplate code. It can be magical to just use a few prompts and have a complete feature ready without the hours of tedious manual coding you would need previously.&lt;/p&gt;
&lt;p&gt;It has also enabled me to be more ambitious with the type of projects I take on. It feels like I have a pretty competent pair programming partner who I can consult with and talk through ideas about different types of projects (including the ones that I have very little experience with). I don&apos;t have to do countless hours of research before starting something that I&apos;m unfamiliar with. AI tools like Claude can be great to bounce different alternative ideas around with and figure out the best approach to take.&lt;/p&gt;
&lt;p&gt;But, sometimes it can be infuriating to work with AI. I appreciate the ability to quickly vibe-code interactive prototypes, they are a massive improvement over just regular Jira tickets or static designs and tell me a lot more about what the product needs to be like. However, trying to make a vibe-coded app into something that&apos;s robust, secure and performant still feels like too much work. In most cases you&apos;re probably better off just starting from scratch.&lt;/p&gt;
&lt;p&gt;I also don&apos;t get into the same type of flow when working with an AI agent because I have to wait for it to finish and then reviewing the massive amount of code it spits out (they sure do love to use a lot of code) can almost be a bigger bottleneck than just writing the code myself.&lt;/p&gt;
&lt;p&gt;So, I think there&apos;s still a lot of value in AI-assisted coding but you need to follow some best practices to get the most out of it and luckily those best practices tend to be the same ones you&apos;d use when improving your own code too. Some of the things that I&apos;ve found to be helpful are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Have a clearer idea of the actual problem you&apos;re trying to solve first. AI can help you write a pretty decent spec which you can use as a high level plan for yourself or have it try implementing some isolated parts of it.&lt;/li&gt;
&lt;li&gt;Have small focused commits. There&apos;s nothing worse than having to review a massive code change made by an Agent. Some of the newer models are capable of one-shotting incredible apps but just because they can doesn&apos;t mean you should let them do it. It&apos;s much better to have them work on smaller features or parts of a feature, review it and then move on to something else.&lt;/li&gt;
&lt;li&gt;Use as much deterministic tooling as possible. You can use AI to get a good summary of code changes but you should take it with a grain of salt. It&apos;s not a replacement for actually reading the code. Instead, to make sure the code is actually correct, use tried and tested tools that are deterministic like linters, type checkers, unit tests, end to end tests, etc.&lt;/li&gt;
&lt;li&gt;Introduce constraints whenever possible. Use things like an &lt;code&gt;agents.md&lt;/code&gt; file or add specific instructions in the spec to only allow the Agent to do certain things. Be clear with your tech stack and patterns you want to follow. This is the reason why I rarely start a project with AI, I often find it much more productive to establish a good foundation myself and once I run into repetitive tasks, I use AI to help me with that.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve also grown to appreciate simplicity a lot more because of AI-assisted coding. I know that we should always optimize for reading code more than writing code because you will be reading it much more often than writing it. But, in practice it can be hard to remember this and you end up trying to create abstractions and use dependencies that let you write code faster which often makes it harder to read and understand.&lt;/p&gt;
&lt;p&gt;This year I read the &lt;a href=&quot;https://lets-go.alexedwards.net/&quot;&gt;&lt;strong&gt;Let&apos;s go&lt;/strong&gt;&lt;/a&gt; and &lt;a href=&quot;https://lets-go-further.alexedwards.net/&quot;&gt;&lt;strong&gt;Let&apos;s go further&lt;/strong&gt;&lt;/a&gt; books by Alex Edwards and it made me appreciate the simplicity of golang and how great it can feel to write simple code that is easy to understand. This has the added benefit of making it easier for AI agents to understand your codebase without needing additional context about different abstractions or dependencies. So, in 2026 one of my goals is to write more simple code and think a lot more critically about the abstractions and dependencies I use.&lt;/p&gt;
&lt;h2&gt;Learning and projects&lt;/h2&gt;
&lt;p&gt;I finished a few different courses this year and tried to understand the tools and languages I use in a deeper way. Some of the courses I took were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.joyofreact.com/&quot;&gt;Joy of React&lt;/a&gt; by Josh W Comeau (a fantastic course on how React actually works)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lets-go.alexedwards.net/&quot;&gt;&lt;strong&gt;Let&apos;s go&lt;/strong&gt;&lt;/a&gt; and &lt;a href=&quot;https://lets-go-further.alexedwards.net/&quot;&gt;&lt;strong&gt;Let&apos;s go further&lt;/strong&gt;&lt;/a&gt; books by Alex Edwards (great books on the Go programming language and its standard library to build web servers)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.totaltypescript.com/books/total-typescript-essentials&quot;&gt;Total TypeScript Essentials&lt;/a&gt; by Matt Pocock (Matt is probably the go-to guy for TypeScript and his free TS course is fantastic and much more detailed than any other typescript essentials course)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://frontendmasters.com/courses/developer-productivity-v2/&quot;&gt;Dev Productivity&lt;/a&gt; and &lt;a href=&quot;https://frontendmasters.com/courses/blazingly-fast-js/introduction/&quot;&gt;Blazing fast JavaScript&lt;/a&gt; by The Primagen (The Primagen needs no introduction, his courses are fantastic and very detailed)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://frontendmasters.com/courses/sqlite/&quot;&gt;Complete Intro to SQLite&lt;/a&gt; by Brian Holt (SQLite can be a great tool for many different projects where you don&apos;t need a full blown database)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://frontendmasters.com/courses/frontend-system-design/&quot;&gt;Front-End System Design&lt;/a&gt; by Evgenii Ray (it was nice to go deeper on some of the common patterns and practices used in front-end development)&lt;/li&gt;
&lt;li&gt;Some &lt;a href=&quot;https://vueschool.io/&quot;&gt;Vueschool&lt;/a&gt; courses (like TDD with Vitest, Vue Component Design and Nuxt data fetching)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides this, I also took some time to learn Vim motions and moved from VSCode to Zed and started using zellij for my session management (small things like this probably don&apos;t make you a better developer, but they do make you more productive and make coding more fun). I also tried out the Symfony PHP framework and some Ruby on Rails but decided they weren&apos;t for me (going to stick with TypeScript and Golang for now).&lt;/p&gt;
&lt;p&gt;While it&apos;s important to keep learning, building projects is also important. They help you learn by doing and solidify your knowledge. I worked on these side projects in 2025:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nirjan-dev/servomon/&quot;&gt;&lt;em&gt;Servomon&lt;/em&gt;&lt;/a&gt;: A selfhostable homelab monitoring app built with Nuxt and Deno. The dashboard is built with Nuxt and communicates with a Deno client that runs on the server using websockets.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nirjan-dev/rosetide&quot;&gt;&lt;em&gt;Rosetide&lt;/em&gt;&lt;/a&gt;: A  privacy focused secure period tracking app. Stores all data locally and lets users track their periods and get an overview of their cycle and a prediction of their next period.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://evergreenplants.shop/&quot;&gt;&lt;em&gt;Evergreen Plants&lt;/em&gt;&lt;/a&gt;: An online store for the best plant nursery in Nepal (I&apos;m totally not biased because my girlfriend runs the nursery).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://remotedevjobs.net/&quot;&gt;&lt;em&gt;Remote Dev Jobs V2&lt;/em&gt;&lt;/a&gt;: Updated the job site that I run for remote developers to Nuxt 4 and Nuxt UI 4 and Drizzle (from Prisma).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Coding in 2026&lt;/h2&gt;
&lt;p&gt;2026 is shaping up to be another year filled with huge potential changes in the world of coding. There are lots of uncertainties but I feel like there&apos;s some exciting opportunities as well. The AI Genie is truly out of the bottle now and there&apos;s no going back, however we can choose how we use this tool (at the end of the day it&apos;s still just another tool in the toolbox).&lt;/p&gt;
&lt;p&gt;Personally, I want to focus on making my tech stack simpler (less abstractions, minimal dependencies and solid fundamentals). I&apos;m planning on using a set of core technologies which are tried and trusted and simple (Golang, SvelteJS, TypeScript, Postgres, Docker, Linux). I have a lot of interesting ideas that I want to turn into actual products.&lt;/p&gt;
&lt;p&gt;This year I want to focus on some more foundational concepts as well. I want to learn more about security, networking, databases and performance optimization.&lt;/p&gt;
&lt;p&gt;Apart from coding on my side projects, I also want to spend my free time doing some more writing and open source work. I realize that making any sort of money from writing about tech is pretty much impossible now but I want to write mainly as a way of clearing my head and a way of solidifying some of my opinions and ideas. I want to become a better coder too so for that I want to start reading a lot more open-source code. Being able to get some actual feedback from people with more experience than me is important too so I want to find a few open source projects that I love using and contribute back to them.&lt;/p&gt;
&lt;p&gt;I can&apos;t predict the future and have no control over how things are going to shake up in the tech world. I don&apos;t know how AI will change things in 2026 but I can control how I spend my time and what things I chose to focus on so hopefully it&apos;s going to be another year of working on some cool shit, learning some amazing things and growing as a person and a developer.&lt;/p&gt;
</content:encoded><category>review</category><author>Nirjan Khadka</author></item><item><title>2024, The year I pressed reset: Career change, Back to TypeScript (for now) and new habits</title><link>https://nirjan.dev/blog/2024-yearly-review/</link><guid isPermaLink="true">https://nirjan.dev/blog/2024-yearly-review/</guid><description>2024 was my reset year – transitioning from technical leadership to rediscovering my path as a developer. After exploring countless frameworks and leading major infrastructure projects, I learned that progress isn&apos;t about chasing every new technology. For 2025, I&apos;m choosing focus: TypeScript, PWAs, and solving problems that matter.</description><pubDate>Fri, 03 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sometimes the biggest transformations start with a series of small decisions. In 2024, I made three choices that completely reshaped my professional and personal life: stepping away from a senior technical role during tech&apos;s most uncertain year, embarking on a month-long journey to London, and committing to what seemed like a simple habit – daily journaling and time tracking.&lt;/p&gt;
&lt;p&gt;That last decision, surprisingly, had the most profound impact. Tracking every day of 2024 fundamentally shifted how I view my priorities and where I choose to invest my time. It revealed patterns I had never noticed and helped me make decisions I might have otherwise second-guessed.&lt;/p&gt;
&lt;p&gt;As I step into 2025, I want to reflect on these changes and share what I&apos;ve learned – both for my future self and for others who might be considering similar transitions.&lt;/p&gt;
&lt;h2&gt;Farewell to Gfinity&lt;/h2&gt;
&lt;p&gt;After nearly four years at Gfinity, where I progressed from a front-end developer to technical lead, I made the difficult decision to move on. While I&apos;m grateful for the experience and the excellent team I worked with, I felt it was time for a change as I was stagnating in my role and my vision no longer aligned with the senior leadership.&lt;/p&gt;
&lt;p&gt;During my final year, I was able to lead my team with the roll-out of several significant improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We achieved a 93% cost reduction by migrating our sites from GCP to Fly for Node.js hosting, maintaining performance and stability throughout the transition.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I developed a custom product tracking system using &lt;a href=&quot;https://crawlee.dev/&quot;&gt;Crawlee&lt;/a&gt;, GCP functions, and Node.js, resulting in an 80% reduction in scraping infrastructure costs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We implemented Hashtag labs advertising with a custom placement algorithm, moving from a revenue-sharing model to a fixed-cost structure that increased our advertising revenue.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I spearheaded the migration of StockInformer sites from legacy C# and VB.net to a modern Nuxt 3 codebase, leading to more frequent releases and improved uptime.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Led the roll-out the redesign of our shared design library that empowered our editorial team with enhanced curation controls, leading to a measurable increase in page views per session&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Launched and integrated a new property, TCGRocks.com, into our network, expanding our digital footprint&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Led the gradual migration of all network sites from Nuxt 2 to Nuxt 3, ensuring smooth transitions while maintaining site performance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Supported the migration of our Siege Laravel server and Golang microservices from bare metal to Fly.io, significantly improving system reliability and observability&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Learning and Growth&lt;/h2&gt;
&lt;p&gt;2024 was also a year of lots of learning. I deep-dived into modern Laravel, mastered Docker through &lt;a href=&quot;https://frontendmasters.com/courses/complete-intro-containers-v2/&quot;&gt;Brian Holt&apos;s container course&lt;/a&gt;, and explored &lt;a href=&quot;https://www.vuemastery.com/courses/vue3-deep-dive-with-evan-you/vue3-overview/&quot;&gt;Vue 3&apos;s internals with Evan You&lt;/a&gt;. I completed the &lt;a href=&quot;https://linuxjourney.com/&quot;&gt;Linux Journey curriculum&lt;/a&gt; and learned to build desktop apps with Electron and Tauri as well.&lt;/p&gt;
&lt;p&gt;A significant focus was on web technologies – I studied &lt;a href=&quot;https://mastery.games/serviceworkies/&quot;&gt;service workers&lt;/a&gt;, Progressive Web Apps (PWAs), WebSocket protocols, and WebRTC for real-time applications. I also picked up Phoenix LiveView and improved my development workflow by learning VIM motions and proper touch typing.&lt;/p&gt;
&lt;p&gt;Perhaps most importantly, I completed Yale&apos;s &lt;a href=&quot;https://www.coursera.org/learn/the-science-of-well-being&quot;&gt;&quot;The Science of Well-being&quot;&lt;/a&gt; course on Coursera, which had a profound impact on my perspective and daily life.&lt;/p&gt;
&lt;h2&gt;Side Projects and Community Engagement&lt;/h2&gt;
&lt;p&gt;Throughout the year, I worked on several side projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built &lt;a href=&quot;https://chromastery.vercel.app/&quot;&gt;Chromastery&lt;/a&gt;, a Tailwind color palette picker&lt;/li&gt;
&lt;li&gt;Developed &lt;a href=&quot;jobgettr.vercel.app/&quot;&gt;JobGettr&lt;/a&gt;, an app to tailor your resume for each job, powered by AI&lt;/li&gt;
&lt;li&gt;Migrated my personal site to Astro from Next.js&lt;/li&gt;
&lt;li&gt;Built a peer to peer video chat application called &lt;a href=&quot;https://litsi.fly.dev/&quot;&gt;Litsi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also began working part-time with &lt;a href=&quot;https://clickout.com/&quot;&gt;Clickout&lt;/a&gt; and became more active in the local tech community by attending meetups and conferences like &lt;a href=&quot;https://gdg.community.dev/events/details/google-gdg-kathmandu-presents-devfest-kathmandu-2024/&quot;&gt;DevFest Kathmandu&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Looking Forward to 2025&lt;/h2&gt;
&lt;p&gt;After a year of extensive exploration, I&apos;ve made some deliberate choices about my technical direction. These decisions aren&apos;t just about choosing technologies – they&apos;re about aligning my tools with my career goals and working style.&lt;/p&gt;
&lt;h3&gt;Why I&apos;m Going All-In on TypeScript&lt;/h3&gt;
&lt;p&gt;My journey in 2024 started with plans to focus on Laravel, but I&apos;ve come to realize that TypeScript better aligns with my current career goals. While Laravel remains an excellent choice for indie hackers building sustainable businesses, I&apos;ve discovered that my passion lies elsewhere – I thrive on exploring diverse problems and building various solutions rather than maintaining a single product.&lt;/p&gt;
&lt;p&gt;TypeScript offers several advantages that match my needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Robust tooling that supports rapid prototyping while maintaining code quality&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flexibility to evolve projects beyond the prototype phase through easy refactoring&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A vast ecosystem that enables building anything from web apps to desktop software&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strong job market with numerous opportunities at companies solving interesting problems&lt;/p&gt;
&lt;p&gt;I&apos;m also planning to expand my expertise into React and Go. While they might not be my first choice for personal projects, their position as industry standards makes them valuable additions to my toolkit. The goal isn&apos;t to master every technology, but to be proficient enough to contribute effectively in various professional contexts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shifting Focus: From Framework Exploration to Problem Solving&lt;/h3&gt;
&lt;p&gt;2024 was my year of framework exploration – I dove into everything from Laravel to Rails to Phoenix. While this broadened my perspective, it also limited my ability to ship projects. For 2025, I&apos;m taking a different approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Shipping More, Learning Through Building&lt;/strong&gt;: Instead of framework-hopping, I&apos;ll focus on launching more projects and solving real problems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exploring New Territories&lt;/strong&gt;: I&apos;m particularly excited about:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;The local-first movement and its potential for creating resilient applications&lt;/li&gt;
&lt;li&gt;Real-time technologies and their applications in modern web development 3. &lt;strong&gt;Embracing Progressive Web Apps&lt;/strong&gt;: I&apos;m making a conscious decision to step away from native app development. While native apps have their place, the constantly changing app store policies and restrictions have become more burden than benefit. The web&apos;s openness, ease of deployment, and maintenance advantages make PWAs an attractive alternative for most use cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pragmatic AI Integration&lt;/h3&gt;
&lt;p&gt;While AI generates plenty of hype, I&apos;m taking a practical approach to incorporating it into my workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Selective Usage&lt;/strong&gt;: I&apos;ve actually disabled AI code completion as I found it was hindering rather than helping my learning process.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Strategic Implementation&lt;/strong&gt;: Instead, I&apos;m leveraging AI tools as thinking partners for higher-level planning and architecture discussions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focus on Productivity&lt;/strong&gt;: The goal is to use AI where it genuinely enhances productivity without becoming a crutch or distraction.&lt;/p&gt;
&lt;p&gt;This approach to AI reflects my broader technical philosophy for 2025: being deliberate about tool choices, focusing on solving real problems, and maintaining a balance between exploration and productivity.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m refining my focus to be more intentional and impactful and limiting it to the following areas:&lt;/p&gt;
&lt;h3&gt;Technical Focus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mastering fundamentals: TypeScript, JavaScript, CSS, SQL, C, computer systems, Golang, and React&lt;/li&gt;
&lt;li&gt;Deepening my expertise in Nuxt&lt;/li&gt;
&lt;li&gt;Exploring both real-time and local-first applications&lt;/li&gt;
&lt;li&gt;Expanding into PWA development as an alternative to traditional app stores&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Professional Growth&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Contributing to open source projects&lt;/li&gt;
&lt;li&gt;Studying more existing codebases&lt;/li&gt;
&lt;li&gt;Exploring cybersecurity&lt;/li&gt;
&lt;li&gt;Integrating AI tools into my workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Personal Development&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Adopting a more focused learning approach instead of trying to keep up with every new technology&lt;/li&gt;
&lt;li&gt;Emphasizing depth over breadth&lt;/li&gt;
&lt;li&gt;Creating and launching prototypes more quickly&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;m looking for my next long-term role – somewhere I can grow and contribute for at least five years. My favorite part of being with Gfinity was being able to improve the company, team and codebase for an extended period of time. So, even though job hopping might be better financially for me, I would prefer to find another long term company to work for.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My goal is to focus on strong fundamentals while solving diverse problems with a consistent tech stack, rather than constantly switching between technologies.&lt;/p&gt;
&lt;p&gt;The tech industry continues to evolve rapidly, but I&apos;m excited to take a more measured, focused approach to my career growth in 2025 and beyond.&lt;/p&gt;
</content:encoded><category>review</category><author>Nirjan Khadka</author></item><item><title>Migrating my site from Next.js to Astro, Picking simplicity over complexity</title><link>https://nirjan.dev/blog/migrating-my-site-from-next-to-astro/</link><guid isPermaLink="true">https://nirjan.dev/blog/migrating-my-site-from-next-to-astro/</guid><description>After a few years of using Next.js for my personal site, I finally decided to rebuild it and migrate to Astro. In this post, I&apos;ll cover how my site was previously built, why I picked Astro and my experience with the Next.js to Astro migration.</description><pubDate>Fri, 06 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The old tech stack with Next.js and Sanity&lt;/h2&gt;
&lt;p&gt;Over the years, I&apos;ve migrated my sites to a few different frameworks. It all started with a Gatsby site, then I moved it to a Svelte static site generator called &lt;a href=&quot;https://github.com/Elderjs/elderjs&quot;&gt;Elder.js&lt;/a&gt; (which actually implemented the &lt;a href=&quot;https://www.patterns.dev/vanilla/islands-architecture/&quot;&gt;islands architecture&lt;/a&gt; before Astro), then finally to Next.js. I&apos;ve also migrated my content from using markdown to &lt;a href=&quot;https://www.storyblok.com/&quot;&gt;storyblok&lt;/a&gt; CMS and then to &lt;a href=&quot;https://www.sanity.io/&quot;&gt;Sanity CMS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If I&apos;m being honest, I haven&apos;t enjoyed working with Next.js that much. I mainly decided to use &lt;a href=&quot;https://nextjs.org&quot;&gt;Next.js&lt;/a&gt; for my site because it&apos;s by far the most popular meta-framework and uses &lt;a href=&quot;https://react.dev/&quot;&gt;React&lt;/a&gt; which is the most popular frontend framework. So, I thought If I used it for my personal site, I would be a better react developer and it would give me more opportunities professionally. But Ironically, I ended up joining a company that uses &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; and &lt;a href=&quot;https://nuxt.com/&quot;&gt;Nuxt.js&lt;/a&gt; and I&apos;ve been working with that tech stack for the last 4 years 🤷‍♂️.&lt;/p&gt;
&lt;p&gt;I don&apos;t necessarily hate React and I don&apos;t mind working in a React codebase but there are a lot more simpler alternatives. As I get more experienced, I&apos;m appreciating simplicity more and more and leaning towards the simplest way to solve problems.&lt;/p&gt;
&lt;p&gt;So, as a part of rebuilding my site, I wanted to simplify my tech stack as much as possible. That meant picking a framework like Astro which has good support for templating without needing to use any other frontend frameworks (unless I want to) and moving back to using good old markdown instead of a CMS.&lt;/p&gt;
&lt;p&gt;I also decided to get rid of my monorepo setup with &lt;a href=&quot;https://turbo.build/repo/docs&quot;&gt;turborepo&lt;/a&gt; which was definitely overkill for my personal site. I don&apos;t have any complicated linting rules or pre-commit hooks or auto-formatting either. You can still find the &lt;a href=&quot;https://github.com/nirjan-dev/nirjan.dev-next.js-version&quot;&gt;Next.js version&lt;/a&gt; and &lt;a href=&quot;https://github.com/nirjan-dev/nirjan.dev-elderjs&quot;&gt;the Elder.js version&lt;/a&gt; of the site on my Github.&lt;/p&gt;
&lt;h2&gt;Why Astro?&lt;/h2&gt;
&lt;p&gt;Since the main goal of rebuilding my site was to make it simpler, Astro was a great fit for that. I also considered Nuxt.js which has a better developer experience but is probably overkill for a simple content focused site like mine.&lt;/p&gt;
&lt;p&gt;I wanted to move my content to markdown again too because I want to have complete control over my content, store it in a format that is extremely portable (in case I want to migrate to something else) and it also makes writing and editing simpler. Astro just happens to have great support for markdown with it&apos;s &lt;a href=&quot;https://docs.astro.build/en/guides/content-collections/&quot;&gt;content collections&lt;/a&gt; feature that lets you create a schema for markdown and query it like structured content.&lt;/p&gt;
&lt;p&gt;Another selling point of Astro was the Island&apos;s architecture where everything is just HTML but I can have islands of interactive components on any part of the page. I really think this is the best way to build modern sites and even most web apps.&lt;/p&gt;
&lt;p&gt;The browser is great at rendering HTML so we should just shift towards that instead of trying to render everything with JavaScript. Even with Server Side Rendering, I think sites that hydrate and turn into client-rendered sites (most meta-frameworks like Next.js, Svelte, Nuxt, etc) are more brittle and less performant.&lt;/p&gt;
&lt;p&gt;I&apos;ve worked on a lot of content heavy sites with a framework that does this (Nuxt.js) and I definitely want to avoid going back to fully hydrated sites like that and deal with all the extra issues from hydration.&lt;/p&gt;
&lt;p&gt;Moving towards sites that are just HTML with smaller isolated interactive components just makes the most sense to me. It let&apos;s us actually use the underlying web platform which is a lot more stable than most frameworks and is also way more performant and accessible.&lt;/p&gt;
&lt;p&gt;We also have a lot more lightweight alternatives to frontend frameworks, like HTMX, Alpine or just using web components to handle client-side interactivity. My thoughts on this might change as I build more projects with these technologies but for now I&apos;m happy to embrace simplicity over the complexity of modern frontend frameworks.&lt;/p&gt;
&lt;h2&gt;What I liked about astro&lt;/h2&gt;
&lt;p&gt;There&apos;s a lot of things to like about Astro. I&apos;ve already mentioned the simplicity of Astro sites (they&apos;re mostly just HTML, CSS and some JavaScript if needed). But, the developer experience is also not that bad. It&apos;s basically just a framework that lets you create templates and organize them neatly into smaller components. All the Astro components are turned into regular HTML during the build process.&lt;/p&gt;
&lt;p&gt;It also has a lot of useful features to improve the performance, accessibility and SEO of your sites. It has a built-in image component that can help you optimize your images. It automatically does syntax highlighting for code blocks in your markdown which you can customize too.&lt;/p&gt;
&lt;p&gt;There are first-party integrations for creating sitemaps and RSS feeds to improve your SEO. It includes a toolbar during development that can detect some accessibility and performance issues and flag it to you. It does CSS scoping for you automatically and has an official tailwind integration.&lt;/p&gt;
&lt;p&gt;The best selling point for Astro for a lot of people might actually be the support for multiple frameworks. It has official integrations for React, Preact, Svelte, Vue, Solid, Alpine and Lit. You can also just use a little vanilla JavaScript to add interactive Astro components too. It has some support for Server Side Rendering and Server APIs but I haven&apos;t used that part of it so far.&lt;/p&gt;
&lt;p&gt;It was a pretty good experience building with Astro and I really like how much they prioritize simplicity, performance, accessibility and using the web platform. I will most likely continue building a lot of my upcoming projects using Astro.&lt;/p&gt;
&lt;h2&gt;What can astro improve&lt;/h2&gt;
&lt;p&gt;I still think there are a few things that could be improved in Astro. Having come from the Nuxt.js ecosystem I might be a bit spoiled when it comes to enjoying a good developer experience. Astro is not the worst when it comes to developer experience (looking at you Next.js 👀) but it is nowhere near to the level of seamless integration that you get with the Nuxt.js devtools.&lt;/p&gt;
&lt;p&gt;Astro has made a good start with their toolbar to detect accessibility and performance issues but I would love it if they added some features from the Nuxt devtools like the built-in routes and API explorer, bundling and compilation visualizations, open graph image previews, component inspectors and being able to browse and install integrations directly from the devtools.&lt;/p&gt;
&lt;p&gt;I didn&apos;t use the server-side features of Astro in this project but looking at the documentation they seem to be missing a few things that the nitro server (which Nuxt.js uses) already supports. So, it would be great to see some support for things like Tasks, Cron jobs, built-in ORM (besides just Astro DB), caching and KV storage. The 3rd-party integrations can also be a bit hit and miss but that should start improving as more people start adopting Astro.&lt;/p&gt;
&lt;h2&gt;Result of migrating from Next.js to Astro&lt;/h2&gt;
&lt;p&gt;Overall, I&apos;m really happy with the move from Next.js to Astro and I look forward to working more with Astro on future projects. Here are the main things I learned by migrating my blog from Next.js to Astro
- A framework that lets you incrementally add complexity and start from the simplest possible way of doing things feels great to use
- Sites built with Astro will most likely always be better in terms of performance, accessibility and SEO than other meta-frameworks that need to do a full page hydration
- You can use technologies that are closer to the web platform when using Astro compared to other frameworks. You can more easily adopt things like web components, smaller bits of vanilla JS logic, plain CSS HTML features. Of course, you can still use them with other frameworks but that&apos;s generally not the most common practice in those ecosystems.
- Modern HTML and CSS has come a long way and is really good for common interactions. Features like the popover API, HTML Dialogs, HTML details and summary, CSS scroll transitions and the View transition API are enough to build a lot of rich modern client-side interactions without using additional JavaScript.
- Astro might be the best solution for now if you value simplicity, performance and accessibility for your projects and want to stay in the JavaScript/Typescript ecosystem.
- I still think there are some trade-offs to consider when using Astro, especially for highly dynamic apps or sites that require lots of server-side processing but in most cases Astro makes a lot of sense.
- If I had to construct a Frankenstein&apos;s monster of a stack to fit all web projects it would probably have Astro&apos;s island&apos;s architecture, Nuxt&apos;s developer tooling, Laravel&apos;s first party packages, Go&apos;s simplicity and speed and Elixir&apos;s easy concurrency and scaling features but since I can&apos;t make something like that (yet), Astro&apos;s the framework to beat for now.
- Astro sites are blazingly fast 🚀&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./homepage.png&quot; alt=&quot;Perfect Lighthouse scores for my homepage built with Astro&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./blogpage.png&quot; alt=&quot;Perfect Lighthouse scores for my blog page built with Astro&quot; /&gt;&lt;/p&gt;
</content:encoded><category>migration</category><category>javascript</category><author>Nirjan Khadka</author></item><item><title>The best tech stack for 2024, self-hosting and 3 years at Gfinity | 2023 review</title><link>https://nirjan.dev/blog/the-best-tech-stack-for-2024-self-hosting-and-3-years-at-gfinity-2023-review/</link><guid isPermaLink="true">https://nirjan.dev/blog/the-best-tech-stack-for-2024-self-hosting-and-3-years-at-gfinity-2023-review/</guid><description>It’s that time of the year again, folks, time for another yearly recap. It feels like each year the tech industry is getting crazier, and this year has been especially crazy. While the AI drama is still going strong, I’m still cautiously optimistic about being a developer in 2024.</description><pubDate>Wed, 03 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You can also skip to the end to see what I think is the &lt;a href=&quot;https://nirjan.dev/blog/the-best-tech-stack-for-2024-self-hosting-and-3-years-at-gfinity-2023-review#plans-for-2024-and-the-perfect-tech-stack&quot;&gt;best tech stack for most developers in 2024.&lt;/a&gt; You can also checkout my previous yearly recaps for &lt;a href=&quot;https://nirjan.dev/blog/first-remote-job-leading-a-team-learning-seo-or-2021-review-from-a-web-developer&quot;&gt;2021&lt;/a&gt; and &lt;a href=&quot;https://nirjan.dev/blog/moving-to-a-tech-lead-role-working-on-more-side-projects-learning-sveltekit-and-c-sharp-2022-review&quot;&gt;2022&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;3 years at Gfinity and first year as a Tech Lead&lt;/h2&gt;
&lt;p&gt;I’ve officially spent 3 years working at &lt;a href=&quot;https://www.gfinityplc.com/&quot;&gt;Gfinity PLC&lt;/a&gt; now. I also finished my first full year as the technical lead for my team. This year was definitely a mixed-bag as we had lots of changes in the company and had to say goodbye to a lot of talented developers. But, We also had new team-members who have absolutely killed it since joining. Being able to have a big say in the hiring process has allowed me to be more selective when picking new hires. We also managed to accomplish a lot this year, with the following achievements being the highlights for me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Migrated to a new ad-tech partner to increase our revenue per session and better per page revenue breakdowns.&lt;/li&gt;
&lt;li&gt;Rolled out a lot of performance improvements which led to all the sites passing the Core Web Vitals assessment. Our sites also load in less than 2 seconds on average now.&lt;/li&gt;
&lt;li&gt;Migrated from Nuxt 2 to Nuxt 3 and from Vue 2 to Vue 3.&lt;/li&gt;
&lt;li&gt;Launched &lt;a href=&quot;https://starfieldportal.com/&quot;&gt;Starfield Portal&lt;/a&gt; which ended the year with 1.5 million page views in just 5 months after launch.&lt;/li&gt;
&lt;li&gt;Launched game databases for &lt;a href=&quot;https://starfieldportal.com/db&quot;&gt;Starfield&lt;/a&gt; and &lt;a href=&quot;https://www.gfinityesports.com/db/mw3/&quot;&gt;Call of Duty: Modern Warfare 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Deployed our custom content analytics dashboard with Nuxt 3 and a site health monitoring dashboard with Grafana.&lt;/li&gt;
&lt;li&gt;Improved our deployment process by adding support for feature flags and A/B testing.&lt;/li&gt;
&lt;li&gt;CMS workflow improvements including a mass link replacement tool, customizable automatic internal linking, built-in integration for freelancer payments and a draft and review workflow.&lt;/li&gt;
&lt;li&gt;Redesigned the navigation experience and added support for easier homepage content curation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The recent developments with AI and the changes in the ad tech market are definitely big challenges for publishers like us. But, we’re confident that our plans for growing our community, increasing engagement and augmenting our content production with custom AI tools will help us grow bigger than ever.&lt;/p&gt;
&lt;h2&gt;Learning new tech, two new projects and a home server&lt;/h2&gt;
&lt;p&gt;It has also been a busy year for my personal projects as well. I launched two new side projects this year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://remotedevjobs.net/&quot;&gt;Remote Dev Jobs&lt;/a&gt;: A job site focused on helping developers get remote tech jobs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.nirjan.smartspend&quot;&gt;Smart Spend&lt;/a&gt;: An android app to help you plan your expenses and be more mindful of your spending habits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I didn’t get to add all the features that I wanted to for these projects, but I’m glad that I actually shipped them. I definitely want to push out improvements to them in the next year and market them better.&lt;/p&gt;
&lt;p&gt;It was surprising to learn that I published 6 blog posts this year (I know it’s not that much but I only published 3 last year). I also started to use an old laptop as a home server. I mostly use it to manage my media library, run a self-hosted alternative to google photos, run self-hosted versions of LLM chatbots and run automated backups. Sometimes it can be frustrating to maintain and fix issues but self-hosting different services locally has helped me improve my knowledge of docker and it’s also just fun to try out new things on your own local server.&lt;/p&gt;
&lt;p&gt;I spent a lot of time learning new technologies as well in 2023. These are the main things that I learn this year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finished a &lt;a href=&quot;https://masteringnuxt.com/&quot;&gt;masterclass in Nuxt 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Did a course on &lt;a href=&quot;https://frontendmasters.com/courses/deep-javascript-v3/&quot;&gt;Deep JavaScript foundations&lt;/a&gt; and &lt;a href=&quot;https://frontendmasters.com/courses/javascript-new-hard-parts/&quot;&gt;Async programming in JavaScript&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learnt &lt;a href=&quot;https://www.youtube.com/watch?v=un6ZyFkqFKo&quot;&gt;Golang for backend development&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learnt a little bit of &lt;a href=&quot;https://elixir-lang.org/&quot;&gt;Elixir&lt;/a&gt; and the &lt;a href=&quot;https://hexdocs.pm/phoenix/overview.html&quot;&gt;Phoenix framework&lt;/a&gt;. Elixir might be my favorite new technology that I discovered in 2023.&lt;/li&gt;
&lt;li&gt;Did a few courses on &lt;a href=&quot;https://js.langchain.com/docs/get_started/introduction&quot;&gt;Langchain.js&lt;/a&gt; and &lt;a href=&quot;https://www.deeplearning.ai/short-courses/chatgpt-prompt-engineering-for-developers/&quot;&gt;Prompt Engineering&lt;/a&gt;. Looking forward to integrating this more into the projects that I built in 2024.&lt;/li&gt;
&lt;li&gt;Took a look at quasar again for building mobile apps&lt;/li&gt;
&lt;li&gt;Discovered &lt;a href=&quot;https://n8n.io/&quot;&gt;n8n&lt;/a&gt; and wrote a few automated workflows using it.&lt;/li&gt;
&lt;li&gt;Learnt more about how docker containers work.&lt;/li&gt;
&lt;li&gt;Used &lt;a href=&quot;https://supabase.com/&quot;&gt;Supabase&lt;/a&gt; as the backend for a few projects.&lt;/li&gt;
&lt;li&gt;Started using &lt;a href=&quot;https://www.prisma.io/&quot;&gt;Prisma&lt;/a&gt; and &lt;a href=&quot;https://orm.drizzle.team/&quot;&gt;Drizzle&lt;/a&gt; for my typescript projects. Prisma has the better docs and a bigger community but I prefer the drizzle syntax a lot more.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Plans for 2024 and the perfect tech stack&lt;/h2&gt;
&lt;p&gt;I spent a lot of time exploring new tech in 2023 but for 2024 I want to focus on getting better with those technologies and launching more projects. So, without further ado, I want to share the perfect tech stack (for most developers) in 2024.&lt;/p&gt;
&lt;h3&gt;And the best tech stack is…&lt;/h3&gt;
&lt;p&gt;It’s Laravel. I know a lot of people who hate PHP might disagree but I don’t think there is a better option than Laravel for building web-apps as a solo developer.&lt;/p&gt;
&lt;p&gt;I spent a lot of time comparing different frameworks like Ruby on Rails, Nuxt.js, Next.js, Sveltekit, ASP Dontnet, Golang and HTMX, Phoenix, etc but nothing came close to Laravel.&lt;/p&gt;
&lt;p&gt;When you’re building something quick and you don’t have the luxury of having millions of users, nothing beats Laravel with it’s simplicity, extensive documentation and fantastic ecosystem.&lt;/p&gt;
&lt;p&gt;I would love to use something like Typescript, Go or Elixir for my main language but they just don’t have a framework as mature as Laravel right now. I will still be using Vue and Nuxt for the UI layer because I don’t believe livewire can support building the highly interactive and responsive UIs that I want in my projects. I would also love to build some smaller services with Golang and explore data science and machine learning with Elixir. So for 2024, I&apos;m planning to use this tech stack for my projects&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backend APIs with &lt;a href=&quot;https://laravel.com/&quot;&gt;Laravel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends&quot;&gt;BFF&lt;/a&gt; API with &lt;a href=&quot;https://nuxt.com/&quot;&gt;Nuxt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; for the frontend&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://go.dev/&quot;&gt;Golang&lt;/a&gt; for performance critical APIs and tooling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elixir-lang.org/&quot;&gt;Elixir&lt;/a&gt; for data science and machine learning&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; and &lt;a href=&quot;https://primevue.org/&quot;&gt;PrimeVue&lt;/a&gt; for styling and UI components&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/&quot;&gt;Postgres&lt;/a&gt; as my database&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt; for frontend hosting&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/&quot;&gt;Fly&lt;/a&gt; for backend hosting&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://capacitorjs.com/&quot;&gt;Capacitor&lt;/a&gt; for mobile apps (with ionic or quasar)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.electronjs.org/&quot;&gt;Electron&lt;/a&gt; for desktop apps (tauri does look interesting too but no sure about rust)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I still have some doubts about my tech choices, mainly how context switching between multiple languages will affect my productivity but I think the trade-offs are worth it.&lt;/p&gt;
&lt;p&gt;I also want to mention how being more reflective about my goals has helped me this year. I’ve started to track my time with &lt;a href=&quot;https://toggl.com/&quot;&gt;toggl&lt;/a&gt; and do a weekly, monthly and quarterly review in &lt;a href=&quot;https://www.notion.so/&quot;&gt;notion&lt;/a&gt;. This has helped me track my progress more consistently while being flexible enough to change my goals when needed so I will definitely continue using this practice and would recommend it for anyone struggling to track their goals.&lt;/p&gt;
&lt;p&gt;To sum up, I will be focusing on on the following things in 2024:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launch more projects&lt;/li&gt;
&lt;li&gt;Get proficient with my tech stack&lt;/li&gt;
&lt;li&gt;Connect with more developers&lt;/li&gt;
&lt;li&gt;Get better at marketing&lt;/li&gt;
&lt;li&gt;Publish more blog post&lt;/li&gt;
&lt;li&gt;Contribute regularly to open source&lt;/li&gt;
&lt;li&gt;Redesigning my personal site&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>review</category><author>Nirjan Khadka</author></item><item><title>How to debug a Node.js Server</title><link>https://nirjan.dev/blog/how-to-debug-a-node-js-server/</link><guid isPermaLink="true">https://nirjan.dev/blog/how-to-debug-a-node-js-server/</guid><description>Using the debugger to go through your code line by line and see your variable values can save you lots of time. In front-end JavaScript, you can add a debugger statement to trigger the debugger. But how can you use the debugger on the server-side with node.js? Here’s a quick guide on how you can debug a node.js server. I will go through the steps to debug it in the terminal, with the chrome DevTools and with VS Code.</description><pubDate>Mon, 18 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You can grab the &lt;a href=&quot;https://github.com/nirjan-dev/debugging-node-server&quot;&gt;final demo app&lt;/a&gt; from my github profile.&lt;/p&gt;
&lt;h2&gt;How to use the node.js debugger&lt;/h2&gt;
&lt;p&gt;Node includes a built-in debugger that you can use on the command line. You can do most of the debugging actions that you normally do in the chrome DevTools or the VS Code debugger directly from the command line. Let’s create a very basic node HTTP server to try it out.&lt;/p&gt;
&lt;h3&gt;How to set up a basic node.js server&lt;/h3&gt;
&lt;p&gt;I’m using the following tools to setup the HTTP server in node.js:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NPM v8.19.2 (you don’t actually need it, you can just run the commands through node)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nodejs.org/en&quot;&gt;Node&lt;/a&gt; v20.10.0&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can follow these steps to get the server running&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initialize the node project with &lt;code&gt;npm init&lt;/code&gt; (you can use the default options for everything)&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;index.mjs&lt;/strong&gt; file and paste in the following&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    import http from &quot;node:http&quot;;
    const PORT = 3000;
    const HOST_NAME = &quot;localhost&quot;;
    
    async function fetchData() {
      return new Promise((resolve, reject) =&amp;gt; {
        setTimeout(() =&amp;gt; {
          resolve(&quot;Hello World&quot;);
        }, 3000);
      });
    }
    
    const server = http.createServer(async (req, res) =&amp;gt; {
      if (req.url === &quot;/&quot;) {
        const someDataFromDatabase = await fetchData();
        res.end(someDataFromDatabase);
      }
    });
    
    server.listen(PORT, HOST_NAME, () =&amp;gt; {
      console.log(`Server running at http://${HOST_NAME}:${PORT}/`);
    });
    
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Here’s a brief overview of the code
&lt;ul&gt;
&lt;li&gt;we import the http module from node&lt;/li&gt;
&lt;li&gt;we create a fetchData function which simulates getting data from somewhere else&lt;/li&gt;
&lt;li&gt;we create the server with a handler that’s setup to handle only the root endpoint&lt;/li&gt;
&lt;li&gt;we setup the server to listen to port 3000 on localhost&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can now add this to the &lt;strong&gt;scripts&lt;/strong&gt; section of the package.json file to setup a start command&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    &quot;start&quot;: &quot;node index.mjs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Then, run the command through npm&lt;/p&gt;
&lt;p&gt;npm start&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;when you visit &lt;strong&gt;localhost:3000&lt;/strong&gt; you should see hello world after 3 seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to start the node.js debugger&lt;/h3&gt;
&lt;p&gt;To start the node debugger, you have to add the inspect argument to your node command. So, you can add a &lt;code&gt;start:debug&lt;/code&gt; command to the package.json script section like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;start:debug&quot;: &quot;node inspect index.mjs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you run npm run start:debug then the debugger will pause on the first line of the file. To pause it on the debugger statement, you need to set the &lt;strong&gt;NODE_INSPECT_RESUME_ON_START&lt;/strong&gt; variable to 1.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;start:debug&quot;: &quot;NODE_INSPECT_RESUME_ON_START=1 node inspect index.mjs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let’s update out code to add a few debugger statements.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    import http from &quot;node:http&quot;;
    const PORT = 3000;
    const HOST_NAME = &quot;localhost&quot;;
    
    async function fetchData() {
      return new Promise((resolve, reject) =&amp;gt; {
        setTimeout(() =&amp;gt; {
          resolve(&quot;Hello World&quot;);
        }, 3000);
      });
    }
    
    const server = http.createServer(async (req, res) =&amp;gt; {
      if (req.url === &quot;/&quot;) {
        debugger;
        const someDataFromDatabase = await fetchData();
        debugger;
        res.end(someDataFromDatabase);
      }
    });
    
    server.listen(PORT, HOST_NAME, () =&amp;gt; {
      debugger;
      console.log(`Server running at http://${HOST_NAME}:${PORT}/`);
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you run the start:debug command again, you&apos;ll see it pause after the server starts listening on the port.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ❯ npm run start:debug
    
    &amp;gt; debugging-node-server@1.0.0 start:debug
    &amp;gt; NODE_INSPECT_RESUME_ON_START=1 node inspect index.mjs
    
    &amp;lt; Debugger listening on ws://127.0.0.1:9229/69001291-bc1e-4f0a-af8a-685cb2e7c74b
    &amp;lt; For help, see: https://nodejs.org/en/docs/inspector
    &amp;lt; 
    connecting to 127.0.0.1:9229 ... ok
    &amp;lt; Debugger attached.
    &amp;lt; 
    break in index.mjs:23
     21 
     22 server.listen(PORT, HOST_NAME, () =&amp;gt; {
    &amp;gt;23   debugger;
     24   console.log(`Server running at http://${HOST_NAME}:${PORT}/`);
     25 });
    debug&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use the &lt;strong&gt;help&lt;/strong&gt; command to see all the commands that you can use with this CLI debugger. The most useful ones will be &lt;strong&gt;c&lt;/strong&gt; to continue and &lt;strong&gt;repl&lt;/strong&gt; to go into the repl mode. Inside the repl mode, you can check the values of the variables in your program. Try to get to the last debugger statement and go into the repl mode to check the value of &lt;strong&gt;someDataFromDatabase&lt;/strong&gt;. You just have to type the variable name and press enter in the repl mode to see it’s value. To actually reach that debugger line, you’ll also need to trigger the handler by visiting &lt;strong&gt;localhost:3000&lt;/strong&gt; in your browser.&lt;/p&gt;
&lt;p&gt;You can checkout &lt;a href=&quot;https://nodejs.org/docs/latest-v20.x/api/debugger.html&quot;&gt;the full debugger docs on the node documentation&lt;/a&gt; to see what else you can do with it.&lt;/p&gt;
&lt;h2&gt;How to debug node.js using the chrome DevTools&lt;/h2&gt;
&lt;p&gt;If you’re already used to the chrome DevTools debugger, then you can also debug your node apps using that.&lt;/p&gt;
&lt;p&gt;To setup debugging in chrome, you need to use the &lt;strong&gt;--inspect&lt;/strong&gt; flag. Let’s setup another NPM command in your package.json to do this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &quot;start:chrome-debug&quot;: &quot;node --inspect index.mjs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, when you run it in your terminal, you should see a similar message.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ❯ npm run start:chrome-debug
    
    &amp;gt; debugging-node-server@1.0.0 start:chrome-debug
    &amp;gt; node --inspect index.mjs
    
    Debugger listening on ws://127.0.0.1:9229/8689da89-80f3-4cd4-bdd9-9a6199c8fc34
    For help, see: https://nodejs.org/en/docs/inspector
    Server running at http://localhost:3000/
    Debugger attached.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can visit &lt;strong&gt;chrome://inspect&lt;/strong&gt; in chrome to view your app using the chrome DevTools. You should see your app listed in the &lt;strong&gt;Remote Target&lt;/strong&gt; section. Just click on inspect option and then you should see the chrome DevTools open up. Now you can debug your app with the chrome debugger.&lt;/p&gt;
&lt;h2&gt;How to debug node.js in VS Code&lt;/h2&gt;
&lt;p&gt;The VS Code debugger uses the CLI debugger under the hood and gives you the same options inside your editor. To start, you can go to the debugger window (Ctrl + Shift + D). If you’re doing this for the first time in your app then it will prompt you to create a launch.json file.&lt;/p&gt;
&lt;p&gt;Click on that button to create a new launch.json file. For this specific demo, the default options should be fine. Go to your index.mjs file again and press the “Launch Program” button. It should pause at the first debugger line again and open up the debug console in your VS code terminal.&lt;/p&gt;
&lt;p&gt;You can read more about the different options with the debugger on the &lt;a href=&quot;https://code.visualstudio.com/docs/editor/debugging&quot;&gt;VS code debugger docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I would recommend the following simple changes to the launch.json file for this demo server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update the &lt;strong&gt;program&lt;/strong&gt; property to your server entry file so the debugger will run that file regardless of what file you have currently opened . The default option will try to run the currently opened file with node instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    &quot;program&quot;: &quot;${workspaceRoot}/index.mjs&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;If you’re using something like &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;NVM&lt;/a&gt; to manage your node versions then you can use the &lt;strong&gt;runtimeVersion&lt;/strong&gt; property to match it to your version of node.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    &quot;runtimeVersion&quot;: &quot;20.10.0&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>javascript</category><category>debugging</category><category>node.js</category><author>Nirjan Khadka</author></item><item><title>Destructure and rename variables with JavaScript, plus other cool JS destructuring use cases</title><link>https://nirjan.dev/blog/destructure-and-rename-variables-with-javascript-plus-other-cool-js-destructuring-use-cases/</link><guid isPermaLink="true">https://nirjan.dev/blog/destructure-and-rename-variables-with-javascript-plus-other-cool-js-destructuring-use-cases/</guid><description>Want to simplify your JavaScript code and extract the values you need from objects and arrays easily? Learn how to use destructuring! In this article, I&apos;ll show you how to destructure objects and arrays, rename variables, set default values, and merge arrays and objects. Plus, I&apos;ll also cover how to use destructuring in practical scenarios, such as extracting data from APIs and handling function parameters.</description><pubDate>Mon, 12 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Destructuring and Renaming Variables in JavaScript&lt;/h2&gt;
&lt;p&gt;Destructuring is a useful feature in JavaScript which lets you assign variables to the values of object properties and array items easily. It is a way of unpacking data from objects and arrays into different variables.&lt;/p&gt;
&lt;p&gt;This allows you to create new variables from object properties and array items. In JavaScript, you can destructure objects with curly braces {} and arrays with brackets [].&lt;/p&gt;
&lt;h2&gt;JavaScript Object Destructuring Syntax&lt;/h2&gt;
&lt;p&gt;Destructuring can be used in lots of ways, but the most common usage is to extract properties from an object or items from an array.&lt;/p&gt;
&lt;p&gt;For objects, the syntax is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos;, age: 30 }; const { name, age } = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we’re destructuring the &lt;code&gt;person&lt;/code&gt; object and assigning its &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; property values to a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; variable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Destructuring doesn’t actually change the original object at all. It only copies the value of the object properties.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;JavaScript Array Destructuring Syntax&lt;/h2&gt;
&lt;p&gt;For arrays, the syntax is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const numbers = [1, 2, 3, 4, 5]; const [first, second] = numbers;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the example above, we use destructuring to assign the first two items from the &lt;code&gt;numbers&lt;/code&gt; array to the &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;second&lt;/code&gt; variables.&lt;/p&gt;
&lt;h2&gt;Storing the remaining values in a separate variable&lt;/h2&gt;
&lt;p&gt;You can use the &lt;code&gt;...&lt;/code&gt; rest operator to assign the remaining properties or items in an array to another variable.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos;, age: 30, country: &apos;USA&apos;, city: &apos;New York&apos; };
const { name, age, ...remainingProperties } = person;
console.log(remainingProperties) // {country: &apos;USA&apos;, city: &apos;New York&apos;}

const numbers = [1, 2, 3, 4, 5];
const [first, second, ...remainingItems] = numbers;
console.log(remainingItems) // [3,4,5]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whatever variable you put the &lt;code&gt;...&lt;/code&gt; rest operator in front of, it will have the rest of the values that you didn’t destructure. It will create a new object when destructuring an object and a new array when destructuring an array.&lt;/p&gt;
&lt;h2&gt;Renaming variables using destructuring&lt;/h2&gt;
&lt;p&gt;One of the useful features of destructuring is that it allows you to rename variables during the assignment. You can use the colon &lt;code&gt;:&lt;/code&gt; to rename a variable.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos;, age: 30 };
const { name: personName, age: personAge } = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we are renaming the &lt;code&gt;name&lt;/code&gt; property to &lt;code&gt;personName&lt;/code&gt; and the &lt;code&gt;age&lt;/code&gt; property to &lt;code&gt;personAge&lt;/code&gt;. This is useful when you want to rename a property to something more specific or if there is another variable in the &lt;a href=&quot;https://nirjan.dev/blog/understanding-lexical-scope-and-closures-in-3-minutes&quot;&gt;current JavaScript scope&lt;/a&gt; with the same name.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: the right hand-side will be the new name that you want to use, and the left hand-side will be the name of the property you want to destructure. &lt;code&gt;{name: firstName} means {name as firstName}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Default values with destructuring&lt;/h2&gt;
&lt;p&gt;You can also set default values for variables in case the value is undefined or null. You can do this by using the equal sign &lt;code&gt;=&lt;/code&gt; after the variable name.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos; };
const { name, age = 30 } = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, if the &lt;code&gt;age&lt;/code&gt; property is not defined in the &lt;code&gt;person&lt;/code&gt; object, it will default to &lt;code&gt;30&lt;/code&gt;. This feature is particularly useful when you need to handle optional properties in an object.&lt;/p&gt;
&lt;h2&gt;Practical examples of destructuring in JavaScript&lt;/h2&gt;
&lt;p&gt;Destructuring can be used in many practical scenarios such as extracting data from APIs, handling function parameters, and more. Here are a few cool tricks you can do with destructuring in JavaScript.&lt;/p&gt;
&lt;h3&gt;Extracting function arguments&lt;/h3&gt;
&lt;p&gt;You can use destructuring to quickly create variables from an object parameter for a function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getFullName({ firstName, lastName }) {
    return `${firstName} ${lastName}`;
}

const person = { firstName: &apos;John&apos;, lastName: &apos;Doe&apos;, age: 30 };
const fullName = getFullName(person);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we are using destructuring to extract the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; properties from the &lt;code&gt;person&lt;/code&gt; object to get the full name. This makes the code more readable, and the function parameter is self-documenting.&lt;/p&gt;
&lt;p&gt;Overall, destructuring and renaming variables in JavaScript is a powerful feature that can simplify your code and make it more readable. With destructuring, you can extract the values you need from objects and arrays with ease, and with renaming, you can make your code more descriptive and self-documenting.&lt;/p&gt;
&lt;h3&gt;Removing some properties from an object&lt;/h3&gt;
&lt;p&gt;To remove some properties from an object, you can use destructuring and the rest operator.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos;, age: 30, country: &apos;USA&apos;, city: &apos;New York&apos; };
const { age, ...personWithoutAge } = person;
console.log(personWithoutAge) // {name: &apos;John&apos;, country: &apos;USA&apos;, city: &apos;New York&apos;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we are removing the &lt;code&gt;age&lt;/code&gt; property from the &lt;code&gt;person&lt;/code&gt; object and creating a new object without it. This can be useful when you want to pass an object to a function, but don&apos;t want to include certain properties.&lt;/p&gt;
&lt;h3&gt;Merging arrays and objects&lt;/h3&gt;
&lt;p&gt;Destructuring is also useful when you want to merge objects or arrays. You can use the spread operator to merge objects or arrays together.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const person = { name: &apos;John&apos;, age: 30 };
const address = { country: &apos;USA&apos;, city: &apos;New York&apos; };
const mergedPerson = { ...person, ...address };
console.log(mergedPerson) // {name: &apos;John&apos;, age: 30, country: &apos;USA&apos;, city: &apos;New York&apos;}

const numbers1 = [1, 2, 3];
const numbers2 = [4, 5, 6];
const mergedNumbers = [...numbers1, ...numbers2];
console.log(mergedNumbers) // [1, 2, 3, 4, 5, 6]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we are using the spread operator to merge the &lt;code&gt;person&lt;/code&gt; and &lt;code&gt;address&lt;/code&gt; objects into a new object. We are also using the spread operator to merge two arrays into a new array. This is a concise way of merging objects and arrays without having to write a lot of code.&lt;/p&gt;
&lt;h3&gt;Multiple return values&lt;/h3&gt;
&lt;p&gt;Finally, destructuring can be used to return multiple values from a function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getValues() {
    return [1, 2, 3];
}

const [a, b, c] = getValues();
console.log(a, b, c) // 1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we are using destructuring to assign the values returned from the &lt;code&gt;getValues&lt;/code&gt; function to the variables &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;c&lt;/code&gt;. This is a convenient way to return multiple values from a function without having to pack them into an object or array.&lt;/p&gt;
&lt;p&gt;If you are using react, then this syntax will be familiar. It is used to destructure the return values of &lt;code&gt;useState&lt;/code&gt; and other react hooks.&lt;/p&gt;
&lt;p&gt;Here&apos;s an example of using &lt;code&gt;useState&lt;/code&gt; with destructuring in a React component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { useState } from &apos;react&apos;;

function MyComponent() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;You clicked {count} times&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={handleClick}&amp;gt;Click me&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;JavaScript destructuring allows for easy assignment of object properties and array items to variables. Renaming variables, setting default values, and merging arrays and objects are all possible with destructuring. It can be used in practical scenarios such as extracting data from APIs and handling function parameters. Destructuring is also used in React hooks such as &lt;code&gt;useState&lt;/code&gt;. What are your favourite ways of using destructuring? Let me know in the comments below.&lt;/p&gt;
</content:encoded><category>javascript</category><author>Nirjan Khadka</author></item><item><title>JavaScript Performance Testing Made Easy: A Beginner&apos;s Guide</title><link>https://nirjan.dev/blog/javascript-performance-testing-made-easy-a-beginner-s-guide/</link><guid isPermaLink="true">https://nirjan.dev/blog/javascript-performance-testing-made-easy-a-beginner-s-guide/</guid><description>As a developer, you understand the importance of creating fast, responsive websites. But, identifying and fixing performance issues can be a challenging task. In this post, I&apos;ll give you a beginner-friendly introduction to JavaScript performance testing. After this, you should be able to start debugging JavaScript performance issues on your own.</description><pubDate>Tue, 23 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What causes poor JavaScript performance&lt;/h2&gt;
&lt;p&gt;First, let’s go over what leads to poor JavaScript performance. The most common causes of poor JavaScript performance are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Large JavaScript files with lots of unused code that takes a long time to parse and execute&lt;/li&gt;
&lt;li&gt;JavaScript Code that blocks the main thread for a long time&lt;/li&gt;
&lt;li&gt;Blocking JavaScript code that gets called too often&lt;/li&gt;
&lt;li&gt;Memory Leaks. If you’re using too much memory, the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management#garbage_collection&quot;&gt;Garbage Collector&lt;/a&gt; will run more often. This pauses the execution of your JavaScript and can cause a lag.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To figure out you can optimize your JavaScript code further, we need to do some performance tests. Then, we can make the right optimizations based on the results.&lt;/p&gt;
&lt;h2&gt;JavaScript Performance test for functions&lt;/h2&gt;
&lt;p&gt;If you already know that you&apos;re calling a specific function a lot, then you should test the performance of it. Generally, you can use easy online tools to quickly check the performance of a function. Then, you can make some optimizations and recheck it.&lt;/p&gt;
&lt;p&gt;My favourite tool to do this is &lt;a href=&quot;https://perf.link/&quot;&gt;perf.link&lt;/a&gt;. You can check different functions at the same time, and it will show you how many times it can run in a second.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./perf-link-screenshot.webp&quot; alt=&quot;Demo of using perf.link to do some JavaScript performance testing&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can also use &lt;a href=&quot;http://jsben.ch/&quot;&gt;jsbench.ch&lt;/a&gt; or &lt;a href=&quot;https://jsbench.me/&quot;&gt;jsbench.me&lt;/a&gt; to test JavaScript performance, but &lt;a href=&quot;http://perf.link/&quot;&gt;perf.link&lt;/a&gt; is the easiest to use.&lt;/p&gt;
&lt;p&gt;This is a good way to optimize performance bottlenecks. But how do you the performance bottlenecks in your app? This is where the browser DevTools come into play.&lt;/p&gt;
&lt;h2&gt;JavaScript Performance testing using DevTools&lt;/h2&gt;
&lt;p&gt;You can use the DevTools in any browser to do performance tests. But, I’m going to use chrome for this post because it has the most in-depth measurement tools. Chrome recently added the &lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance-insights/&quot;&gt;new performance insights panel&lt;/a&gt; which is easier to use than the old performance tab.&lt;/p&gt;
&lt;h3&gt;Using the chrome performance insights panel&lt;/h3&gt;
&lt;p&gt;To open the chrome insights panel, first open the Dev Tools (Ctrl + Shift + I). If you don’t see the Performance Insights panel next to the other tabs (Elements, Network, etc), you can search for it using the command palette (Ctrl + Shift + P).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./perf-insights-panel.webp&quot; alt=&quot;The chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can measure the page load performance with this or measure how quickly your app is responding to user interaction.&lt;/p&gt;
&lt;h3&gt;Measuring Page Load Performance with the Performance Insights Panel&lt;/h3&gt;
&lt;p&gt;Before you measure the page load performance, you&apos;ll want to set up the throttling settings at the top. This allows you to simulate the page load for slower CPUs or slower network connections.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./throttling.webp&quot; alt=&quot;The throttling options in the chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can also add your own custom network throttling profile to make it closure to your user&apos;s network.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./network-throttling.webp&quot; alt=&quot;Chrome Performance Insights Panel&apos;s network throttling options&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This &lt;a href=&quot;https://gist.github.com/theodorosploumis/fd4086ee58369b68aea6b0782dc96a2e&quot;&gt;github gist contains the different profile settings for the different network connections.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After setting up the CPU and network throttling, just click on the “Measure page load” button. This will automatically reload the page, start measuring the page load and stop when it’s done.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./insights-recording.webp&quot; alt=&quot;A page load recording using the chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This will show you a recording of the page-load, with performance related events and insights on the right.&lt;/p&gt;
&lt;p&gt;You can click on the insights like Long task, Layout shift, etc to learn more about the issues. It will give you a link to learn how you can fix those issues too.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./insight-details.webp&quot; alt=&quot;Details being shown of a performance insight using the chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is especially helpful for you to debug issues related to Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS). These metrics are a part of Core Web Vitals. You can read more about them in my &lt;a href=&quot;https://nirjan.dev/blog/how-to-improve-core-web-vitals-a-complete-guide-for-developers&quot;&gt;guide to optimizing core web vitals&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can use this panel to figure out exactly which element is causing the most layout shifts. It will also tell you how much it’s impacting the CLS score. This will then allow you to locate the element in the DOM and prevent the shift from happening.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./perf-details.webp&quot; alt=&quot;Details being shown about a Layout Shift using the chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Additionally, You can click on the Largest Contentful Paint event to figure out which part of the LCP process is taking the longest. This will let you focus on the part that needs the most attention. It also gives you some helpful links to fix some of those issues.&lt;/p&gt;
&lt;h2&gt;Debugging common performance issues using DevTools&lt;/h2&gt;
&lt;p&gt;Besides using the Performance insights panel to debug Core Web Vitals issues, you can also use it to debug issues with network resources, long JavaScript tasks and unnecessary layout re-calculations.&lt;/p&gt;
&lt;h3&gt;Debugging network issues&lt;/h3&gt;
&lt;p&gt;The network section can help you figure out what resources are loading, their loading time and their order. It shows all the request from when you start your test to the end.&lt;/p&gt;
&lt;p&gt;If you click on the dropdown arrow next to network, you can toggle a view which shows the network requests grouped by the domain name. The insights panel can also show you all the render blocking requests.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./requests.webp&quot; alt=&quot;A render blocking request in the network area of the performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When you hover over the render blocking request insight, it will highlight the request in the network section on the left. If you click on it, then it will give you more details like about the request. So, you can figure out why you’re making it and if you can avoid the request.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./request-details.webp&quot; alt=&quot;Details of a render blocking CSS request in the chrome performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Debugging Long JavaScript Tasks&lt;/h3&gt;
&lt;p&gt;You can use the performance insights panel to figure out how many long tasks are freezing your site’s UI. Since, JavaScript is single-threaded, if a script takes a long time to run, it will cause your site’s UI to freeze. So, you need to reduce synchronous long tasks as much as possible.&lt;/p&gt;
&lt;p&gt;This panel can show you when long tasks are happening and how long the tasks are going on for. If you enable &lt;a href=&quot;https://web.dev/source-maps/&quot;&gt;source-maps&lt;/a&gt; for your sites, then it will also show you where the functions are in your codebase.&lt;/p&gt;
&lt;p&gt;It will look like this when you have a source map enabled. This tool can also show you if the long tasks are happening on a third-party script.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./long-task.webp&quot; alt=&quot;A long JavaScript task shown in the performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./long-task-details.webp&quot; alt=&quot;Details of a long-running task in the performance insights panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./third-party-long-task.webp&quot; alt=&quot;details of a long-running task from a third-party script&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Tips on using the performance insights panel&lt;/h2&gt;
&lt;p&gt;Here are some tips on using the performance insights panel that will help you make the most out of it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use network and CPU throttling&lt;/li&gt;
&lt;li&gt;Enable Source maps&lt;/li&gt;
&lt;li&gt;Run your tests in incognito mode without any extensions&lt;/li&gt;
&lt;li&gt;Only &lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance-insights/#settings&quot;&gt;enable the sections you’re focusing on&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Summary and tips&lt;/h2&gt;
&lt;p&gt;In summary, here are the main takeaways from this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Poor performance can be caused by various factors, such as unused code, memory leaks, and network issues.&lt;/li&gt;
&lt;li&gt;JavaScript performance testing tools like &lt;a href=&quot;https://perf.link&quot;&gt;perf.link&lt;/a&gt; and the Performance Insights can help identify and fix these issues.&lt;/li&gt;
&lt;li&gt;Best practices, such as minimizing file sizes and avoiding long-running tasks, can significantly improve the speed of JavaScript code.&lt;/li&gt;
&lt;li&gt;The performance panel offers valuable insights into a website&apos;s performance, including load times and network activity.&lt;/li&gt;
&lt;li&gt;By following these tips and utilizing performance testing tools, developers can create fast, responsive websites that provide an optimal user experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tools like &lt;a href=&quot;https://perf.link&quot;&gt;perf.link&lt;/a&gt; and the &lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance-insights/&quot;&gt;performance insights panel&lt;/a&gt; can be a great way to get started with measuring and debugging your JavaScript performance. But if you want to dive even deeper, then &lt;a href=&quot;https://www.thisdot.co/blog/performance-analysis-with-chrome-devtools&quot;&gt;the performance tab&lt;/a&gt; will give you even more data on what is impacting your performance. But, it is also more complicated to use, so you might not need it. Let me know in the comments if this helped you fix any JavaScript performance issues, and what do you think is the most frustrating part of debugging JavaScript performance?&lt;/p&gt;
</content:encoded><category>javascript</category><category>performance</category><category>devtools</category><author>Nirjan Khadka</author></item><item><title>Top 10 Software Engineering Podcasts for Developers: Learn from the Best</title><link>https://nirjan.dev/blog/top-10-software-engineering-podcasts-for-developers-learn-from-the-best/</link><guid isPermaLink="true">https://nirjan.dev/blog/top-10-software-engineering-podcasts-for-developers-learn-from-the-best/</guid><description>Listening to Podcasts is an underrated way to level up in your software development career. It’s also a great way to rest your eyes after working in front of a screen all day. So, Here are my top recommendations for software engineering podcasts.</description><pubDate>Tue, 18 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Listening to Podcasts is an underrated way to level up in your software development career. It’s also a great way to rest your eyes after working in front of a screen all day. So, Here are my top recommendations for software engineering podcasts.&lt;/p&gt;
&lt;h2&gt;Best podcasts for Frontend developers&lt;/h2&gt;
&lt;p&gt;I’ve been working on the frontend for most of my career and as a result, frontend engineering podcasts are some of my favourites in this list. The podcasts listed here won’t be a shock to anyone, as they’re easily the most popular podcasts in the frontend community. But, just because something is popular, it doesn’t mean it’s not good (unless we’re talking about React 😉).&lt;/p&gt;
&lt;h3&gt;Syntax.fm&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://syntax.fm/&quot;&gt;Syntax.fm&lt;/a&gt; is easily the most popular podcast in the frontend community. Wes Bos and Scott Tolinski do a great job of covering the latest trends and technologies in the frontend community. They’ve sold quite a lot of frontend courses and are great teachers. So, this podcast is especially great for beginners or intermediate developers who want to level-up on a new technology.&lt;/p&gt;
&lt;h3&gt;JavaScript Jabber&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://devchat.tv/js-jabber/&quot;&gt;JavaScript Jabber&lt;/a&gt; is a weekly panel discussion podcast featuring a rotating group of experts and guests. The podcast covers a range of topics related to JavaScript, including frameworks, libraries, and tools. Sometimes the debate can get a bit heated, but if you enjoy listening to passionate people defend their stance on modern web development, then you’ll love this podcast.&lt;/p&gt;
&lt;h3&gt;JS Party&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://changelog.com/jsparty&quot;&gt;JS Party&lt;/a&gt; is another panel discussion show with JavaScript experts. The podcast covers a wider range of topics than the previous podcasts. They also branch out and cover other technologies outside of JavaScript that are related to web development. I really like the game show episodes they do, often featuring other podcast hosts from the frontend community.&lt;/p&gt;
&lt;h2&gt;Best podcasts for Programmers&lt;/h2&gt;
&lt;p&gt;The next group of podcasts are a bit more generic and could be interesting to people outside of web development too. Because they cover a lot of different topics, some episodes might not be for you, but they all have a great backlog of programming related content.&lt;/p&gt;
&lt;h3&gt;SE radio&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.se-radio.net/&quot;&gt;SE radio&lt;/a&gt; is a weekly podcast that covers topics related to software engineering like architecture, design patterns, and programming languages. Each episode has expert guests and that discuss topics relevant to programmers. The quality of the episode will depend a lot on the guest, but I find this podcast really useful to get a quick summary on technologies I haven’t used before.&lt;/p&gt;
&lt;h3&gt;Programming Throwdown&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.programmingthrowdown.com/&quot;&gt;Programming Throwdown&lt;/a&gt; is very similar to SE radio in terms of the format. They also feature guest interviews about different programming topics. While SE radio has more variety in terms of guests, Programming Throwdown covers the topic in a bit more detail. The chapter notes included in this podcast are also helpful to skip parts of a discussion you’re already familiar with.&lt;/p&gt;
&lt;h3&gt;The Changelog&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://changelog.com/&quot;&gt;The Changelog&lt;/a&gt; is yet another programming interview podcast (are you getting tired of this yet? I promise this is the last one). It’s from the same people behind JS Party. But instead of focusing on just web development, they cover a wider range of programming topics.&lt;/p&gt;
&lt;p&gt;You can also subscribe to &lt;a href=&quot;https://changelog.com/master&quot;&gt;the master changelog podcast feed&lt;/a&gt; to get all the podcasts from the changelog team.&lt;/p&gt;
&lt;p&gt;They have great show notes and chapter links on all their episodes. They also have the best production quality out of all the podcasts in this list (shoutout to their editor 👍).&lt;/p&gt;
&lt;h3&gt;CodingBlocks.Net&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.codingblocks.net/&quot;&gt;CodingBlocks.Net&lt;/a&gt; started out as just a .Net podcast, but overtime they’ve branched out into different technologies and topics. All the hosts have great personalities and seem really fun to hang out with. They focus mostly on backend technologies, but they explain the topics really well, so even someone who mostly does frontend like me can follow along easily.&lt;/p&gt;
&lt;p&gt;They also do series of episodes focused around programming books occasionally. So if you want to experience a book club in the form of a podcast, then this is definitely something you should follow.&lt;/p&gt;
&lt;h2&gt;Best Podcasts for Indie Developers&lt;/h2&gt;
&lt;p&gt;The next set of podcasts are a great listen if you’re an indie dev or a solo founder. If you work alone, then learning a bit more about the business side of things and related stuff like design can be really helpful. These are my favourite podcasts to do just that.&lt;/p&gt;
&lt;h3&gt;Coder Radio&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://coder.show/&quot;&gt;Coder Radio&lt;/a&gt; by Jupiter Broadcasting is a great podcast if you want to hear about coding from the perspective of two business owners. The hosts do a fantastic job of covering the latest coding news and also sharing what they have been working on.&lt;/p&gt;
&lt;p&gt;I really enjoy hearing about how they go about their decision-making process. If you like this podcast, then you can check out &lt;a href=&quot;https://feed.jupiter.zone/allshows&quot;&gt;the Jupiter Broadcasting’s master feed&lt;/a&gt; to subscribe to the rest of their shows too. They cover topics related to Linux, open source and self-hosting.&lt;/p&gt;
&lt;h3&gt;My Life as a Programmer&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://anchor.fm/fredrik-christenson&quot;&gt;My Life as a Programmer&lt;/a&gt; might be my favourite podcast out of this list. It’s just the audio version of the YouTube clips that &lt;a href=&quot;https://www.youtube.com/@FredrikChristenson&quot;&gt;Fredrik Christensen&lt;/a&gt; puts out.&lt;/p&gt;
&lt;p&gt;In it, he answers coding related questions sent by his audience. They are mostly 5–10 minutes long and straight to the point. He doesn’t preach about any specific tools or technologies, instead you’ll get direct actionable advice from an experienced programmer.&lt;/p&gt;
&lt;h3&gt;Design Details&lt;/h3&gt;
&lt;p&gt;if you’re like me who’s interested in getting better at the design side of things, then &lt;a href=&quot;https://designdetails.fm/&quot;&gt;Design Details&lt;/a&gt; is the perfect podcast for you. It’s hosted by really experienced designers who have worked for companies like YouTube and GitHub. It’s also a relatively short podcast.&lt;/p&gt;
&lt;p&gt;They cover one big topic in every episode and respond to some feedback and questions. Like most of the podcast hosts featured here, they are also great teachers, which makes it easy for non-designers to follow too.&lt;/p&gt;
&lt;h2&gt;Best Podcast Players&lt;/h2&gt;
&lt;p&gt;I hope you find this list of podcasts interesting. Let me know in the comments if you’ve listened to any of them or gave them a try after reading this. As a bonus, here are some of my recommendations for podcast players:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://pocketcasts.com/&quot;&gt;Pocket Casts&lt;/a&gt;: This is my favourite podcast player. It has lots of customization options and great playback controls. My personal favourite feature is auto-archiving podcast episodes. Since, I subscribe to a lot of podcasts, it can get messy real quick. But, with this, if I don’t listen to an episode within 1 week, it will archive it for me.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://podverse.fm/&quot;&gt;Podverse&lt;/a&gt;: This is another great podcast player. It’s also open source and continuously improving. It has the best podcast playback options that I&apos;ve seen. They have an android, IOS, and web app, so you can listen on multiple devices.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fountain.fm/&quot;&gt;Fountain.fm&lt;/a&gt;: I&apos;m not too familiar with this app, but it has an interesting concept. It actually rewards you for listening to more content. You can connect your bitcoin wallet and earn some &lt;a href=&quot;https://www.coindesk.com/learn/what-is-a-satoshi-understanding-the-smallest-unit-of-bitcoin/&quot;&gt;sats&lt;/a&gt; while you listen to podcasts.&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><category>learning</category><author>Nirjan Khadka</author></item><item><title>How to Improve Core Web Vitals: A Complete Guide for Developers</title><link>https://nirjan.dev/blog/how-to-improve-core-web-vitals-a-complete-guide-for-developers/</link><guid isPermaLink="true">https://nirjan.dev/blog/how-to-improve-core-web-vitals-a-complete-guide-for-developers/</guid><description>Are you looking to improve Core Web Vitals on your site, but don’t know where to start? Or have you tried making improvements but didn’t get the results you were hoping for? Then, this post is perfect for you. I’ll go over how to measure, optimize and get great Core Web Vitals on your site with a checklist at the end.</description><pubDate>Tue, 14 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;First, let’s briefly discuss what Core Web Vitals are and how do they impact your site.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Core Web Vitals are page load metrics that measure 3 different aspects of how users experience your site.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Core Web Vitals consists of three metrics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt;: Measures how quickly the main content loads.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cumulative Layout Shift (CLS):&lt;/strong&gt; Measures how stable the layout of the page is.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;First Input Delay (FID):&lt;/strong&gt; Measures how quickly the site responds to user input.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Google uses the &lt;strong&gt;Core Web Vitals (CWV)&lt;/strong&gt; assessment as part of it’s ranking algorithm. So, If your site depends on SEO, then improving CWV can result in more organic traffic. A faster site is also a lot better for your users. Then, there are &lt;a href=&quot;https://web.dev/vitals-business-impact/&quot;&gt;plenty of other business reasons&lt;/a&gt; as well to improve CWV.&lt;/p&gt;
&lt;p&gt;To pass the CWV assessment, you must hit the following targets for all three metrics, for at least 75% of page visits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LCP should be less than 2.5 seconds&lt;/li&gt;
&lt;li&gt;FID should be less than 100 milliseconds&lt;/li&gt;
&lt;li&gt;CLS should be less than 0.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since you need to pass CWV for at least 75% of page visits, you need to improve your site&apos;s experience for all users.&lt;/p&gt;
&lt;p&gt;For instance, suppose we have a website with 36 visitors. We can sort their Core Web Vitals (CWV) experience from best to worse. The green bars are good CWV, yellow bars need improvements, and red bars are poor CWV.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./percentile-bargraph.webp&quot; alt=&quot;Sorted Bar Graph showing an example of Core Web Vitals&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The 75th percentile for this would be the 26th bar (75% of 36), which is in the needs improvements range. So, this site would fail the CWV assessment.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./percentile-bargraph-label.webp&quot; alt=&quot;Sorted Bar Graph showing an example of Core Web Vitals with the 75th Percentile marker&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If we make improvements to speed up the site for visitors that are already getting good CWV then it still won’t pass.The same thing happens when we only make improvements for people getting the poorest CWV.To pass the CWV assessment, you need to make changes that will impact most of your users.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cwv-passing-graph.webp&quot; alt=&quot;Sorted Bar Graph showing an example of Core Web Vitals showing improvements for all users.&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;How to measure Core Web Vitals&lt;/h2&gt;
&lt;p&gt;Before we learn how to improve Core Web Vitals for your site, we need to know how to measure it. You need to have some way of measuring CWV before you start making changes. This will allow you to actually see the impact of your changes. There are two ways to measure CWV.&lt;/p&gt;
&lt;h3&gt;How to measure Core Web Vitals with Lab data&lt;/h3&gt;
&lt;p&gt;This is the easiest way to measure Core Web Vitals. This is the easiest way to measure Core Web Vitals. You can use tools like &lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/overview/&quot;&gt;Lighthouse&lt;/a&gt; and &lt;a href=&quot;https://www.webpagetest.org/&quot;&gt;WebPageTest&lt;/a&gt; to measure it locally, on staging and on production.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/user-centric-performance-metrics/#in-the-lab&quot;&gt;Lab data&lt;/a&gt;, also known as synthetic data, is collected from a controlled environment, rather than actual users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can even use &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse-ci&quot;&gt;Lighthouse CI&lt;/a&gt; to add it to your CI/CD pipelines. This is a good way to get started and build a performance-centric culture in your team. But, since Google will use the metrics from your actual users (that use Chrome), you should have some way to get that data too.&lt;/p&gt;
&lt;h3&gt;How to measure Core Web Vitals with RUM&lt;/h3&gt;
&lt;p&gt;RUM stands for Real User Metrics, and it’s the best way to track Core Web Vitals. There are lots of services that will track your site’s RUM performance for you. Popular services include &lt;a href=&quot;https://speedcurve.com/&quot;&gt;Speedcurve&lt;/a&gt;, &lt;a href=&quot;https://sentry.io&quot;&gt;Sentry&lt;/a&gt;, &lt;a href=&quot;https://developers.cloudflare.com/analytics/web-analytics/getting-started/&quot;&gt;Cloudflare Analytics&lt;/a&gt;, &lt;a href=&quot;https://cronitor.io/&quot;&gt;Cronitor&lt;/a&gt;, &lt;a href=&quot;https://newrelic.com/&quot;&gt;New Relic&lt;/a&gt; and &lt;a href=&quot;https://www.dynatrace.com/&quot;&gt;Dynatrace&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to track RUM performance on your own then you can use the &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals&quot;&gt;web-vitals JavaScript library&lt;/a&gt;. With this library, you can send the metrics to any API that you want. If you have Google Analytics then you can use this to &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals/#send-the-results-to-google-analytics&quot;&gt;send the data to Google Analytics&lt;/a&gt;. Then, you can &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals/#send-the-results-to-google-analytics&quot;&gt;visualize your RUM data in Google Analytics using this tool&lt;/a&gt;. If you use BigQuery or Looker Studio then you can use them to &lt;a href=&quot;https://web.dev/vitals-ga4/&quot;&gt;create a RUM performance dashboard&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;How to check CWV using Google’s Tools&lt;/h3&gt;
&lt;p&gt;You can also use some tools by Google to check your RUM performance. These tools all use the &lt;a href=&quot;https://developer.chrome.com/docs/crux/&quot;&gt;data from chrome users visiting your site.&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CrUX dashboard&lt;/strong&gt;: You can use this pre-built &lt;a href=&quot;https://developers.google.com/web/updates/2018/08/chrome-ux-report-dashboard&quot;&gt;CrUX dashboard&lt;/a&gt;. It uses a Looker Studio template to visualize your data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search Console:&lt;/strong&gt; You can use &lt;a href=&quot;https://search.google.com/search-console/welcome&quot;&gt;Google Search Console&lt;/a&gt; to view the CWV data on a per-page basis for the sites that you own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PageSpeed Insights (PSI)&lt;/strong&gt;: You can use &lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;the PSI tool&lt;/a&gt; to analyze page level and site level metrics. It will show you both the RUM scores and run a lighthouse test for you. You can also use the &lt;a href=&quot;https://developers.google.com/speed/docs/insights/v5/get-started&quot;&gt;PSI API to automate the testing of your pages.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How to keep track of your Core Web Vitals&lt;/h2&gt;
&lt;p&gt;Once you have a Lab and RUM tracking system in place, you should keep monitoring your Core Web Vitals. It is especially important to check them after a release to avoid any regressions. You can also setup alerts when you get performance issues so you can respond quicker. I find this workflow helpful when tracking Core Web Vitals:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Setup performance tests on your CI pipeline to avoid deploying any new issues.&lt;/li&gt;
&lt;li&gt;Setup running Lab tests whenever you make a new deployment and tag the test with the deployment ID.&lt;/li&gt;
&lt;li&gt;Have RUM tracking enabled for all your users.&lt;/li&gt;
&lt;li&gt;Setup alerts whenever you notice the metrics go over a certain threshold.&lt;/li&gt;
&lt;li&gt;Set up a combined dashboard with your user analytics (some tools will have this out of the box). Then you can corelate site performance with your conversion metrics.&lt;/li&gt;
&lt;li&gt;Make sure you &lt;a href=&quot;https://web.dev/vitals-field-measurement-best-practices/&quot;&gt;follow these guidelines when setting up your RUM tracking.&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that we know how to track Core Web Vitals, let’s look at how we can fix your site&apos;s Core Web Vitals.&lt;/p&gt;
&lt;h2&gt;How to improve CLS score&lt;/h2&gt;
&lt;h3&gt;What is CLS?&lt;/h3&gt;
&lt;p&gt;Cumulative Layout Shift (CLS) measures how much your layout shifts during page visit. The more stable the layout, the better scores you will get.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/cls&quot;&gt;Cumulative Layout Shift&lt;/a&gt; metric, measures the instability of content by summing shift scores across layout shifts that don&apos;t occur within 500ms of user input. It looks at how much visible content shifted in the viewport as well as the distance the elements impacted were shifted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;What causes CLS issues?&lt;/h3&gt;
&lt;p&gt;Layout shifts happen when elements that don&apos;t have a fixed height, load after the initial HTML. Elements like images, ads, embeds and banners can cause this issue. Fonts that are a different size than the fallback system font you are using can also cause CLS. When the font loads and replaces the system font, text will be bigger/smaller and cause a layout shift.&lt;/p&gt;
&lt;h3&gt;Debugging and Fixing CLS issues&lt;/h3&gt;
&lt;p&gt;You can run a lighthouse test or use &lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance-insights/&quot;&gt;the chrome performance insights panel&lt;/a&gt; to find the layout shifting elements.&lt;/p&gt;
&lt;p&gt;Compared to the other CWV metrics, CLS is actually pretty easy to get right. To improve your CLS score, you can follow these steps&lt;/p&gt;
&lt;h4&gt;Set the width and height size on your images and video&lt;/h4&gt;
&lt;p&gt;All Modern browsers can calculate the aspect ratio for your images based on the width and height you set. They will add this style to your images by default.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;img { 
  aspect-ratio: attr(width) / attr(height); 
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You also don’t have to worry about the image not being responsive. For example if you have an image that’s 800px wide and 400px tall, then you can set the width and height like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;img width=&quot;800&quot; height=&quot;400&quot; class=&quot;my-img&quot; src=&quot;/path/to/image.jpg&quot; alt=&quot;image description&quot; /&amp;gt;&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you can make it responsive from your CSS&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; .my-image { 
   width: 100%;
   height: auto;
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you have a responsive image that doesn’t have any layout shifts. The Browser will reserve the height based on the aspect ratio calculated from the width and height attributes. Then, because of the CSS, the image will only be 100% of it’s container and won’t go outside of it.&lt;/p&gt;
&lt;h4&gt;Set a content placeholder for dynamic content&lt;/h4&gt;
&lt;p&gt;You should set a placeholder for dynamic content like ads, embeds banners, etc.&lt;/p&gt;
&lt;p&gt;You can create a container div and set the right width and height for it. You can also hide overflowing content, in case the dynamic content is bigger than you expected.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.container { 
  display: block; 
  width: 300px;
  height: 600px; 
  overflow: hidden; 
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;container&quot;&amp;gt; &amp;lt;div class=&quot;my-special-widget&quot;&amp;gt; ... &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Use a fallback font that’s close to your custom font&lt;/h4&gt;
&lt;p&gt;If you are using a web font then you need to make sure you use a fallback font that’s a similar size to it. This will make sure that when the browser downloads the font and applies it, the text doesn’t jump around too much. Other font optimizations that google recommends are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload&quot;&gt;preloading&lt;/a&gt; the web font with &lt;code&gt;&amp;lt;link rel=preload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;combining preloading with &lt;a href=&quot;https://css-tricks.com/really-dislike-fout-font-display-optional-might-jam&quot;&gt;font-display: optional&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How to fix FID issues&lt;/h2&gt;
&lt;h3&gt;What is FID?&lt;/h3&gt;
&lt;p&gt;First Input Delay (FID) measures how fast your site can respond to user input.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;FID measures the time from when a user first interacts with a page (that is, when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to begin processing event handlers in response to that interaction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To pass the Core Web Vitals assessment your site needs to have an FID of 100 miliseconds or less. Another thing to remeber with FID is that it &lt;strong&gt;only measures the delay in event processing&lt;/strong&gt;. This means, the response to the user’s input can be longer but it needs to process it as fast as possible. So, the &lt;strong&gt;response to user inputs like clicks, taps and key presses&lt;/strong&gt; needs to be fast&lt;/p&gt;
&lt;h3&gt;What causes FID issues?&lt;/h3&gt;
&lt;p&gt;The main causes of FID is long running JavaScript tasks or large JavaScript files. Long running tasks in your scripts can block the browser from responding to user input. Likewise, if you have lots of JavaScript files or big JavaScript files then the browser will need more time to run it.&lt;/p&gt;
&lt;h3&gt;Debugging and fixing FID issues&lt;/h3&gt;
&lt;p&gt;FID is difficult to measure because it requires a real user to actually interact with your site. Instead, You can use a metric called &lt;a href=&quot;https://web.dev/tbt/&quot;&gt;Total Blocking Time (TBT)&lt;/a&gt; to estimate your FID. You can get your TBT score by running a lighthouse test. It can give you a good estimate but to get the actual data for FID, you should use some sort of RUM tracking.&lt;/p&gt;
&lt;p&gt;The main ways to improve your FID score include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regularly Audit your third party scripts to make sure you aren’t using large scripts or scripts that have long running tasks.&lt;/li&gt;
&lt;li&gt;Reducing long running tasks in your own code&lt;/li&gt;
&lt;li&gt;Try to use async code as much as possible instead of code that blocks the main thread&lt;/li&gt;
&lt;li&gt;Load less JavaScript on your page -make use of codespliting and minify and compress your code&lt;/li&gt;
&lt;li&gt;Don’t load any unnecessary JavaScript on your page&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you may have noticed, a lot of these tips involve reducing the amount of JavaScript on your site. If you are starting a new project, frameworks like &lt;a href=&quot;https://astro.build/&quot;&gt;astro&lt;/a&gt;, &lt;a href=&quot;https://remix.run/&quot;&gt;remix&lt;/a&gt; or &lt;a href=&quot;https://qwik.builder.io/&quot;&gt;qwik&lt;/a&gt; can help you to ship less JavaScript.&lt;/p&gt;
&lt;h2&gt;How to improve LCP score&lt;/h2&gt;
&lt;h3&gt;What is LCP&lt;/h3&gt;
&lt;p&gt;Largest Contentful Paint (LCP) measures how long a page takes to load the largest image or text block (above the fold). Your site needs to have an LCP of 2.5 seconds or less for at least 75% of page views to pass thre Core Web Vitals assessment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/lcp/&quot;&gt;Largest Contentful Paint (LCP)&lt;/a&gt; is one of the three &lt;a href=&quot;https://web.dev/vitals/#core-web-vitals&quot;&gt;Core Web Vitals&lt;/a&gt; metrics, and it represents how quickly the main content of a web page is loaded.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;What causes LCP issues?&lt;/h3&gt;
&lt;p&gt;LCP is the hardest CWV metric to get right because there are so many possible reasons for a bad LCP score. You can breakdown the loading into different steps to figure out where the bottleneck is. The most common reasons for having a bad LCP score include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Slow response from the server which maskes the HTML load slowly. This in turn makes the LCP element load slower.&lt;/li&gt;
&lt;li&gt;Delaying the loading of the LCP element. If the HTML is fast but there is a significant delay in loading the LCP element itself then it will have a bad LCP score.&lt;/li&gt;
&lt;li&gt;The LCP element taking a long time to load. If the LCP element is a big image or relies on a large font download then this could be another reason for a bad LCP score.&lt;/li&gt;
&lt;li&gt;Blocking the LCP element from rendering. If JavaScript or CSS blocks the LCP element from rendering then it can also lead to bad LCP scores.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;How to optimize Largest Contentful Paint&lt;/h3&gt;
&lt;p&gt;In most cases, there are many reasons for a site having a poor LCP score, not only one reason. So, the best approach is to break down these parts and optimize them.&lt;/p&gt;
&lt;h4&gt;How to fix LCP element load delay&lt;/h4&gt;
&lt;p&gt;This is often the most easy thing to do when optimizing LCP. You should set the loading priority for the LCP element high enough so that it gets loaded as soon as the HTML loads. The sooner the browser can know about the LCP element and download it, the sooner it will load. To do this you can follow these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the LCP element is an image, make sure to load it from the HTML and not from the CSS. If your LCP element is a CSS background image then it will need to wait for the CSS file to download. So, you should to keep the LCP element in the initial HTML.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&quot;preload&quot; fetchpriority=&quot;high&quot; as=&quot;image&quot; href=&quot;/path/to/hero-image.webp&quot; type=&quot;image/webp&quot;&amp;gt; &amp;lt;link rel=&quot;preload&quot; fetchpriority=&quot;high&quot; as=&quot;image&quot; href=&quot;/path/to/font.woff2&quot; type=&quot;font&quot;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Preload your LCP element. If your LCP element is an image, then preload the image using a link preload tag. If your HTML element is a text block then preload the font file.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/priority-hints/&quot;&gt;priority hints&lt;/a&gt; to make sure your are setting the highest priority for your LCP element. You can then check how early the element is being loaded by using this &lt;a href=&quot;https://www.debugbear.com/resource-hint-validator&quot;&gt;resource hint validator tool&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;How to make the LCP element render sooner&lt;/h4&gt;
&lt;p&gt;Sometimes even after loading the LCP element, the browser can’t render it immediately. These are the main causes that can block an LCP element from rendering:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Synchronous Render Blocking JavaScript or CSS in the head of the document.&lt;/li&gt;
&lt;li&gt;Adding the LCP element to the DOM with JavaScript after the page loads. It will need to wait for the JavaScript to load, execute and then add the element.&lt;/li&gt;
&lt;li&gt;A/B testing tools or some other similar logic that is deciding whether to add the LCP element to the page or not.&lt;/li&gt;
&lt;li&gt;Blocking of the main thread by long running JavaScript tasks. The element will need to wait for it to finish before rendering.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To fix the issues mentioned above, you can follow these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inline any critical CSS and JavaScript in the HTML. (make sure to not inline too much CSS or JS)&lt;/li&gt;
&lt;li&gt;Reduce the size of the CSS and JavaScript files.&lt;/li&gt;
&lt;li&gt;Remove any unused CSS and JavaScript. You can &lt;a href=&quot;https://developer.chrome.com/docs/devtools/coverage/&quot;&gt;use the chrome dev tools to find unused CSS and JavaScript.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Minify and Compress your JavaScript and CSS.&lt;/li&gt;
&lt;li&gt;Don’t use any JavaScript script tags without the &lt;a href=&quot;https://discourse.mozilla.org/t/async-v-s-defer/53819&quot;&gt;async or defer attributes.&lt;/a&gt; This will prevent it from blocking the rendering.&lt;/li&gt;
&lt;li&gt;Don’t use &lt;a href=&quot;https://web.dev/rendering-on-the-web/#client-side-rendering-csr&quot;&gt;client-side rendering&lt;/a&gt;. Instead use &lt;a href=&quot;https://web.dev/rendering-on-the-web/#server-rendering&quot;&gt;server-side rendering&lt;/a&gt; or &lt;a href=&quot;https://web.dev/rendering-on-the-web/#static-rendering&quot;&gt;static site generation&lt;/a&gt; instead. This will mean your LCP element will be in the initial HTML document.&lt;/li&gt;
&lt;li&gt;Avoid long tasks in JavaScript as much as possible. If a JavaScript process takes a long time to finish then the browser will delay rendering the images. This is because browsers render images using the main thread which long JS tasks can block.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to make the LCP element load faster&lt;/h3&gt;
&lt;p&gt;The LCP element of your page will be the main featured image in most cases. If you don’t have a featured image on your page then it will be the text. So, this means you need to optmize the LCP element to make it load faster. Here are the most common ways load your LCP element faster:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce the size of your image or web font. Make sure you’re not serving uneccesarily large images.&lt;/li&gt;
&lt;li&gt;Use modern image formats like AVIF or WebP. They will often be a lot smaller than the JPEG or PNG version of the image.&lt;/li&gt;
&lt;li&gt;Use a &lt;a href=&quot;https://web.dev/content-delivery-networks/&quot;&gt;CDN&lt;/a&gt; to serve assets. Look for a CDN that allows you to proxy requests from your domain. This will reduce the extra step the browser has to do to connect to the domain of the CDN provider.&lt;/li&gt;
&lt;li&gt;Don’t load too many resources at the same time that you are loading your LCP element.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/performance/uses-long-cache-ttl/&quot;&gt;Cache your LCP element&lt;/a&gt; so users visiting again will see the LCP element immediately.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to load your HTML faster&lt;/h3&gt;
&lt;p&gt;This is the most difficult way to optimize LCP as it involves making changes in different places. You can start by &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing&quot;&gt;finding out what is the slowest part of loading your HTML.&lt;/a&gt; Different Cloud providers offer different ways to measure your server processing times.&lt;/p&gt;
&lt;p&gt;You might have to make changes to your server-side code, hosting provider, CDN, etc. Here are the most effective ways to load your HTML document faster:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use a good hosting provider with the most optimized settings for your site. Take a look at the memory consumption and CPU ussage for your site. Make sure your server is capable of handling the traffic you are getting. If it&apos;s failing to do that, you should try &lt;a href=&quot;https://www.section.io/blog/scaling-horizontally-vs-vertically/&quot;&gt;scalling your server horizontally or vertically&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/content-delivery-networks/&quot;&gt;Use a CDN&lt;/a&gt; on top of your server so you can serve cached content from your server to your users faster. Some popular CDNs for this are &lt;a href=&quot;https://www.cloudflare.com/&quot;&gt;Cloudflare&lt;/a&gt;, &lt;a href=&quot;https://www.fastly.com/&quot;&gt;Fastly&lt;/a&gt; and &lt;a href=&quot;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot;&gt;Cloudfront&lt;/a&gt;. Make sure to check the cache-hit ratio your are getting. You should be hitting the cache for most of your user vistis if your site’s content doesn’t change often.&lt;/li&gt;
&lt;li&gt;Update links on your site that are redirecting to another page. Having lots of redirects can cause the page to load slower. So, you shoud try to edit all links that are redirecting within your site.&lt;/li&gt;
&lt;li&gt;Stream HTML to the browser. Some server side technologies can stream HTML so the browser doesn’t have to wait to get it all at once.&lt;/li&gt;
&lt;li&gt;If your content doesn&apos;t change too often then you can &lt;a href=&quot;https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate&quot;&gt;use a service worker with the Stale-while-revalidate approach.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you want to speed up your page navigation, then &lt;a href=&quot;https://developer.chrome.com/docs/workbox/faster-multipage-applications-with-streams/&quot;&gt;this approach of using a service worker with streams&lt;/a&gt; can help.&lt;/li&gt;
&lt;li&gt;Check how fast your database queries are executing. You might have to make some &lt;a href=&quot;https://dzone.com/articles/10-database-optimization-best-practices-for-web-de&quot;&gt;database optimizations&lt;/a&gt; to get the data for your pages faster.&lt;/li&gt;
&lt;li&gt;Make use of &lt;a href=&quot;https://nitropack.io/blog/post/early-hints&quot;&gt;103 Early Hints&lt;/a&gt; to load critical assets for the HTML faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Checklist for Improving Core Web Vitals&lt;/h2&gt;
&lt;p&gt;Here&apos;s a checklist to help you optimize your site for Core Web Vitals:&lt;/p&gt;
&lt;h3&gt;Measuring Core Web Vitals&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Use lab data testing with tools like Lighthouse and WebPageTest to get started.&lt;/li&gt;
&lt;li&gt;[ ] Use RUM data tracking to get data from actual users.&lt;/li&gt;
&lt;li&gt;[ ] Use Google&apos;s tools like CrUX dashboard, Search Console, and PageSpeed Insights to track CWV.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to Fix CLS Issues&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Set the width and height size on your images and video.&lt;/li&gt;
&lt;li&gt;[ ] Set a content placeholder for dynamic content.&lt;/li&gt;
&lt;li&gt;[ ] Use a fallback font that&apos;s close to your custom font.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to Fix FID Issues&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Avoid long running JavaScript tasks or large JavaScript files.&lt;/li&gt;
&lt;li&gt;[ ] Regularly audit your third-party scripts.&lt;/li&gt;
&lt;li&gt;[ ] Use async code as much as possible instead of code that blocks the main thread.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to Fix LCP Issues&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Reduce the size of your image or web font.&lt;/li&gt;
&lt;li&gt;[ ] Use modern image formats like AVIF or WebP.&lt;/li&gt;
&lt;li&gt;[ ] Use a CDN to serve assets.&lt;/li&gt;
&lt;li&gt;[ ] Don’t load too many resources at the same time that you are loading your LCP element.&lt;/li&gt;
&lt;li&gt;[ ] Cache your LCP element so users visiting again will see the LCP element immediately.&lt;/li&gt;
&lt;li&gt;[ ] Use a good hosting provider with the most optimized settings for your site.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;General Best Practices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Reduce the use of third-party scripts and keep them up-to-date.&lt;/li&gt;
&lt;li&gt;[ ] Use lazy loading for images and other non-critical resources.&lt;/li&gt;
&lt;li&gt;[ ] Avoid using large JavaScript libraries and frameworks.&lt;/li&gt;
&lt;li&gt;[ ] Optimize your CSS to cut down on render-blocking stylesheets.&lt;/li&gt;
&lt;li&gt;[ ] Use server-side rendering or static site generation to reduce the load on the client.&lt;/li&gt;
&lt;li&gt;[ ] Use a service worker to cache content.&lt;/li&gt;
&lt;li&gt;[ ] Optimize your web server to reduce response times.&lt;/li&gt;
&lt;li&gt;[ ] Use a content delivery network (CDN) to serve content closer to your users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By following these steps, you&apos;ll optimize your site for Core Web Vitals and a better user experience. Remember that improving your CWV will also improve your search engine rankings. So, it&apos;s worth taking the time to make these improvements.&lt;/p&gt;
&lt;h2&gt;Tools for Improving Core Web Vitals&lt;/h2&gt;
&lt;p&gt;Here are some tools that will be useful to improve your Core Web Vitals.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/web/tools/lighthouse&quot;&gt;Lighthouse&lt;/a&gt; - an open-source tool developed by Google that measures and improves site performance&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.webpagetest.org/&quot;&gt;WebPageTest&lt;/a&gt; - a free online tool that tests site performance from different locations worldwide&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://analytics.google.com/&quot;&gt;Google Analytics&lt;/a&gt; - tracks Core Web Vitals and provides custom reports and dashboards&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/&quot;&gt;Chrome DevTools&lt;/a&gt; - built-in web developer tools in the Chrome browser for real-time performance optimization&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/speed/pagespeed/insights/&quot;&gt;PageSpeed Insights&lt;/a&gt; - a Google tool that analyzes site performance and provides improvement recommendations&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://speedcurve.com/&quot;&gt;SpeedCurve&lt;/a&gt; - a tool that tracks site performance over time, providing detailed metrics and visualizations&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gtmetrix.com/&quot;&gt;GTmetrix&lt;/a&gt; - analyzes site speed and provides actionable insights for optimization&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pingdom.com/&quot;&gt;Pingdom&lt;/a&gt; - monitors site performance and uptime, and provides alerts for issues&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yslow.org/&quot;&gt;YSlow&lt;/a&gt; - analyzes site speed and provides recommendations for improvement&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://varvy.com/pagespeed/&quot;&gt;Varvy Pagespeed Optimization&lt;/a&gt; - analyzes site speed and provides detailed recommendations for optimiza&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/&quot;&gt;Web.dev&lt;/a&gt; - a Google resource that provides guidance and tools for improving site performan&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/web/tools/chrome-user-experience-report&quot;&gt;CrUX dashboard&lt;/a&gt;: A tool that provides aggregated metrics for a large number of sites, based on real-world user data.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChrome/lighthouse-ci&quot;&gt;Lighthouse CI&lt;/a&gt;: A continuous integration service for Lighthouse, which runs Lighthouse tests on every pull request to your codebase.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://search.google.com/search-console/about&quot;&gt;Search Console&lt;/a&gt;: A free tool from Google that helps you monitor, maintain, and improve your site&apos;s presence in Google Search results.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/analytics/&quot;&gt;Cloudflare Analytics&lt;/a&gt;: A tool that provides insights into your site&apos;s performance, security, and reliability. It includes Core Web Vitals data.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sentry.io/&quot;&gt;Sentry&lt;/a&gt;: A tool for error tracking and monitoring. It can help you identify and fix issues that are impacting your site&apos;s performance.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://analytics.google.com/&quot;&gt;Google Analytics&lt;/a&gt;: A tool that provides insights into your site&apos;s traffic, user behavior, and performance.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance-insights/&quot;&gt;Performance Insights Panel&lt;/a&gt;: A panel in the Chrome DevTools that provides insights into your site&apos;s performance, including Core Web Vitals data.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.debugbear.com/resource-hint-validator&quot;&gt;Debugbear Resource Validator&lt;/a&gt;: A tool that can help you validate your resource hints, including preload and prefetch hints, to ensure that they are being used correctly and are improving your site&apos;s performance.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>performance</category><category>javascript</category><author>Nirjan Khadka</author></item><item><title>Software Development Project Management 101: How to Stay On Track and Deliver Quality Software</title><link>https://nirjan.dev/blog/software-development-project-management-101-how-to-stay-on-track-and-deliver-quality-software/</link><guid isPermaLink="true">https://nirjan.dev/blog/software-development-project-management-101-how-to-stay-on-track-and-deliver-quality-software/</guid><description>Is your team having trouble staying focused and delivering on time? Having a good software development project management plan can help. In this post, I&apos;ll cover the most important parts of it, so you can stay on track and deliver quality software.</description><pubDate>Wed, 01 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Goals of Project Management in Software Development&lt;/h2&gt;
&lt;p&gt;This isn&apos;t about a specific framework like Agile, Scrum, Kanban, etc. Instead, it&apos;s about practices that should work with them all. You should use those frameworks as tools for your end goal, not as a strict checklist to follow. A good project management plan should cover how to do these three things well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build the &lt;strong&gt;right thing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Build the &lt;strong&gt;thing right&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Build the &lt;strong&gt;thing fast&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Key Roles in a Software Development Team: Product Owner, Project Manager and Individual Contributors&lt;/h2&gt;
&lt;p&gt;To build a successful product, you&apos;ll need a team of people with different expertise. Each person needs to know exactly what their role is and how they can do it most effectively. Here are some key roles in a software development team:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Product Owner&lt;/strong&gt;: The PO is in charge of the “&lt;strong&gt;build the thing right&lt;/strong&gt;” part. This person acts as a bridge between the stakeholders and the dev team. They need to be a good communicator and should explain the goals of the product to the dev team. They should prioritize the tasks, so the team can focus on the most valuable tasks for the business.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project Manager&lt;/strong&gt;: This person is in charge of the “&lt;strong&gt;build the thing fast&lt;/strong&gt;” part. It&apos;s their job to make sure the team is as efficient as possible. They need to manage people, remove blockers for the team, and increase productivity. They should coach the team, analyse progress, and make changes to deliver things on time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Individual Contributors&lt;/strong&gt;: They are responsible for the “&lt;strong&gt;build the thing right&lt;/strong&gt;” part. This includes people from the dev team, the design team, the QA team, etc. They should build the product to a certain standard. They need to meet the requirements set by the PO.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Document the Project Management Process&lt;/h2&gt;
&lt;p&gt;You should have clear documentation on the steps each team member needs to take and when. This ensures everyone is as efficient as possible. Include all the steps of the project management process and what each team member needs to do.&lt;/p&gt;
&lt;p&gt;Make sure to update this often as processes may change over time. You can also automate some of the tedious steps that the team members need to do to keep it updated.&lt;/p&gt;
&lt;h2&gt;Create consistent task descriptions&lt;/h2&gt;
&lt;p&gt;You should create a consistent task template for all similar tasks. The template can be different for each team or company. But, it should encourage the creators to include all the relevant details.&lt;/p&gt;
&lt;p&gt;Our templates look like this: &lt;code&gt;As a &amp;lt;user role&amp;gt;, I want to &amp;lt;feature description&amp;gt; so that &amp;lt;benefit&amp;gt;&lt;/code&gt;. We also leave some room for more context and comments from the person creating the task. All task descriptions should have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who will benefit from the task&lt;/li&gt;
&lt;li&gt;Clear explanation of the requested change&lt;/li&gt;
&lt;li&gt;How will it be beneficial for the business (with calculations or estimated improvements if possible)&lt;/li&gt;
&lt;li&gt;Any examples by other sites/apps&lt;/li&gt;
&lt;li&gt;Does this have a fixed deadline&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Create a task checklist&lt;/h2&gt;
&lt;p&gt;You must have a clear idea of what you should finish, to complete a task. This helps with sprint reviews, or individual PR reviews. A checklist is a great thing to include in a task. This helps the task creator to communicate to the developers exactly what they want.&lt;/p&gt;
&lt;h2&gt;How to estimate a task&lt;/h2&gt;
&lt;p&gt;This is one of the most difficult things to do. But for effective project management, it is something we have to do. Without estimates, it&apos;s hard to prioritize the work.&lt;/p&gt;
&lt;p&gt;It also makes it difficult to communicate the status of the project to the stakeholders. Some teams prefer time estimation, while some teams prefer estimating using story points. Our team moved from time estimation to story point estimation. Here’s a helpful &lt;a href=&quot;https://www.atlassian.com/agile/project-management/estimation&quot;&gt;guide on story points estimation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;How to prioritize tasks&lt;/h2&gt;
&lt;p&gt;A good prioritization system will make sure your team is focusing on the right things. If you already have a good system for creating tasks and estimating them, then this part should be easy.&lt;/p&gt;
&lt;p&gt;Your team needs to settle on a consistent and clear prioritization system. In our team, we&apos;re using this formula, (Business point + Time Criticality) / Story points. Business points,&lt;/p&gt;
&lt;p&gt;Time criticality and Story points all use a modified Fibonacci series as the values, e.g. 1,2,3,5,8,13,20,40, etc. A good priority formula should account for the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How time sensitive a task is&lt;/li&gt;
&lt;li&gt;How much value will it bring to the business&lt;/li&gt;
&lt;li&gt;How complex will it be to finish it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Setting up a review process&lt;/h2&gt;
&lt;p&gt;At the end of each sprint, there needs to be a review. The team should go over what they accomplished and celebrate that. They should also look at any problems faced during the sprint and find ways to avoid that in future sprints.&lt;/p&gt;
&lt;p&gt;It can be hard to schedule time for the review in a fast-paced environment, but this is one of the most important parts of the process. You should check that your process is actually working and meeting your needs.&lt;/p&gt;
&lt;p&gt;Make sure you&apos;re not blindly following a plan just because it&apos;s easy and that&apos;s how you&apos;ve always done it. You should track the key objectives of your business. Then see if the work you&apos;ve done in your previous sprint has actually got you closer to the objectives or not. If they haven&apos;t, then you need to refine all the items mentioned above for the next sprint.&lt;/p&gt;
&lt;p&gt;Besides the sprint review, you should also have a check-in process to see how the team is progressing on the tasks. This doesn’t need to be as thorough as the sprint review. This should remove any blockers from the team and figure out if the team is on track or not.&lt;/p&gt;
&lt;h2&gt;Communication within the team&lt;/h2&gt;
&lt;p&gt;You should have a clear communication system set up for your team, especially if it’s a remote team. Try to keep it as asynchronous as possible. Tailor your communication for the intended audience.&lt;/p&gt;
&lt;p&gt;Highlight the stuff that your audience actually cares about. Be careful not to have too little communication, which can make people lost. Also, don&apos;t over communicate, which can cause information overload. When creating your process documentation, include how the team should give out updates.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Conclusion and checklist&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;I hope these tips have helped you decide what things you need to do next for your process. Here’s a list of stuff that will help you make your process better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure each team member is aware of their role in the team.&lt;/li&gt;
&lt;li&gt;Make sure each team member knows the full process they should follow as part of their role.&lt;/li&gt;
&lt;li&gt;Have a consistent Task template and ensure everyone follows it.&lt;/li&gt;
&lt;li&gt;All tasks should have a checklist that the team can review.&lt;/li&gt;
&lt;li&gt;Estimate tasks in relative values instead of an absolute value like a time duration.&lt;/li&gt;
&lt;li&gt;Each task should have an estimate for it.&lt;/li&gt;
&lt;li&gt;Create a prioritization system which should sort the tasks automatically for the team.&lt;/li&gt;
&lt;li&gt;Have a template for your review process. Make sure to tie down the reviews with the key metrics your business cares about.&lt;/li&gt;
&lt;li&gt;Have check-ins within sprints to check whether the team is on track or not.&lt;/li&gt;
&lt;li&gt;Set up async communication between the team and the key stakeholders. Inform everyone about the key areas they actually care about. Tailor your communication for the intended audience.&lt;/li&gt;
&lt;li&gt;The Product Owner should communicate the business priorities to the dev team.&lt;/li&gt;
&lt;li&gt;The Project Manager should inform the Product Owner about the status of the different work streams.&lt;/li&gt;
&lt;li&gt;The Dev team should communicate the changes made to the Product Owner.&lt;/li&gt;
&lt;li&gt;The Product Owner and the Dev team should inform the design team on the goals of the designs and the technical limitations for the design.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>management</category><author>Nirjan Khadka</author></item><item><title>Moving to a Tech Lead role, Working on More Side projects, Learning Sveltekit and C# | 2022 review</title><link>https://nirjan.dev/blog/moving-to-a-tech-lead-role-working-on-more-side-projects-learning-sveltekit-and-c-sharp-2022-review/</link><guid isPermaLink="true">https://nirjan.dev/blog/moving-to-a-tech-lead-role-working-on-more-side-projects-learning-sveltekit-and-c-sharp-2022-review/</guid><description>It&apos;s that time of the year again – the end of the year – and it&apos;s a great opportunity to reflect on the past 12 months and all that we&apos;ve accomplished. This year has flown by, but it&apos;s been a year of growth and learning for me.</description><pubDate>Fri, 30 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I also wrote about &lt;a href=&quot;https://nirjan.dev/blog/first-remote-job-leading-a-team-learning-seo-or-2021-review-from-a-web-developer&quot;&gt;my experience in 2021&lt;/a&gt; if you want to take a look at how that went down.&lt;/p&gt;
&lt;h2&gt;New role at work&lt;/h2&gt;
&lt;p&gt;I was officially promoted to the Technical Lead role at &lt;a href=&quot;https://www.gfinityplc.com/gfinity-digtial-media/&quot;&gt;Gfinity Digital Media&lt;/a&gt;. This has meant shifting my focus more towards management than coding. While there are some aspects of the role that I don&apos;t enjoy as much, like an increase in meetings and process management, I&apos;m excited to be able to play a bigger role in shaping the vision and strategy of the company. I&apos;ve also really enjoyed improving the workflow of my team and helping them grow as we work to make our sites better with each release.&lt;/p&gt;
&lt;h2&gt;Major accomplishments&lt;/h2&gt;
&lt;p&gt;Together with my amazing team, we were able to accomplish quite a lot. Some of the highlights include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Migrating two new sites from WordPress to our custom Manifold tech stack&lt;/li&gt;
&lt;li&gt;Adding a suite of automation tools to help our content team produce better content faster&lt;/li&gt;
&lt;li&gt;Improving our personalization tech to serve more personalized promotions on our network&lt;/li&gt;
&lt;li&gt;Working with the &lt;a href=&quot;https://www.stockinformer.com/&quot;&gt;Stockinformer&lt;/a&gt; team to add a custom products’ widget on our sites that can track the stock and prices of products in almost real-time&lt;/li&gt;
&lt;li&gt;Faster and smoother editing experience for larger articles in our CMS&lt;/li&gt;
&lt;li&gt;More fine-grained access controls for our CMS&lt;/li&gt;
&lt;li&gt;More UI improvements to large sections of our sites like navigation, search, article cards, image and video galleries, etc&lt;/li&gt;
&lt;li&gt;Improved the speed of RSS feed and sitemap generation significantly&lt;/li&gt;
&lt;li&gt;New Ad placement algorithm to improve the UX of our sites while boosting ad revenue and impressions&lt;/li&gt;
&lt;li&gt;Started adding automated tests for the most important parts of our codebase&lt;/li&gt;
&lt;li&gt;Improvements to documentation and product analytics&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Things I learned in 2022&lt;/h2&gt;
&lt;p&gt;I&apos;ve been able to learn a lot about management this year, but that has limited my ability to learn new technical skills. To make up for this, I&apos;ve made a conscious effort to set aside personal time to work on side projects. Some of the things I&apos;ve learned or delved deeper into this year include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Started learning about C# and dotnet&lt;/li&gt;
&lt;li&gt;Learned &lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; and migrated my personal site from &lt;a href=&quot;https://elderguide.com/tech/elderjs/&quot;&gt;Elder.js&lt;/a&gt; to Next.js&lt;/li&gt;
&lt;li&gt;Started learning &lt;a href=&quot;https://kit.svelte.dev/&quot;&gt;Sveltekit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tried out &lt;a href=&quot;https://nuxt.com/v3&quot;&gt;Nuxt 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Currently building a side-project using &lt;a href=&quot;https://supabase.com/&quot;&gt;Supabase&lt;/a&gt; and Sveltekit&lt;/li&gt;
&lt;li&gt;Moved my site from markdown to &lt;a href=&quot;https://www.sanity.io/&quot;&gt;Sanity.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Started Learning &lt;a href=&quot;https://cloud.google.com/bigquery/&quot;&gt;Google BigQuery&lt;/a&gt; and &lt;a href=&quot;https://datastudio.google.com/&quot;&gt;Google DataStudio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Did the &lt;a href=&quot;https://seofordevs.com/&quot;&gt;SEO for Devs course&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the main takeaways I&apos;ve had this year is the importance of being clinical in deciding where to spend my time and energy. I also plan to be more consistent with my &quot;learning in public&quot; approach and not worry so much about perfection.&lt;/p&gt;
&lt;h2&gt;Things I want to learn in 2023&lt;/h2&gt;
&lt;p&gt;I already have a huge list of things I want to learn in 2023. This may change in the future but here are the things I want to learn next year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More Sveltekit (I really like the progressive enhancement concepts and the simplicity of the dev experience)&lt;/li&gt;
&lt;li&gt;More Supabase and Postgres (I want to do more side-projects using supabase and want to dive deeper into Postgres too)&lt;/li&gt;
&lt;li&gt;Improving my SEO knowledge (while ChatGPT is a threat to google, I don’t see the value of SEO skills declining for at least another decade)&lt;/li&gt;
&lt;li&gt;Improving my backend skills (I want to get some experience with more backend technologies so that I can be a bit more well-rounded)&lt;/li&gt;
&lt;li&gt;Marketing (I want to be able to market my side-projects and start generating some revenue from them)&lt;/li&gt;
&lt;li&gt;Writing (I want to write more in 2023 and keep improving my writing and communication skills)&lt;/li&gt;
&lt;li&gt;Machine Learning and AI models&lt;/li&gt;
&lt;li&gt;Finally, I want to continue improving my team leadership skills and finding ways to better support and empower my team.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;My focus in 2023&lt;/h2&gt;
&lt;p&gt;I’m honestly looking forward to 2023. I want to launch a couple of products and learn how to market them. Furthermore, I’m also looking forward to doing more svelte and learning more about backend technologies. It’s going to be hard, but I’m going to try to write a lot more and document my journey in 2023 as I build and learn new things along the way. Happy new year, everyone! Hope you have a great year ahead.&lt;/p&gt;
</content:encoded><category>review</category><author>Nirjan Khadka</author></item><item><title>11 easy tips to fix bugs and debug your code faster</title><link>https://nirjan.dev/blog/11-easy-tips-to-fix-bugs-and-debug-your-code-faster/</link><guid isPermaLink="true">https://nirjan.dev/blog/11-easy-tips-to-fix-bugs-and-debug-your-code-faster/</guid><description>I have a love-hate relationship with coding bugs. I hate finding and debugging them, but I love the moment that I find a fix for it. As my career progresses, I&apos;ve found some things that I do over and over that help me fix bugs faster. In this post, I&apos;ll list the debugging tips that I use the most.</description><pubDate>Fri, 25 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. Gather info&lt;/h2&gt;
&lt;p&gt;Your dev tools are your best friends during this step. Look for error messages in the console or your logging tool of choice. Try to reproduce your error by focusing on certain parts of your app. Look at the end-game. Ask yourself what are you trying to do? Try to be focused instead of looking everywhere. The better you get at filtering logs, the easier this will get.&lt;/p&gt;
&lt;p&gt;Can you build a simpler version some place else like &lt;a href=&quot;https://codepen.io/&quot;&gt;codepen&lt;/a&gt;, &lt;a href=&quot;https://codesandbox.io/&quot;&gt;codesandbox&lt;/a&gt;, &lt;a href=&quot;https://stackblitz.com/&quot;&gt;stackblitz&lt;/a&gt;, etc?&lt;/p&gt;
&lt;p&gt;You need to be analytical in this step of the process and think like a detective.&lt;/p&gt;
&lt;h2&gt;2. Go through your code&lt;/h2&gt;
&lt;p&gt;Actually read your code – don&apos;t skim it. Think about how the code is actually working. Follow the control flow of the code. If you have a whiteboard or even a notebook, then use that in this step. Try to visualize your code and create a mental model of how it&apos;s working. Can you spot any logical issues with your code? This step can also help you figure out if you need to refactor your code, too. If it&apos;s hard to read and reason about then when you&apos;re done fixing the bug, you should also make a note of coming back to this and refactoring it.&lt;/p&gt;
&lt;h2&gt;3. Stay calm and take a break&lt;/h2&gt;
&lt;p&gt;It&apos;s easy to get nervous or worked up when the stakes are high, but panicking won&apos;t help. Don&apos;t stress out about finding the bug. Take a 10-minute walk or take deep breaths, take a shower, stretch, anything that will help clear your mind.&lt;/p&gt;
&lt;p&gt;Sometimes our subconscious is a much better coder than we are. We can stumble upon the fix when we least expect it. This is also a good time to ask for help if you are working in a team. Normally, I ask for help if I get stuck on a problem for more than &lt;strong&gt;2 hours without any progress&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You don&apos;t want to go to your teammates for every small issue. But there is also no point in wasting hours of your time if they can help you fix it in minutes.&lt;/p&gt;
&lt;h2&gt;4. Make it simple&lt;/h2&gt;
&lt;p&gt;Make your code simpler, break it into smaller parts. Limit the number of inputs and outputs. Get it working in a limited capacity. (e.g. safe mode, Codepen, etc.)&lt;/p&gt;
&lt;p&gt;Comment out major sections of code until you have a working example. Ask yourself, does this issue exist outside the framework? Does this work in a clean environment? Sometimes the bugs can exist outside your code. It might just be a bug in a third party library.&lt;/p&gt;
&lt;h2&gt;5. Test in all environments&lt;/h2&gt;
&lt;p&gt;Testing in different environments can help you discover the cause of your errors quicker. You should be able to take a look at the problem at different levels. Does it work locally but not on the server? Does it work in other browsers? Is it breaking only on mobile and not desktop? Tools like &lt;a href=&quot;https://www.lambdatest.com/&quot;&gt;lambdatest&lt;/a&gt; and &lt;a href=&quot;https://www.browserstack.com/&quot;&gt;browserstack&lt;/a&gt; are great for this.&lt;/p&gt;
&lt;h2&gt;6. Talk it over&lt;/h2&gt;
&lt;p&gt;Getting the perspective of another developer can be extremely helpful. Even talking to a non developer about what you are trying to do can sometimes help you get to the root of your issue. Even if you&apos;re alone, just saying the problem out loud can be helpful.&lt;/p&gt;
&lt;h2&gt;7. Use Git&lt;/h2&gt;
&lt;p&gt;Commit your code often. If you&apos;re worrying about having too many commits in your branch, then you can &lt;a href=&quot;https://www.git-tower.com/learn/git/faq/git-squash/&quot;&gt;squash them&lt;/a&gt; when you&apos;re done. If your code commits are up-to-date, you can change code without fear of deleting things. Just revert to a previous commit once you find the issue and fix it. You can use git features like &lt;a href=&quot;https://www.git-scm.com/docs/git-stash&quot;&gt;stashing&lt;/a&gt; to try out different things.&lt;/p&gt;
&lt;h2&gt;8. Don&apos;t jump to solutions&lt;/h2&gt;
&lt;p&gt;Take the time to dissect the problem. Question your assumptions. If you&apos;re thinking It can&apos;t possibly be a problem with x, then it might actually be a problem with x. Nothing should be off the table. Sometimes the cause of your bugs are in the place you least expected.&lt;/p&gt;
&lt;h2&gt;9. Get good at pattern matching&lt;/h2&gt;
&lt;p&gt;This comes with experience. After fixing a lot of bugs throughout your career, you&apos;ll notice yourself asking the same questions. When did this problem start? Did we deploy any code? Did we change any logic? X bugs tend to happen when Y happens. This is mostly about figuring out the right questions to ask.&lt;/p&gt;
&lt;h2&gt;10. Document your bug fixes&lt;/h2&gt;
&lt;p&gt;This is related to the last tip. It&apos;s not good enough to only recognize the questions you&apos;re asking to find the bugs. You should also document it somehow. List your errors, their causes, and their solution somewhere. You never know when you will run into the same problem again. You don&apos;t have to list every bug, only the ones that took a long time to find the fix for.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like to list all the bugs and their fixes that I&apos;ve faced before using GitHub issues. You can use the labels to organize them and the search feature to find the bug fix you&apos;re looking for.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;11. Google&lt;/h2&gt;
&lt;p&gt;Get good at googling, being able to describe your problem is key. Learn to search for keywords that will help you find solutions quicker. Also, learn to search in sites like &lt;a href=&quot;https://stackoverflow.com/&quot;&gt;stackoverflow&lt;/a&gt;, GitHub issue pages, discord channels, etc.&lt;/p&gt;
&lt;p&gt;Most likely someone has already faced a similar problem. So, there is already a fix for it somewhere on the internet.&lt;/p&gt;
&lt;p&gt;Do you have any other debugging tips? I would love to hear about it in the comments section. Thanks for reading.&lt;/p&gt;
</content:encoded><category>debugging</category><author>Nirjan Khadka</author></item><item><title>First remote job, leading a team, learning SEO | 2021 review from a web developer</title><link>https://nirjan.dev/blog/first-remote-job-leading-a-team-learning-seo-or-2021-review-from-a-web-developer/</link><guid isPermaLink="true">https://nirjan.dev/blog/first-remote-job-leading-a-team-learning-seo-or-2021-review-from-a-web-developer/</guid><description>This was a pretty big year for me. While my personal life didn’t change a lot because of the pandemic, my professional life changed quite a lot. I got my first remote role, got involved more in management and met lots of talented people. I don’t remember each moment, but I do have some highlights for the year that I want to go through in this post.</description><pubDate>Sat, 08 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This was a pretty big year for me. While my personal life didn’t change a lot because of the pandemic, my professional life changed quite a lot. I got my first remote role, got involved more in management and met lots of talented people. I don’t remember each moment, but I do have some highlights for the year that I want to go through in this post.&lt;/p&gt;
&lt;h2&gt;Work update&lt;/h2&gt;
&lt;p&gt;I joined Gfinity in December 2020 so this year I finished my first full year at &lt;a href=&quot;https://www.gfinityplc.com/&quot;&gt;Gfinity&lt;/a&gt;. My experience has been pretty good so far. We have a great team of talented developers from around the world. The team that I’m working on is small, so we’ve had a chance to get to know each other pretty well. I like the fact that my team can run at a startup speed without a rigid bureaucratic management team. Yet, we don&apos;t have to constantly worry about raising money. We have a flexible remote working culture that has allowed me to improve my work-life balance.&lt;/p&gt;
&lt;p&gt;Some notable moments for me at gfinity so far include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Being able to manage a team for the first time in my career.&lt;/li&gt;
&lt;li&gt;Architecting a new platform (Manifold) to power the sites in our network.&lt;/li&gt;
&lt;li&gt;First time working with SEO and Ads. It was challenging, but the experience of working with them has made me a better developer.&lt;/li&gt;
&lt;li&gt;Learning more about improving site performance. A huge part of my job was improving the performance of the sites in our network.&lt;/li&gt;
&lt;li&gt;Being able to improve my project management skills. This was the first time I had to actually go in-depth with project management. There are still some that I need to improve on, but I’ve made good progress in this part of my skill set. I still have a love-hate relationship with click up (our project management tool).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Accomplishments&lt;/h2&gt;
&lt;p&gt;These are the things that I’m most proud of in 2021:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First time leading a team of developers.&lt;/li&gt;
&lt;li&gt;Architecting the manifold platform that will power all our sites going forward.&lt;/li&gt;
&lt;li&gt;Being able to contribute to the decision-making process as well instead of only working on tech features.&lt;/li&gt;
&lt;li&gt;Improving the project management process for my team.&lt;/li&gt;
&lt;li&gt;SEO improvements made to the Gfinity Digital Media sites (ended the year at 15.5 monthly unique users).&lt;/li&gt;
&lt;li&gt;Performance improvements made to the Gfinity Digital Media sites (went from sites loading MBs of only JavaScript and 800KB of compressed HTML to 600 KB for all resources including HTML, JS, CSS, images and fonts). We’re also close to getting a green CWV score on all the sites using our manifold platform.&lt;/li&gt;
&lt;li&gt;Migrated two sites from WordPress and a legacy CMS over to the new manifold platform.&lt;/li&gt;
&lt;li&gt;Kept a consistent deployment schedule for almost the entire year.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What next&lt;/h2&gt;
&lt;p&gt;It has been an eventful year, but I expect 2022 to be even bigger. These are the things I’m most excited for in 2022&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Growing the GDM network (more sites, more traffic, more revenue).&lt;/li&gt;
&lt;li&gt;Process improvements — I want to further optimize our tech precesses like sprint planning, CI/CD, automated testing, etc.&lt;/li&gt;
&lt;li&gt;Re-architechting manifold — the first version of manifold has served its purpose well. Now we need to update it to fit the current requirements of the network.&lt;/li&gt;
&lt;li&gt;Focusing on writing high quality tests for the most important parts of the network.&lt;/li&gt;
&lt;li&gt;Growing the GDM community — only having high traffic is not enough. We should be aiming to have a more engaged user base and strive to provide more value to our users.&lt;/li&gt;
&lt;li&gt;Writing more posts — There are lots of topics like SEO, web performance, CSS, project management, debugging, UI/UX,etc that I&apos;m interested in. I&apos;m hoping to write about them a lot more this year.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;It has been a crazy challenging year in which I got to grow quite a lot in my role. Special shoutout to &lt;a href=&quot;https://www.linkedin.com/in/mikenstevens/&quot;&gt;Mike Stevens&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/rivulent/&quot;&gt;Eric Ping&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/dominicneedler/&quot;&gt;Dominc Needler&lt;/a&gt; at Gfinity who believed in my capabilities and trusted me to lead the amazing GDM tech team (&lt;a href=&quot;https://www.linkedin.com/in/vlad-polevoi-3a0937138/&quot;&gt;Vlad&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/okandas/&quot;&gt;Raymond&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/victor-obije-a78003187/&quot;&gt;Victor&lt;/a&gt;). On a personal note, I am looking forward to writing more and building more cool stuff in 2022. Happy new year, everyone!&lt;/p&gt;
</content:encoded><category>review</category><author>Nirjan Khadka</author></item><item><title>How to build accessible hidden navigation menus on the web</title><link>https://nirjan.dev/blog/how-to-build-accessible-hidden-navigation-menus-on-the-web/</link><guid isPermaLink="true">https://nirjan.dev/blog/how-to-build-accessible-hidden-navigation-menus-on-the-web/</guid><description>Menus are all over the web, but a lot of them are inaccessible. As the people building the web, we need to make sure that everyone is able to use our sites without a problem. That&apos;s why creating accessible menu&apos;s should be part of every web developer&apos;s toolkit. In this post, I&apos;ll show you the CSS, JavaScript, HTML and ARIA attributes that you need to know to create accessible menus.</description><pubDate>Thu, 15 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;How most hidden Menus work&lt;/h2&gt;
&lt;p&gt;Most hidden menus work by using JavaScript to change the styles or toggle a class to show or hide a bunch of links.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    .menu-list {
    //hide menu
    }
    
    .menu--is-open .menu-list {
    // show menu
    }
    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;ve created a &lt;a href=&quot;https://codepen.io/nirjan_dev/pen/jOmbgxJ&quot;&gt;basic nav menu on codepen&lt;/a&gt;. You can use that to follow along with this post.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./accessible-menu-screenshot.webp&quot; alt=&quot;screenshot of a mobile menu&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Semantic HTML&lt;/h2&gt;
&lt;p&gt;Using good semantic HTML is essential to creating accessible sites. In my example, I&apos;ve wrapped the links in an unordered list. So, the screen reader can know how many links are there in the list.&lt;/p&gt;
&lt;p&gt;I&apos;ve wrapped the list in a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav&quot;&gt;nav tag&lt;/a&gt;. I&apos;ve then wrapped the nav tag in a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header&quot;&gt;header tag&lt;/a&gt;. I&apos;m also using a button to toggle the menu and not a span or a div. So, the user can focus on it by tabbing and use the button with just the keyboard. The menu button shouldn&apos;t be a link either because it won&apos;t link to anything.&lt;/p&gt;
&lt;p&gt;You should always try to find the correct HTML tag for your use-case, instead of just using divs or spans everywhere. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element&quot;&gt;The elements reference page on MDN&lt;/a&gt; is great for researching what tags to use where.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;header class=&quot;main-header&quot;&amp;gt;
      &amp;lt;a class=&quot;brand-logo&quot; href=&quot;/&quot;&amp;gt;NK Studio&amp;lt;/a&amp;gt;
     
      &amp;lt;nav class=&quot;main-nav&quot; id=&quot;primary-nav&quot;&amp;gt;
        &amp;lt;button class=&quot;menu-btn&quot;&amp;gt;
          Menu
          &amp;lt;i class=&quot;gg-menu menu-btn__icon&quot;&amp;gt;&amp;lt;/i&amp;gt;
        &amp;lt;/button&amp;gt;
        &amp;lt;ul class=&quot;main-nav__list&quot;&amp;gt;
          &amp;lt;li class=&quot;main-nav__list-item&quot;&amp;gt;
            &amp;lt;a class=&quot;main-nav__link&quot; href=&quot;#about&quot;&amp;gt;About&amp;lt;/a&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;li class=&quot;main-nav__list-item&quot;&amp;gt;
            &amp;lt;a class=&quot;main-nav__link&quot; href=&quot;#team&quot;&amp;gt;Team&amp;lt;/a&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;li class=&quot;main-nav__list-item&quot;&amp;gt;
            &amp;lt;a class=&quot;main-nav__link&quot;href=&quot;#portfolio&quot;&amp;gt;Portfolio&amp;lt;/a&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;li class=&quot;main-nav__list-item&quot;&amp;gt;
            &amp;lt;a class=&quot;main-nav__link&quot; href=&quot;#case-studies&quot;&amp;gt;Case studies&amp;lt;/a&amp;gt;
          &amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;  
      &amp;lt;/nav&amp;gt;
    &amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: I&apos;m placing the Menu button inside the nav tag. This is to ensure that the people who move to the nav tag using a shortcut won&apos;t just find a hidden list. They&apos;ll find the button to open the nav menu. You should also make sure that the focus order makes sense. Here the next item that is focusable after the menu button is the first link in the menu.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Hiding the menu&lt;/h2&gt;
&lt;p&gt;You need to make sure that the hidden menu is not accessible without opening it. You should use the display or visibility property to hide the menu. This makes sure that the hidden menu isn&apos;t focused when tabbing and aren&apos;t read by screen readers.&lt;/p&gt;
&lt;p&gt;Be careful if you&apos;re only using transforms, width, opacity or any other similar properties to hide the menu. Screen readers can still access them, and users can reach them by tabbing. So, you need to use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/display&quot;&gt;display&lt;/a&gt; or &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/visibility&quot;&gt;visibility&lt;/a&gt; property to hide the menu.&lt;/p&gt;
&lt;p&gt;In this example, I&apos;m using a high negative transformY value to hide the menu. So I need to use the visibility property to make sure the hidden nav is not accessible without opening it. You could also use the display property, but it can be bad for performance.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    .main-nav__list{
      // other styles
    
      transform: translateY(-999px);
      visibility: hidden;
    }
      
      
    .main-nav--is-open .main-nav__list {
      transform: translateY(0);
      visibility: visible;
    }
    
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Communicating Menu States&lt;/h2&gt;
&lt;p&gt;The next thing you need to do is make sure all the users of your site are aware of the menu&apos;s open and closed states. This is simple for sighted users as they can just see the menu open and close, but you also need to make sure any users with visual impairments can tell the current state of the menu.&lt;/p&gt;
&lt;p&gt;We need to add an aria-expanded attribute to the button. This informs the user about the current state of the button and lets them know we can open the menu using the button. We need to change the value of aria-expanded to true when it&apos;s open and to false when it&apos;s closed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;button class=&quot;menu-btn&quot; aria-expanded=&quot;false&quot;&amp;gt;
      Menu
      &amp;lt;i class=&quot;gg-menu menu-btn__icon&quot;&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    function toggleAriaExpanded() {
      const isExpanded = menuBtn.getAttribute(&apos;aria-expanded&apos;) === &apos;true&apos;;
      
      let newState;
      if (isExpanded) {
        newState = false;
      } else {
        newState = true;
      }
      menuBtn.setAttribute(&apos;aria-expanded&apos;, newState);
    }
    
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Adding Aria-controls&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://tink.uk/using-the-aria-controls-attribute/&quot;&gt;aria-controls attribute&lt;/a&gt; helps screen reader users navigate from a controlling element to a controlled element. But, it is only supported in the JAWS screen reader. So you simply can’t rely on it.&lt;/p&gt;
&lt;p&gt;The aria-controls attribute is still a nice to have feature for JAWS users and since it doesn&apos;t do much harm, we can choose to add it to our menu.&lt;/p&gt;
&lt;p&gt;We just need to add it to the menu button and set the value to the value of the ID for the menu.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;button class=&quot;menu-btn&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;nav-list&quot;&amp;gt;
      Menu
      &amp;lt;i class=&quot;gg-menu menu-btn__icon&quot;&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/button&amp;gt;
    &amp;lt;ul class=&quot;main-nav__list&quot; id=&quot;nav-list&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Where to go from here&lt;/h2&gt;
&lt;p&gt;If you follow all the tips mentioned in this post, then you should have a more accessible nav menu for your site. Make sure to test this using an actual screen reader.&lt;/p&gt;
&lt;p&gt;There are other types of menus that aren&apos;t used for site navigation. Instead, they&apos;re used for choosing options in an app. Take a look at Heydon Pickering&apos;s &lt;a href=&quot;https://inclusive-components.design/menus-menu-buttons/&quot;&gt;excellent guide to building inclusive menus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&apos;re using a hover menu, then it might be a good time to switch to click menus, as mentioned in &lt;a href=&quot;https://css-tricks.com/in-praise-of-the-unambiguous-click-menu/&quot;&gt;this post on csstricks.&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>accessibility</category><category>css</category><category>ux</category><author>Nirjan Khadka</author></item><item><title>Step by Step guide to CSS text truncate; different ways to truncate text with CSS</title><link>https://nirjan.dev/blog/step-by-step-guide-to-truncating-text-in-css-shorten-text-like-a-pro/</link><guid isPermaLink="true">https://nirjan.dev/blog/step-by-step-guide-to-truncating-text-in-css-shorten-text-like-a-pro/</guid><description>In this post, I&apos;ll show you how to implement a CSS text truncate. I will cover how to shorten both a single line and multiple lines. I&apos;ll also mention some common problems you may face when doing a CSS text truncate.</description><pubDate>Tue, 22 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Text Truncate in CSS&lt;/h2&gt;
&lt;p&gt;Truncated or shortened text is most common when you&apos;re working on a design with equal-height columns. But generally, the text for those columns is dynamic. I had to work on a design like that at work recently.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Row of articles using a card design that shows off CSS text truncate&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./card-layout-finished.webp&quot; alt=&quot;Row of articles using a card design that shows off CSS text truncate&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The category names like Mario, Nintendo, Call of Duty: Modern Warfare, etc need to be in a single line. If it doesn&apos;t fit, then I need to truncate it. I also need to truncate the title of the article to 4 lines. So, for this specific layout, I had to do CSS text truncate for both a single line and multiple lines.&lt;/p&gt;
&lt;h2&gt;How to do CSS text truncate?&lt;/h2&gt;
&lt;p&gt;Let&apos;s start off with a single line CSS text truncate with a “p” tag. You can follow along with me using this snippet. Here&apos;s the link to the &lt;a href=&quot;https://codepen.io/nirjan_dev/pen/GRWYQMr&quot;&gt;finished codepen&lt;/a&gt; if you want to copy it from there.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p class=&quot;single-truncate&quot;&amp;gt;
  Call of Duty: Modern Warfare
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* global styles */
body {
  min-height: 100vh;
  display: grid;
  place-items: center;
  gap: 0.8em;
  font-family: Arial,Helvetica Neue,Helvetica,sans-serif;
  font-size: 1.6rem;
}

p {
  background: tomato;
  padding: 1em;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./box-with-COD.webp&quot; alt=&quot;box with the text, Call of Duty: Modern Warfare&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here are the steps you need to follow to truncate this text.&lt;/p&gt;
&lt;h3&gt;1. Setting fixed width with CSS&lt;/h3&gt;
&lt;p&gt;You need to set a width on the element that you are targetting. So, the browser knows how long the text should be before you truncate it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* truncate stuff */
.single-truncate {
  width: 150px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./COD-box-stacked.webp&quot; alt=&quot;box with the text, Call of Duty: Modern Warfare&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2. Using the white-space property in CSS&lt;/h3&gt;
&lt;p&gt;To avoid wrapping the text to the next line, we need to set the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/white-space&quot;&gt;white-space property&lt;/a&gt; to nowrap.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.single-truncate {
  width: 150px;
  white-space: nowrap;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./COD-box-overflow.webp&quot; alt=&quot;Box with the text, Call of Duty: Modern Warfare, Modern Warfare is sticking outside the box&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. Using the overflow CSS property&lt;/h3&gt;
&lt;p&gt;Next, you need to set the overflow property to hidden. This hides the text when it goes beyond it&apos;s width.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.single-truncate {
  width: 150px;
  white-space: nowrap;
  overflow: hidden;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./COD-box-clipped.webp&quot; alt=&quot;Box with the text Call of Duty: Modern Warfare, Modern Warfare is clipped by the border and hidden&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4. CSS truncate with ellipsis&lt;/h3&gt;
&lt;p&gt;We have successfully truncated the text. But it would be nice to have some sort of indication that we have truncated it. Let&apos;s add ellipses to the end of the shortened text. We can do this by setting the text-overflow property to ellipsis.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.single-truncate {
  width: 150px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./COD-box-elipsis.webp&quot; alt=&quot;Box with the text Call of Duty: Modern Warfare, Modern Warfare is truncated&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All you need to remember is 4 CSS properties. Width, white-space, overflow, text-overflow or remember the acronym, &lt;strong&gt;WWOT&lt;/strong&gt;. You can use &quot;We Won&apos;t Overflow Text” as a mnemonic. You can probably come up with something better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;How do you truncate multiple lines with CSS?&lt;/h2&gt;
&lt;p&gt;Truncating text for multiple lines is a bit more tricky. Let&apos;s start with a simple “p” tag again, but with some more text this time and make it wider.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;p class=&quot;multiple-truncate&quot;&amp;gt;
    Nintendo E3 2021: Direct Dates and Time, Predictions, Rumours and Zelda Plans 
 &amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.multiple-truncate {
  width: 250px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./paragraph-box.webp&quot; alt=&quot;Box with an article title&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Right now, the text has 5 lines. Let&apos;s see if we can truncate it to just 4 lines.&lt;/p&gt;
&lt;h3&gt;How to use line clamp in CSS&lt;/h3&gt;
&lt;p&gt;This property only works if you set the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/display&quot;&gt;display&lt;/a&gt; property to -webkit-box or -webkit-inline-box. Also, the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/box-orient&quot;&gt;-webkit-box-orient&lt;/a&gt; property needs to be set to vertical.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This property was originally implemented in WebKit and has some issues. It got standardized for legacy support.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;When applied to anchor elements, the truncating can happen in the middle of the text, not necessarily at the end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, let&apos;s add the new rules to our multiple-truncate class and see what will happen.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  .multiple-truncate {
    width: 250px;

  /* truncates text   */
  -webkit-line-clamp: 4;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./paragraph-box-wip.webp&quot; alt=&quot;Box with an article title, ellipsis after the fourth line but the fifth line is also showing&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s not quite what we were looking for. The problem with this approach is that we won&apos;t be able to have a padding-bottom on the actual text. Otherwise, the space occupied by the bottom padding will show the truncated text. So, let&apos;s remove the bottom padding for now.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.multiple-truncate {
  width: 250px;
  
  /* truncates text   */
  -webkit-line-clamp: 4;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  padding-bottom: 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we need to hide the truncated text by setting the overflow to hidden.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.multiple-truncate {
  width: 250px; 

 /* truncates text   */
  -webkit-line-clamp: 4;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  padding-bottom: 0;
  overflow: hidden;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The downside to this approach is that you can&apos;t have a padding-bottom on the text. You would need to add your padding to the parent or try something else.&lt;/p&gt;
&lt;p&gt;One thing you can try is to set a border on an &quot;after&quot; pseudo-element. The border-color should be the same as the background for the text. Then, you need to set the border-width to the padding-bottom value you want. You can use an SCSS mixin or CSS variables for this to make it more robust and reusable.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.multiple-truncate:after {
  content: &apos;&apos;;
  display: block;
  border-bottom: 1em solid tomato;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./paragraph-box-finished.webp&quot; alt=&quot;box with an article title, truncated after 4 lines&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Truncate text with flexbox&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Truncating text like this doesn&apos;t work well if the element you&apos;re truncating has a display value of flex or inline-flex.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The text will still be shortened but you won&apos;t get the ellipsis at the end. I&apos;m not sure why it happens or if there are any workarounds for this. If you have any ideas, then let me know in the comments below.&lt;/p&gt;
&lt;h2&gt;Truncate text with SCSS&lt;/h2&gt;
&lt;p&gt;Here are two SCSS mixins that will make truncating text easier.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@mixin truncate-single-line($width) {
  width: $width;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@mixin truncate-multiple-lines($width, $lines, $paddingBottom: false, $bg) {
  width: $width;
  -webkit-line-clamp: $lines;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  padding-bottom: 0;
  
  @if $paddingBottom {
    &amp;amp;:after {
    content: &apos;&apos;;
    display: block;
      border-bottom-width: $paddingBottom;
      border-bottom-style: solid;
      border-bottom-color: $bg;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can even use CSS variables for the &lt;strong&gt;$paddingBottom&lt;/strong&gt; argument and then use media queries to make it responsive without changing the mixin.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.multiple-truncate--with-mixin {
  --pd: 1em;
 padding: var(--pd);
  @include truncate-multiple-lines($width: 250px, $lines: 4, $bg: tomato, $paddingBottom: var(--pd));
  
 @media (max-width: 600px) {
    --pd: 0.2em;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Summary on CSS truncate text&lt;/h2&gt;
&lt;p&gt;Here&apos;s a quick summary of how to do text truncation with CSS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Truncated or shortened text is commonly used in designs with equal-height columns where the text is dynamic.&lt;/li&gt;
&lt;li&gt;To truncate text in CSS, you can use the following steps:
&lt;ol&gt;
&lt;li&gt;Set a fixed width on the element you are targeting.&lt;/li&gt;
&lt;li&gt;Use the white-space property and set it to &apos;nowrap&apos; to avoid wrapping the text to the next line.&lt;/li&gt;
&lt;li&gt;Use the overflow property and set it to &apos;hidden&apos; to hide the text when it goes beyond its width.&lt;/li&gt;
&lt;li&gt;Use the text-overflow property and set it to &apos;ellipsis&apos; to add an indication that the text has been truncated.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Truncating text for multiple lines is more tricky, but can be done by setting a fixed height on the element, using the display property and setting it to &apos;-webkit-box&apos; and &apos;-webkit-line-clamp&apos; and setting the number of lines to be displayed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How has your experience been with truncating text in CSS? What techniques have you tried? Do you know any other ways to do this? Let me know in the comments below. I hope this was a helpful article.&lt;/p&gt;
</content:encoded><category>css</category><category>design</category><author>Nirjan Khadka</author></item><item><title>Tips for beginners learning to code</title><link>https://nirjan.dev/blog/tips-for-beginners-learning-to-code/</link><guid isPermaLink="true">https://nirjan.dev/blog/tips-for-beginners-learning-to-code/</guid><description>If you&apos;re new to coding then these tips might help you out. I&apos;ve listed some tips that I would have really benefited from when I was learning to code.</description><pubDate>Thu, 13 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s been a while since I started coding, So for this post, I decided to do something different. I want to list down some tips I&apos;ve learned over the last two years on getting better at learning to code. So this will be like a message to my younger self which might also hopefully be useful to some other beginners just starting out.&lt;/p&gt;
&lt;h2&gt;1. Build more cool stuff&lt;/h2&gt;
&lt;p&gt;I think this is the number one thing that can make it easier for you to learn something whether it&apos;s a programming language, framework or any other coding concept. Don&apos;t just go from one tutorial to another. Take what you&apos;ve learned and make something cool with it, Most of the time you will learn way more from building stuff than any tutorial will ever teach you.&lt;/p&gt;
&lt;p&gt;It can be normal to develop a mindset where you think what you&apos;ve learned so far is not enough and you can&apos;t possibly make anything useful from it. You will always want to know more and that&apos;s not a bad thing. But, I&apos;m gonna let you in a little secret,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No programmer on earth knows enough to always get the job done without any help, whether that help is a coworker, mentor or StackOverflow, Nobody knows enough, There&apos;s always more to learn whether you&apos;ve been coding for a month or 10 years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;2. Build apps that actually help you&lt;/h2&gt;
&lt;p&gt;If you agree with my first piece of advice and decide to build things then don&apos;t just build random things or some demo app that you saw being built in a tutorial instead identify a problem that you are facing in your day to day life, no matter how small that may seem and try to build a solution for that.&lt;/p&gt;
&lt;p&gt;For example, you might find it hard to focus or manage your time then build a simple time tracker, if you are having a hard time managing your money then build a budget tracker, etc. (note: Don&apos;t just build trackers, these are just examples) Doing this will make sure you are truly invested in the project and won&apos;t give up as soon as the project becomes a little difficult.&lt;/p&gt;
&lt;h2&gt;3. Don&apos;t build complex apps too fast&lt;/h2&gt;
&lt;p&gt;Sometimes it can be overwhelming to build apps that do too much. Instead, break your idea down into small pieces and focus on the most important part of your app and once that is complete then move onto other parts. You don&apos;t have to build a complex app just a simple app that solves one problem really well. I have gone down a rabbit hole where I kept adding features and eventually just gave up on the project because it was to complex for me to handle. Take it one step at a time and don&apos;t try to build something too complex.&lt;/p&gt;
&lt;h2&gt;4. Be a part of the community&lt;/h2&gt;
&lt;p&gt;Listen to coding podcasts, subscribe to coding channels, follow other developers online, be a part of the community. Don&apos;t just be a passive observer, share your thoughts, ask questions but don&apos;t be a dick.&lt;/p&gt;
&lt;h2&gt;5. Take a break&lt;/h2&gt;
&lt;p&gt;I think this is something that beginners tend to ignore. When you&apos;re learning something or working on a new project you might lose track of time or might spend hours trying to fix something. Remember to take a break from coding, do other stuff, focus on other interests to recharge your batteries. If you are interested in a sport or any other team activity then that can be great for your work-life balance since most developers spend a lot of time sitting and staring at a screen. Don&apos;t neglect your wellbeing because it&apos;s really easy to get burned out when you don&apos;t know your limits.&lt;/p&gt;
&lt;h2&gt;Other useful tips&lt;/h2&gt;
&lt;p&gt;There are tons of tips that I have for beginners but I consider the tips mentioned here to be the most helpful. You should be fine if you follow these tips but if you don&apos;t then you&apos;re never going to make it (just kidding, these are just suggestions, not rules). Take what you want from this post, it might be helpful for you or it might not but If I could go back in time then I would certainly give these tips to my past self. Here are some other tips that might be useful&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Share your journey online with others and document it&lt;/li&gt;
&lt;li&gt;Try a little bit of everything(different frameworks, coding - styles, etc), you&apos;d be surprised at what you find yourself enjoying the most&lt;/li&gt;
&lt;li&gt;Before trying everything make sure you master the fundamentals (please don&apos;t learn a JS framework before learning JS)&lt;/li&gt;
&lt;li&gt;Find different ways to tackle problems&lt;/li&gt;
&lt;li&gt;Always think critically before committing to something&lt;/li&gt;
&lt;li&gt;Always pick readability over clever code&lt;/li&gt;
&lt;li&gt;Don&apos;t use &lt;a href=&quot;https://dev.to/wuz/stop-trying-to-be-so-dry-instead-write-everything-twice-wet-5g33&quot;&gt;the DRY principle&lt;/a&gt; for everything&lt;/li&gt;
&lt;li&gt;Don&apos;t use &lt;a href=&quot;https://medium.com/@thisdotmedia/the-cost-of-premature-abstraction-b5d71ffd6400&quot;&gt;abstractions too early&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Take a look at the project from a larger scope&lt;/li&gt;
&lt;li&gt;Make sure most of the code you write is easily replaceable&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>learning</category><author>Nirjan Khadka</author></item><item><title>How to easily understand &quot;this&quot; in Javascript - with a simple visual chart</title><link>https://nirjan.dev/blog/understanding-this-in-javascript/</link><guid isPermaLink="true">https://nirjan.dev/blog/understanding-this-in-javascript/</guid><description>This post will help you figure out how you can easily find out the value of “this” in JavaScript. If you&apos;re in a hurry, there&apos;s a JavaScript this keyword cheat sheet at the end.</description><pubDate>Wed, 15 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post will help you figure out how you can easily find out the value of “this” in JavaScript. If you&apos;re in a hurry, there&apos;s a JavaScript this keyword cheat sheet at the end.&lt;/p&gt;
&lt;p&gt;The keyword &lt;strong&gt;“&lt;strong&gt;this&lt;/strong&gt;”&lt;/strong&gt; in JavaScript has confused a lot of developers, but with just 4 simple rules, you will never be confused again.&lt;/p&gt;
&lt;p&gt;First, you need to know one important thing when working with the “this” keyword -&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;this&lt;/strong&gt; is not author-time binding but runtime binding so it&apos;s not about where a function is declared but how it&apos;s called&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I talk about &lt;strong&gt;“this bindings”,&lt;/strong&gt; I simply mean, how the “this” keyword is given a value. In JavaScript, there are 4 different types of “this” bindings, and they have their own order of precedence. So here are the 4 different “this” bindings in ascending order of precedence.&lt;/p&gt;
&lt;h2&gt;How the “this” keyword works in JavaScript — Default Binding&lt;/h2&gt;
&lt;p&gt;Most of the function calls in your code will have the default binding. The value of this is bound to the global object (the window object when working with JavaScript in the browser). This happens when you call a function with just the function name and it&apos;s arguments within brackets.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: If the function is in strict mode, then by default &lt;strong&gt;“this”&lt;/strong&gt; refers to undefined. When working in a JavaScript module, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#strict_mode_for_modules&quot;&gt;strict mode is enabled automatically.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  this.a = 4;
  /**
   *   creates a global variable a
   *    this is the same as doing these things
   *    var a = 4;
   *    or window.a = 4;
   **/
}

foo();
console.log(a); // 4

function bar() {
  &quot;use strict&quot;;
  /**
   * since this is undefined in strict mode
   * the a variable cannot be set and it
   * results in an error
   */

  this.a = 6;
  console.log(a);
}
bar(); // TypeError: Cannot set property &apos;a&apos; of undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;What is the “this” keyword in a JavaScript class – Class Binding&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This type of binding happens when you call a function as a method of an object. The value of &lt;strong&gt;this&lt;/strong&gt; is the object itself.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj = {
  a: 4,
  foo: function() {
    console.log(this.a);
  }
};
obj.foo(); // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It does not matter where you declare the function, as long as you call it as a method of the object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

obj = {
  a: 7,
  foo: foo
};

obj.foo(); // 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only the top/last level of an object property reference chain matters.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}
const obj1 = {
  a: 4,
  foo: foo
};
const obj2 = {
  a: 7,
  obj1: obj1
};
obj2.obj1.foo(); // 4

/*
Here, obj2 is accessing it&apos;s obj1 property 
and then since, the obj1 property is an object itself, 
it calls it&apos;s own foo method,
which accesses the a variable set in the obj1 object so it logs the value 4.
*/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The most important thing to remember is that, it&apos;s not about the function itself. It&apos;s about how it is called. For example, here we call the foo function but since it is not called as a method of an object, we fall back to the default binding of “this”.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

const obj = {
  a: 7,
  foo: foo
};

/**
 *  only a reference to the actual function is assigned
 * it does not care about the implicit binding
 */
const bar = obj.foo;

var a = 11;

/**
 * here this refers to the window object because of
 * default binding
 **/
bar(); // 11
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;How to bind this in JavaScript – Explicit Binding with call and apply&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Most of the built-in functions and all user-defined functions have two special utility methods; apply and call. You can use these methods to explicitly bind the value of this. The value of “this” is easy to figure out because it is explicitly passed in as the first argument to the call or apply methods.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

const obj = {
  a: 4
};

/**
 * calls the foo function
 * where this is bound to the obj object
 */
foo.call(obj); // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: apply and call both works the same for explicitly binding “this” to a given value, but the way they &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply&quot;&gt;pass in other arguments is a little different&lt;/a&gt;. You may have also used the .bind() es6 method before which uses explicit binding under the hood, you can &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind&quot;&gt;read more about it here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;strong&gt;How this works in JavaScript with the new keyword – new binding&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To understand this type of binding, you need to understand how constructors work in JavaScript. In JavaScript, constructors are just functions that are called with the “new” operator in front of them. They are not attached to classes, nor are they instantiating a class. They are just regular functions hijacked by the use of the “new” keyword.&lt;/p&gt;
&lt;p&gt;Any user-defined or built-in function can be called with a “new” in front of it, and that makes it a construction call. There is no such thing as constructor functions, but rather construction calls of functions.&lt;/p&gt;
&lt;p&gt;These things happen when you make a construction call:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A brand-new object is created.&lt;/li&gt;
&lt;li&gt;The new object is prototype linked.&lt;/li&gt;
&lt;li&gt;The object is set as the “this” binding for the function call&lt;/li&gt;
&lt;li&gt;Unless the function returns its own alternate object, the new invoked function call will return the newly constructed object.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  this.a = 4;
}
const bar = new foo(); // bar is set to the newly created object;
console.log(bar.a); // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;How this works in an arrow function – Arrow function binding&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;I know I promised there were only 4 different types of &lt;strong&gt;“this”&lt;/strong&gt; binding and in the past, that was true, until es6 which introduced arrow functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 *  arrow functions use the fat arrow =&amp;gt;
 * instead of the function keyword.
 */

a =&amp;gt; {
  console.log(a);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Arrow functions are not just a quicker way to write functions, but they also do “this” binding a little different. They use &lt;strong&gt;lexical scope&lt;/strong&gt; for “this”. To learn more about lexical scope, check out my &lt;a href=&quot;https://nirjan.dev/blog/understanding-lexical-scope-and-closures-in-3-minutes&quot;&gt;guide to lexical scope and closure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;They inherit the value of &lt;strong&gt;“this”&lt;/strong&gt; from their outer function. By “outer function”, I mean the function where you declare the arrow function, not where you call them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  var = 3;
  return () =&amp;gt; {
    /**
     * here this actually refers to the
     * this of the foo function
     */

    console.log(this.a); // 3
  };
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s a more complicated example, that uses the other ways to bind “this” alongside the arrow function binding.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  return () =&amp;gt; {
    /**
     * here this actually refers to the
     * this of the foo function
     */

    console.log(this.a);
  };
}
const obj1 = {
  a: 4
};
const obj2 = {
  a: 7
};

/**
 * sets &quot;this&quot; binding to obj1 and
 * gets the arrow function as the return value
 * Now bar is a reference to the arrow function returned by the foo function
* */
const bar = foo.call(obj1);


/**
 * tries to set the this binding
 * of the arrow function to obj2 but
 * the arrow function&apos;s this is set
 * to the this of foo which was bound to obj1
 **/
bar.call(obj2); // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Therefore, the &lt;strong&gt;“this”&lt;/strong&gt; binding of arrow function is actually done in author-time rather than runtime like the other types of &lt;strong&gt;“this”&lt;/strong&gt; binding.&lt;/p&gt;
&lt;h2&gt;&quot;this&quot; in JavaScript Summary and Cheat sheet&lt;/h2&gt;
&lt;p&gt;Here are the things we now know about how &quot;this&quot; works in JavaScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &quot;this&quot; keyword in JavaScript is not author-time binding but runtime binding, meaning it&apos;s not about where a function is declared but how it&apos;s called&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are 4 different types of “this” bindings in JavaScript, each with its own order of precedence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Default Binding: the value of this is bound to the global object (the window object when working with JavaScript in the browser). If the function is in strict mode, then &quot;this&quot; refers to undefined.&lt;/li&gt;
&lt;li&gt;Class Binding: the value of this is the object itself when calling a function as a method of an object.&lt;/li&gt;
&lt;li&gt;Explicit Binding with call and apply: allows you to explicitly bind the value of this by passing the desired value as the first argument to the call or apply method.&lt;/li&gt;
&lt;li&gt;Implicit Binding: the value of this is the object that the function is a property of.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The most important thing to remember is that it&apos;s not about the function itself, it&apos;s about how it&apos;s called.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Arrow functions in JavaScript do not have their own &quot;this&quot; binding, they inherit the “this” value of the surrounding scope. This means that the value of &quot;this&quot; inside an arrow function will be the same as the value of &quot;this&quot; in the code that surrounds the arrow function.&lt;/p&gt;
&lt;p&gt;You can use this cheat sheet to help you find the value of &lt;strong&gt;“this”&lt;/strong&gt; in JavaScript. So, next time when it&apos;s hard to debug the value of” &lt;strong&gt;this”&lt;/strong&gt; just remain calm and ask yourself these questions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./this-JS-cheatsheet.png&quot; alt=&quot;Cheat sheet to figure out the value of &amp;quot;this&amp;quot; in JavaScript&quot; /&gt;&lt;/p&gt;
</content:encoded><category>javascript</category><author>Nirjan Khadka</author></item><item><title>Javascript Closures Complete Guide - with practical use cases and examples</title><link>https://nirjan.dev/blog/understanding-lexical-scope-and-closures-in-3-minutes/</link><guid isPermaLink="true">https://nirjan.dev/blog/understanding-lexical-scope-and-closures-in-3-minutes/</guid><description>In this post, I explain how JavaScript Closures work and what is Lexical Scope in JavaScript. In the end, I will also show you examples of JavaScript Closures. Having some previous knowledge about how JavaScript variables and functions work is necessary to continue on with this post.</description><pubDate>Thu, 21 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What is scope in JavaScript?&lt;/h2&gt;
&lt;p&gt;We first need to know what we mean by scope to understand a JavaScript Closure. Scope is a set of rules that tell you where your variables and functions can be accessed from.&lt;/p&gt;
&lt;p&gt;Depending on where you have set your variables and defined your functions, you can only access them in specific sections of your code. Here is an example of that in JavaScript.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const firstVariable = 1;


function firstFunction() {
    return 2;
}

function functionWithAnotherFunctionInside() {    
    const secondVariable = 2;
    
    function secondFunction() {
        return 3;
    }
}


// will log 1 2
console.log(firstVariable, firstFunction()) 

// Uncaught ReferenceError: secondVariable is not defined
console.log(secondVariable, secondFunction())
    ``` 

So what&apos;s the deal here? Why can can we access the _**firstVariable**_ and the **_firstFunction_** but not the **_secondVariable_** and the **_secondFunction_** ? This is because of how JavaScript Scope works.

How does Scope work in JavaScript
---------------------------------

JavaScript only had **function scope** (with a few exceptions) until the [ES6](https://www.programiz.com/javascript/ES6) version came out. This meant that, whenever you defined a new function, you created a new scope. A variable defined inside a function cannot be accessed from outside the function.

This is why we get an error when trying to log the secondVariable value and call the secondFunction.
```js
const firstVariable = 1;
]
function firstFunction() {
    return 2;
}

function functionWithAnotherFunctionInside() {    
    const secondVariable = 2;
    
    function secondFunction() {
        return 3;
    }
}


// will log 1 2
console.log(firstVariable, firstFunction()) 

// Uncaught ReferenceError: secondVariable is not defined
console.log(secondVariable, secondFunction()) 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Scope won&apos;t let you access the variables that are set inside a function from the outside.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./scope-access-functions-diagram.png&quot; alt=&quot;Diagram showing Function Scope in JavaScript&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;JavaScript Scopes are nested&lt;/h3&gt;
&lt;p&gt;The inner scope has access to the outer scope, but the outer scope can&apos;t access the variables set in the inner scope.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function outerFunction() {
  let i = 777;
  console.log(i); // 777
  console.log(b); // Refference Error (outer scope can&apos;t access variables in inner scope)

  function innerFunction() {
    console.log(i); // 777 (inner scope can access the enclosing outer scope)
    let b = &quot;hello&quot;;
  }

  innerFunction();
}
outerFunction();

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Scope consists of a series of bubbles that each act as a container or bucket in which identifiers are declared , these bubbles nest inside each other and this nesting is defined at author time.&lt;br /&gt;
&lt;a href=&quot;https://twitter.com/getify&quot;&gt;Kyle Simpson&lt;/a&gt; (Author of the &lt;a href=&quot;https://github.com/getify/You-Dont-Know-JS&quot;&gt;You Don&apos;t know JS series&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./scope-access-diagram.png&quot; alt=&quot;Diagram showing how the outer scope can&apos;t access the inner scope, but the inner scope can access the outer scope in JavaScript.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./scope-bubbling-diagram.png&quot; alt=&quot;Code example of JavaScript Scope being nested&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//global scope
var i = 666;
console.log(i); // 666

function foo() {
  // scope of foo
  var i = 777;
  console.log(i); // 777
}

foo();

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;How does JavaScript Scope work in ES6&lt;/h3&gt;
&lt;p&gt;ES6 introduced two new ways to declare variables; using let and const. They can be used for block scoping. Whenever you use let or const to declare variables, they are scoped to the block (any code surrounded by a pair of curly brackets). ES6 also introduced another scope with modules, but closures work in the same way in modules too, so we don&apos;t have to dive deep into that. If you are curious, here&apos;s the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&quot;&gt;MDN link to JavaScript modules&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//global scope
var i = 666;
console.log(i); // 666

{
  // new block scope
  // you&apos;l see these types of blocks used with if,else,for,while,etc
  let i = 777;
  console.log(i); // 777
}

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;note:&lt;/strong&gt; You might have heard the term &lt;strong&gt;lexical scope&lt;/strong&gt; in JavaScript which is just a technical term for scope that is defined during the code compilation process called lexing. It basically means that scope is defined when you are writing the code (declaring functions, or blocks), instead of when it is actually executed by the computer.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;What is a Closure?&lt;/h2&gt;
&lt;p&gt;A closure is a programming technique for allowing functions to access values that are defined outside of it. It is the combination of a function bundled together with variables that are outside of it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You have a closure when a function accesses variables defined outside of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./scope-bubbling-diagram.png&quot; alt=&quot;Visual example of a closure&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;What are JavaScript Closures?&lt;/h2&gt;
&lt;p&gt;In JavaScript, because scope is nested, it is actually pretty easy to create a closure.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let usernames = [&apos;John&apos;, &apos;Jack&apos;, &apos;James&apos;, &apos;Jhonny&apos;];
let searchTerm = &apos;Ja&apos;;

// Here the function is accessing the searchTerm variable which is outside the function
// this is a closure
let filteredUsernames = usersnames.filter(function (username) { 
    return username.startsWith(searchTerm)
  });

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since, functions can be nested, you can also use closures with nested functions like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function outerFunction() {
  let a = 666;
  function innerFunction() {
    console.log(a);
  }
  return innerFunction;
}
let myFunc = foo(); // now myFunc is just a reference to innerFunction inside the outerFunction.

myFunc(); // 666;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the outer function runs, the &apos;a&apos; variable is set to 666. So, You might expect the &apos;a&apos; variable to not be available afterwards when the function has finished running.&lt;/p&gt;
&lt;p&gt;Since scope can be nested, the inner function still has access to the &apos;a&apos; variable. So, as long as some part of the code can still call the inner function, it can still remember the &apos;a&apos; variable.&lt;/p&gt;
&lt;p&gt;Closures can cause functions to remember variables within their scope.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With a Closure, you are combining a function with the data that it can access outside of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Examples of JavaScript Closures&lt;/h2&gt;
&lt;p&gt;Closures are useful to combine a function with some internal value that it should use. This might be familiar if you have some experience with &lt;a href=&quot;https://press.rebus.community/programmingfundamentals/chapter/encapsulation/&quot;&gt;object-oriented programming and encapsulation&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getClickCountUpdater() {
  let counter = 0;
  return function() {
    counter = counter + 1;
    console.log(counter);
  };
}

const updateClickCounter = getClickCountUpdater();

// now to change the counter, you need to use this function, you can&apos;t change it directly
updateClickCounter(); // 1;
updateClickCounter(); // 2;

counter = counter+1; // ReferenceError: counter is not defined
console.log(counter); // ReferenceError: counter is not defined

// You can create another count updater function which will have a seprate counter variable in it&apos;s scope
const anotherCounter = getClickCounUpdater();
anotherCounter(); // 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can also be useful for creating different variations of a function, and to keep track of some value inside a function that shouldn&apos;t be changed from anywhere else. This is pretty useful when you want to do some logging for a specific function like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createAd(width, height) {
  let adCounter = 0;
  return function (link) {
    adCounter++;
    console.log(`${width}x${height} ad created ${adCounter} times!`);
    return {
      _type: &apos;ad&apos;,
      link: link,
      width: width,
      height: height,
      // other generic ad options
    }
  }
}

const create300x250Ad = createAd(300, 250);
const create728x90Ad = createAd(720, 90);

// 300x250 ad created 1 times!
const new300x250Ad = create300x250Ad(&apos;https://linkToTheAd.com/path&apos;);

// 300x250 ad created 2 times!
const another300x250Ad = create300x250Ad(&apos;https://linkToTheAd.com/path&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;What is the benefit of closure in JavaScript?&lt;/h2&gt;
&lt;p&gt;JavaScript Closures can also be used to do some performance optimization. Let&apos;s say you have a function that needs to set a variable, but that variable takes up a lot of memory. Instead of creating that variable each time you run the function, you could use a closure to reuse it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function findAdLinkById(id) {
  const adMap = {
    &apos;e645-2456&apos;: &apos;https://link.com/path&apos;,
    &apos;2282-3238&apos;: &apos;https://another-link.com/another-path&apos;,
    // 1000 more items
    
    &apos;2901-2192&apos;: &apos;https://one-more-link.com/path&apos;
  }
  return adMap[id]
} 

// whenever this function gets called it needs to store a new adMap value in memory which makes calling this function slower the more we call it
const firstAd = findAdLinkById(&apos;e645-2456&apos;)
const secondAd = findAdLinkById(&apos;2282-3238&apos;)
const thirdAd = findAdLinkById(&apos;2901-2192
function createFindAdLinkById() {
  const adMap = {
    &apos;e645-2456&apos;: &apos;https://link.com/path&apos;,
    &apos;2282-3238&apos;: &apos;https://another-link.com/another-path&apos;,
    // 1000 more items
    
    &apos;2901-2192&apos;: &apos;https://one-more-link.com/path&apos;
  }
  return (id) =&amp;gt; adMap[id]
} 
const findAdLinkById = createFindAdLinkById()

// whenever this function gets called it reuses the same adMap value which makes it faster to run
const firstAd = findAdLinkById(&apos;e645-2456&apos;)
const secondAd = findAdLinkById(&apos;2282-3238&apos;)
const thirdAd = findAdLinkById(&apos;2901-2192&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: while this will be more performant, it will also use more memory. So, if you also need to optimize the memory consumption then you should try something else.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the most common use cases of JavaScript Closures is with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous&quot;&gt;asynchronous JavaScript&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let id = 1;

getUserFromAPI(id).then(response =&amp;gt; {
  // this works because the function callback here can still remember the value of the id even though this code won&apos;t run immediately
  console.log(`Fetched user ID: ${id}`)
})

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of the time, you might not even realize when you&apos;re using a closure. Basically, anytime you&apos;re using a variable that is outside a function from inside the function, you are using a closure.&lt;/p&gt;
&lt;p&gt;So, These are some practical use cases for JavaScript Closures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Limiting the access to certain variables&lt;/li&gt;
&lt;li&gt;Limiting the access to call certain functions&lt;/li&gt;
&lt;li&gt;Keeping track of values across function calls&lt;/li&gt;
&lt;li&gt;Logging function calls&lt;/li&gt;
&lt;li&gt;Optimizing the memory usage of function calls&lt;/li&gt;
&lt;li&gt;Creating different variations of the same function&lt;/li&gt;
&lt;li&gt;Remembering values with asynchronous functions that get executed later&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Closures can cause performance issues&lt;/h2&gt;
&lt;p&gt;While closures can be pretty useful when you use them intentionally. Sometimes they can also lead to memory issues, because closures are stored in memory. If we create unnecessary closures frequently, then it can cause a memory leak.&lt;/p&gt;
&lt;p&gt;We need to make sure we&apos;re actually using the variables that are being stored in the memory. We should not create unnecessary closures too much. Let&apos;s take a look at our example from earlier to see how closures can cause too much memory usage.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createFindAdLinkById() {
  const adMap = {
    &apos;e645-2456&apos;: &apos;https://link.com/path&apos;,
    &apos;2282-3238&apos;: &apos;https://another-link.com/another-path&apos;,
    // 1000 more items
    
    &apos;2901-2192&apos;: &apos;https://one-more-link.com/path&apos;
  }
  return (id) =&amp;gt; adMap[id]
} 


// now instead of having just one closure, we have 2000 closures
for (let i = 0; i &amp;lt;= 2000; i++) {
  const findAdLinkById = createFindAdLinkById()
  const firstAd = findAdLinkById(&apos;e645-2456&apos;)
  const secondAd = findAdLinkById(&apos;2282-3238&apos;)
  const thirdAd = findAdLinkById(&apos;2901-2192&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, Whenever you are creating closures, you need to be aware of how much memory you are actually using.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./closure-memory-diagram.png&quot; alt=&quot;Closures live in the heap memory instead of the call stack&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Summary of JavaScript Closures&lt;/h2&gt;
&lt;p&gt;I hope you now have a better understanding of JavaScript Closures. Here&apos;s what was covered in this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scope is a set of rules that determine where variables and functions can be accessed in code.&lt;/li&gt;
&lt;li&gt;Until ES6, only function scope was available in JavaScript, meaning variables defined within a function could not be accessed from outside.&lt;/li&gt;
&lt;li&gt;ES6 introduced block scoping with the “let” and “const” keywords.&lt;/li&gt;
&lt;li&gt;JavaScript&apos;s scope is nested, with inner scopes having access to outer scopes but not vice versa.&lt;/li&gt;
&lt;li&gt;“Lexical scope” refers to scope that is defined during the code compilation process, rather than when the code is executed.&lt;/li&gt;
&lt;li&gt;Closures are functions that have access to variables in their parent scope even after the parent function has returned.&lt;/li&gt;
&lt;li&gt;Closure allows a function to remember the environment in which it was created, even after it leaves that environment.&lt;/li&gt;
&lt;li&gt;Closures can be used to create private variables and methods, by returning inner function from outer function.&lt;/li&gt;
&lt;li&gt;Closures can also be used to make performance optimizations.&lt;/li&gt;
&lt;li&gt;You should use closures carefully if you want to make your apps more memory efficient.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>javascript</category><author>Nirjan Khadka</author></item></channel></rss>