<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sandip Gyawali</title>
    <description>The latest articles on DEV Community by Sandip Gyawali (@sand1p_gyawa1i).</description>
    <link>https://dev.to/sand1p_gyawa1i</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3339268%2F41c2908f-626d-4f80-9ca5-0a690d9e89e7.webp</url>
      <title>DEV Community: Sandip Gyawali</title>
      <link>https://dev.to/sand1p_gyawa1i</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sand1p_gyawa1i"/>
    <language>en</language>
    <item>
      <title>Why I Switched from VSCode to NeoVim (and Why You Might Too)</title>
      <dc:creator>Sandip Gyawali</dc:creator>
      <pubDate>Fri, 11 Jul 2025 03:14:00 +0000</pubDate>
      <link>https://dev.to/sand1p_gyawa1i/why-i-switched-from-vscode-to-neovim-and-why-you-might-too-2p58</link>
      <guid>https://dev.to/sand1p_gyawa1i/why-i-switched-from-vscode-to-neovim-and-why-you-might-too-2p58</guid>
      <description>&lt;p&gt;I used VSCode from the beginning of my career — for about 4 to 5 years. It had everything I needed: themes, a polished GUI, and a vast extension ecosystem. But over time, it started to feel... slow and clunky. I found myself wanting more control, less bloat, and something more lightweight — maybe even a bit more experimental than VSCode. That’s when NeoVim entered the picture. At the same time, I had also been using Linux (Fedora with the i3 window manager) for a while, which naturally pushed me toward more minimal, keyboard-driven tools.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vqd86x8o76dw283aobl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vqd86x8o76dw283aobl.gif" alt="Cat Typing" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, I dismissed it. Terminal based? Vim Keybindings? Manual plugin setup? I was scared. But after watching a few videos and references, I decided to give it a shot. What followed was a week-long rabbit hole of configuration, key mapping, plugin exploration — and eventually, a workflow that made VSCode feel sluggish and noisy in comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Made Me Switch
&lt;/h2&gt;

&lt;p&gt;Here’s what drew me in:&lt;/p&gt;

&lt;p&gt;⚡ Speed: NeoVim launches almost instantly. No Electron overhead, no lags.&lt;br&gt;
⌨️ Modal editing: At first weird, but now addictive. I rarely touch my mouse anymore.&lt;br&gt;
🔌 Full control: With Lua-based configs and plugin managers like Lazy.nvim, I could tailor everything to my liking.&lt;br&gt;
🎯 Focus: Working in the terminal eliminated distractions. It’s just me and the code.&lt;/p&gt;

&lt;p&gt;It felt like i was superior and god with some divine power.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrdt1a0oy2z6u9pujfde.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrdt1a0oy2z6u9pujfde.gif" alt="God" width="398" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My tmux and Neovim Setup:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7oo0z2busifqus1k55lm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7oo0z2busifqus1k55lm.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6za30fzdh8gg07m49lor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6za30fzdh8gg07m49lor.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plugin Manager: Lazy.nvim — fast and declarative.&lt;br&gt;
Theme &amp;amp; UI: Catppuccin&lt;br&gt;
lualine.nvim for a clean, themed statusline.&lt;br&gt;
bufferline.nvim to navigate between open files easily.&lt;br&gt;
neo-tree.nvim as my file explorer with icons, git status, and fuzzy finding.&lt;br&gt;
Telescope for everything else — searching files, buffers, and more.&lt;br&gt;
mason.nvim to manage language servers and formatters.&lt;br&gt;
nvim-lspconfig for TypeScript, Lua, and more.&lt;br&gt;
none-ls (formerly null-ls) to run formatters like prettier and linters like eslint_d.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some of the Performance Changes that i Noticed over VsCode.
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;VSCode&lt;/th&gt;
&lt;th&gt;NeoVim&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Interface&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Graphical, mouse-driven&lt;/td&gt;
&lt;td&gt;Terminal-based, keyboard-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can be slow and resource-heavy&lt;/td&gt;
&lt;td&gt;Lightweight and extremely fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Customization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited to GUI settings and JSON configs&lt;/td&gt;
&lt;td&gt;Fully scriptable and deeply customizable via Lua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plugin Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy one-click installs via Marketplace&lt;/td&gt;
&lt;td&gt;More control, but manual setup via GitHub plugins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Editing Workflow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Traditional typing with optional Vim extension&lt;/td&gt;
&lt;td&gt;Native modal editing for speed and precision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Beginner-friendly, works out of the box&lt;/td&gt;
&lt;td&gt;Steep at first, but highly rewarding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4nvei14uxc1i4ryt3kju.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4nvei14uxc1i4ryt3kju.gif" alt=" " width="393" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources That Helped Me
&lt;/h2&gt;

&lt;p&gt;If you’re curious, here’s what helped me dive in:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Library&lt;/strong&gt;: &lt;a href="https://github.com/nvim-lua/kickstart.nvim" rel="noopener noreferrer"&gt;https://github.com/nvim-lua/kickstart.nvim&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;LazyVim&lt;/strong&gt;: &lt;a href="https://www.lazyvim.org/" rel="noopener noreferrer"&gt;https://www.lazyvim.org/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Youtube&lt;/strong&gt;: &lt;a href="https://www.youtube.com/watch?v=m8C0Cq9Uv9o&amp;amp;t=516s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=m8C0Cq9Uv9o&amp;amp;t=516s&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Switching to NeoVim felt like stepping out of my comfort zone — and into complete control. I don’t think everyone needs to make the switch, but if you’re frustrated with the performance or limitations of VSCode, NeoVim is worth exploring. It's lean, powerful, and once you get used to modal editing, it’s genuinely hard to go back.&lt;/p&gt;

&lt;p&gt;Have you tried NeoVim or thinking of switching? I’d love to hear your experience in the comments!  &lt;/p&gt;

&lt;p&gt;If you liked this post, follow me on &lt;a href="https://dev.to/sand1p_gyawa1i"&gt;Dev.to&lt;/a&gt;, &lt;a href="http://github.com/SandipGyawali" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, or &lt;a href="https://www.linkedin.com/in/sandip-gyawali-615681211/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; — I’ll be sharing more tips as I go deeper into NeoVim and terminal-based dev workflows.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>neovim</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Writing Scalable Express.js Backends with the Dependency Inversion Principle.</title>
      <dc:creator>Sandip Gyawali</dc:creator>
      <pubDate>Wed, 09 Jul 2025 15:13:27 +0000</pubDate>
      <link>https://dev.to/sand1p_gyawa1i/writing-scalable-expressjs-backends-with-the-dependency-inversion-principle-59i0</link>
      <guid>https://dev.to/sand1p_gyawa1i/writing-scalable-expressjs-backends-with-the-dependency-inversion-principle-59i0</guid>
      <description>&lt;p&gt;In this article, I’ll explore how the Dependency Inversion Principle (DIP) can be applied to build efficient and scalable Node.js backend systems.&lt;/p&gt;

&lt;p&gt;Recently, I set out to write a clean and maintainable Express.js backend using the MVC (Model-View-Controller) architecture, incorporating some of the SOLID principles along the way. During that process, I stumbled upon the Dependency Inversion Principle and realized how powerful it can be—especially when working with unopinionated frameworks like Express.js.&lt;/p&gt;

&lt;p&gt;In this post, I’ll break down what Dependency Inversion is, how it fits into the architecture of a Node.js backend, and how it can help us write more modular, testable, and flexible code.&lt;/p&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;

&lt;p&gt;First initialize the package.json in the file as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir express-di-project &amp;amp;&amp;amp; npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you have node and npm installed in your system.&lt;/p&gt;

&lt;p&gt;Install the packages and dependencies required for the Application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install tsyringe typedi express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After Installing we get the package.json file as &lt;br&gt;
follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name": "express-di-project",
    "version": "1.0.0",
    "description": "A Node Server",
    "keywords": [
        "js",
        "ts",
        "typescript",
        "javascript",
        "express",
        "node"
    ],
    "type": "module",
    "scripts": {
    },
    "dependencies": {
        "express": "^5.1.0",
        "tsyringe": "^4.10.0",
        "typedi": "^0.10.0"
    },
    "devDependencies": {
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up-to this step the step and configuration part has been completed. Now we focus on the modules that can be used to implement the Dependency Inversion Principle.&lt;/p&gt;

&lt;p&gt;Add the tsyringe and typedi modules to the &lt;strong&gt;helpers/helpers.di.js&lt;/strong&gt; file in the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// dependency injection modules
import {
  autoInjectable,
  inject,
  injectAll,
  container,
  registry,
} from "tsyringe";
export { Service as Model, Container as Context } from "typedi";
export { Router } from "express";

export const Container = container;
export const Service = autoInjectable;
export const Controller = autoInjectable;
export const Injectable = autoInjectable;
export const Route = autoInjectable;
export const Inject = inject;
export const InjectAll = injectAll;
export const Module = registry;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here,&lt;br&gt;
1.Service / Injectable / Controller / Route&lt;br&gt;
→ All are aliases for autoInjectable from tsyringe.&lt;br&gt;
Automatically injects dependencies into the constructor of a class.&lt;br&gt;
No need to manually register or resolve them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable()
class UserService {
  constructor(private repo: UserRepo) {}
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Inject&lt;br&gt;
→ Used to manually inject a specific token or dependency into the constructor.&lt;br&gt;
Useful when the type can't be inferred (e.g., interfaces or custom tokens).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(@Inject("CustomRepo") repo: IRepository) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.InjectAll&lt;br&gt;
→ Injects all registered instances matching a token.&lt;br&gt;
Great for plugin systems or processing chains.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(@InjectAll("Handlers") private handlers: Handler[]) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Module&lt;br&gt;
→ Alias for registry from tsyringe.&lt;br&gt;
Registers a group of classes or instances for DI in one go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Module([
  { token: "UserRepo", useClass: UserRepository },
  { token: "Logger", useValue: console },
])
class AppModule {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Container
→ The global tsyringe container instance.
Manages all registered dependencies.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Container.resolve(UserService); // Manual resolution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a brief understanding of the modules we go for the implementation section.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We divide implementation in 3 parts:

&lt;ol&gt;
&lt;li&gt;Defining a class with a service/auto-Injectable.&lt;/li&gt;
&lt;li&gt;Using the defined class as a injection for the other class.&lt;/li&gt;
&lt;li&gt;storing the instances in the registry and managing through the container/state.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 1:&lt;br&gt;
-&amp;gt; Define a class/service-class and add the decorators to the class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Service } from "../helpers/helper.di.ts";

@Service()
export class PingService {
  constructor() {}

  async ping() {
    const metaData: Record&amp;lt;string, unknown&amp;gt; = {
      message: "Server Connected",
      status: HttpStatusCode.OK,
    };

    return metaData;
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2:&lt;br&gt;
-&amp;gt; Using the Service() instance as the dependency in the other class. Here, we inject the class so that during the run time the application pulls the instance from the container/state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import type { Request, Response } from "express";
import { PingService } from "../services/service.ping.ts";
import { Controller, Inject } from "~/helpers/helper.di.ts";
import { catchAsync } from "../middlewares/catch-async.ts";

@Controller()
export class PingController {
  constructor(@Inject("PingService") private service: PingService) {}

  public ping = catchAsync(async (req: Request, res: Response) =&amp;gt; {
    const response = await this.service.ping();
    res.status(200).json(response);
  });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3:&lt;br&gt;
-&amp;gt; Defining a module which acts as a registry for the application in the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { PingController } from "../controllers/ping.controller.ts";
import { Inject, Injectable, Module } from "../helpers/helper.di.ts";
import { PingService } from "../services/service.ping.ts";

@Module([
  {
    token: "PingService",
    useClass: PingService,
  },
  {
    token: "PingController",
    useClass: PingController,
  },
])
@Injectable()
export class PingModule {
  constructor(@Inject("PingRoute") public route: PingRoute) {}
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, Using the instance of the services and controllers via the container/state in the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "reflect-metadata";
import express, { Router, type Application } from "express";
import { Container, Injectable } from "./helpers/helper.di.ts";

@Injectable()
class App {
  private app: Application;

  constructor() {
    this.app = express();
    this.main();
  }

  private main(): void {
    this.middlewares();
    this.config();
    this.routes();
  }

  private config(): void {
    this.app.disable("x-powered-by");
  }

  private middlewares() {
    this.app.use(express.json());
    this.app.use(
      express.urlencoded({
        extended: true,
      })
    );
  }

  private routes(): void {
    this.app.use("/ping", Container.resolve&amp;lt;Router&amp;gt;("PingModule"));

  public listen() {
    this.app.listen(3000, (err) =&amp;gt; {
      if (err) {
        process.exit(1);
      }
      console.log(`Listening to the server ${3000}`);
    });
  }
}

(function () {
  Container.resolve&amp;lt;App&amp;gt;(App).listen();
})();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the container is the state from which we are getting the singleton instance of the controller, module and services.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR;
&lt;/h2&gt;

&lt;p&gt;So, By this approach we a implement scalable architecture in the nodejs/expressjs application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;p&gt;If you enjoyed this post and would like to stay updated, feel free to connect.&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/SandipGyawali" rel="noopener noreferrer"&gt;https://github.com/SandipGyawali&lt;/a&gt;&lt;br&gt;
LinkedIn: &lt;a href="https://www.linkedin.com/in/sandip-gyawali-615681211/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/sandip-gyawali-615681211/&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://x.com/SandipGyawali3" rel="noopener noreferrer"&gt;https://x.com/SandipGyawali3&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>architecture</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
