<?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: Sanket Jagtap</title>
    <description>The latest articles on DEV Community by Sanket Jagtap (@sanketjagtap1).</description>
    <link>https://dev.to/sanketjagtap1</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4056696%2F8eeb8804-a896-4744-89cd-362011d69e45.png</url>
      <title>DEV Community: Sanket Jagtap</title>
      <link>https://dev.to/sanketjagtap1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanketjagtap1"/>
    <language>en</language>
    <item>
      <title>How Much Does a Website Cost in India? (2026 Pricing Guide)</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Fri, 31 Jul 2026 14:48:50 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/how-much-does-a-website-cost-in-india-2026-pricing-guide-3f2o</link>
      <guid>https://dev.to/sanketjagtap1/how-much-does-a-website-cost-in-india-2026-pricing-guide-3f2o</guid>
      <description>&lt;p&gt;"How much will my website cost?" is the first question every client asks — and most answers online are either vague or written by agencies with something to sell. Here are real numbers, based on what I actually charge and what I see across the Indian freelance market in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic website (3–5 pages):&lt;/strong&gt; ₹10,000 – ₹25,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professional business website (CMS, animations, admin panel):&lt;/strong&gt; ₹25,000 – ₹60,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full-stack web application (auth, database, payments, dashboards):&lt;/strong&gt; ₹50,000 – ₹2,00,000+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hourly work (fixes, features, consulting):&lt;/strong&gt; ₹500 – ₹1,500/hour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For reference, my own packages start at &lt;strong&gt;₹15,000&lt;/strong&gt; for a basic website and &lt;strong&gt;₹800/hour&lt;/strong&gt; for ad-hoc work — you can see the full breakdown on my &lt;a href="https://dev.to/services"&gt;services page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually drives the price
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Number of unique page designs
&lt;/h3&gt;

&lt;p&gt;A 3-page site where every page shares one layout is cheap. Ten pages with distinct designs is not. Most of the cost is design and content work, not code.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Custom functionality
&lt;/h3&gt;

&lt;p&gt;The moment you need logins, payments, bookings, or an admin panel, you've crossed from "website" into "web application" — the engineering effort roughly triples. A contact form is trivial; a customer dashboard is not.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Content management
&lt;/h3&gt;

&lt;p&gt;If you want to edit content yourself, you need a CMS or admin panel. That adds cost up front but saves you paying a developer for every text change later. For most businesses it pays for itself within a year.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Who you hire
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freelancer (direct):&lt;/strong&gt; best value — you pay for the work, not office overhead. ₹15k–₹60k for most business sites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small agency:&lt;/strong&gt; ₹60k–₹3L for the same scope. You're paying for project managers and margins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website builders (Wix/WordPress templates):&lt;/strong&gt; ₹0–₹10k, but you'll fight the template, load slowly, and rank poorly. Fine for a hobby; risky for a business.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Costs people forget
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain:&lt;/strong&gt; ₹800–₹1,500/year&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; ₹1,500–₹8,000/year for most sites (a small VPS runs several sites comfortably)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSL:&lt;/strong&gt; free with Let's Encrypt — never pay for basic SSL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance:&lt;/strong&gt; budget a small monthly retainer if your site changes often&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Red flags when comparing quotes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quotes with no scope in writing ("website: ₹40,000") — you'll pay for every change later&lt;/li&gt;
&lt;li&gt;No mention of mobile responsiveness or page speed — in 2026 both are table stakes&lt;/li&gt;
&lt;li&gt;"SEO included" with no specifics — real SEO is structured data, performance, and content, not a checkbox&lt;/li&gt;
&lt;li&gt;You don't get the source code or hosting access — you should own what you pay for&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I price projects
&lt;/h2&gt;

&lt;p&gt;I quote a fixed price against a written scope: pages, features, timeline, and what's included (responsive design, SEO basics, deployment). Anything outside scope is discussed before it's built — no surprise invoices. If you're planning a website or web app and want a real number for your specific case, &lt;a href="https://dev.to/contact"&gt;tell me what you're building&lt;/a&gt; — I reply within a day with an honest estimate, no obligation.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>pricing</category>
      <category>freelance</category>
      <category>india</category>
    </item>
    <item>
      <title>How to Hire a Freelance Full-Stack Developer in India (Without Getting Burned)</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Fri, 31 Jul 2026 14:48:50 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/how-to-hire-a-freelance-full-stack-developer-in-india-without-getting-burned-1pea</link>
      <guid>https://dev.to/sanketjagtap1/how-to-hire-a-freelance-full-stack-developer-in-india-without-getting-burned-1pea</guid>
      <description>&lt;p&gt;Hiring a freelance developer is a leap of trust: you're handing your idea, your money and your timeline to someone you found on the internet. I'm a &lt;a href="https://dev.to/"&gt;freelance full-stack developer&lt;/a&gt; myself, so consider this the checklist I'd want my own clients to use — including the questions that would make a bad freelancer uncomfortable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "full-stack" should actually mean
&lt;/h2&gt;

&lt;p&gt;A genuine full-stack developer can take your project from empty folder to live product: front-end (Angular/React), back-end APIs (Node.js and similar), database design, and deployment to a real server. If a candidate can only do one side, you'll end up hiring twice and paying for the coordination overhead yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fair rates in India (2026)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Junior (0–2 yrs):&lt;/strong&gt; ₹300–₹600/hour — fine for simple sites with supervision&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mid-level (2–5 yrs):&lt;/strong&gt; ₹600–₹1,200/hour — the sweet spot for most business projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Senior (5+ yrs):&lt;/strong&gt; ₹1,200–₹2,500/hour — worth it for complex systems and architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suspiciously cheap quotes usually mean the work is subcontracted, rushed, or will quietly die at 80% complete. The most expensive project is the one you pay for twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 7-point vetting checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Live products, not just screenshots.&lt;/strong&gt; Ask for URLs you can click and apps you can install. A portfolio of images proves nothing about deployment skills.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real employment or client history.&lt;/strong&gt; Cross-check LinkedIn. Someone who has shipped inside companies (banks, product firms) has survived code reviews and deadlines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask "what would you build this with, and why?"&lt;/strong&gt; A good developer explains trade-offs in plain language. A bad one hides behind jargon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Written scope before money.&lt;/strong&gt; Pages, features, milestones, timeline, and what happens when scope changes. If they resist writing it down, walk away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Milestone payments.&lt;/strong&gt; 30–40% to start, the rest tied to demos you can actually click. Never 100% up front.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You own the code.&lt;/strong&gt; Repository access under your account, hosting credentials in your name, and a handover clause. Non-negotiable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication rhythm.&lt;/strong&gt; Agree on update frequency (I send progress updates at least weekly). Silence is how projects die.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where to find good freelancers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Referrals&lt;/strong&gt; — still the highest hit rate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio sites + a real conversation&lt;/strong&gt; — a developer who writes about their work (blog, GitHub, case studies) is showing you how they think before you pay them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketplaces (Upwork, Contra)&lt;/strong&gt; — workable, but reviews measure politeness more than engineering quality; still run the checklist above&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Red flags that predict failure
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"Yes" to every requirement without a single clarifying question&lt;/li&gt;
&lt;li&gt;No questions about &lt;em&gt;why&lt;/em&gt; you're building it — features without purpose become rework&lt;/li&gt;
&lt;li&gt;Won't do a short intro call&lt;/li&gt;
&lt;li&gt;Can't explain their own past projects in detail (they may not have built them)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ready to talk to one?
&lt;/h2&gt;

&lt;p&gt;I'm Sanket — a full-stack developer with 4+ years of experience across enterprise finance portals, real-time trading platforms and mobile apps, based in Pune and working with clients everywhere. My &lt;a href="https://dev.to/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://dev.to/services"&gt;pricing&lt;/a&gt; and &lt;a href="https://dev.to/contact"&gt;contact form&lt;/a&gt; are all public — run this very checklist on me. That's exactly the kind of scrutiny a good freelancer should welcome.&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>freelance</category>
      <category>fullstack</category>
      <category>india</category>
    </item>
    <item>
      <title>Deploying a Full-Stack App with Docker and Nginx on a VPS</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Mon, 22 Jun 2026 16:57:25 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/deploying-a-full-stack-app-with-docker-and-nginx-on-a-vps-1710</link>
      <guid>https://dev.to/sanketjagtap1/deploying-a-full-stack-app-with-docker-and-nginx-on-a-vps-1710</guid>
      <description>&lt;p&gt;You do not need Kubernetes to ship a real app. A single VPS with Nginx and Docker handles a surprising amount of traffic. Here is the setup that runs this portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  The topology
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nginx is the front door, terminating SSL and serving the built Angular app as static files.&lt;/li&gt;
&lt;li&gt;The Node + Prisma API runs in a Docker container on a private port (6000).&lt;/li&gt;
&lt;li&gt;MySQL is the database; uploaded images live on a persistent host volume.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nginx as the front door
&lt;/h2&gt;

&lt;p&gt;One server block does three jobs: serve the SPA with a history-API fallback, reverse-proxy the API, and serve uploaded files. The detail that bites everyone is the &lt;strong&gt;trailing slash on proxy_pass&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:6000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# no trailing slash -&amp;gt; keeps /api prefix&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# SPA fallback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a trailing slash Nginx strips the matched prefix, so /api/users would arrive at the backend as /users and 404. Dropping the slash preserves the path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistent uploads
&lt;/h2&gt;

&lt;p&gt;Anything written inside a container is gone on the next deploy. Uploads must live on the host and be mounted in, with ownership that matches the container user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 6000:6000 &lt;span class="nt"&gt;--env-file&lt;/span&gt; .env &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /opt/app/uploads:/opt/app/uploads &lt;span class="se"&gt;\&lt;/span&gt;
  portfolio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SSL
&lt;/h2&gt;

&lt;p&gt;Let's Encrypt via certbot gives free, auto-renewing certificates. Nginx redirects all HTTP to HTTPS, so the app is TLS-only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploys
&lt;/h2&gt;

&lt;p&gt;The flow is pleasantly boring: pull the latest code, &lt;strong&gt;docker build&lt;/strong&gt; , stop the old container, run the new one. Because migrations run on startup and uploads live outside the container, a redeploy is safe and repeatable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas worth remembering
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;proxy_pass trailing slash changes the forwarded path — choose deliberately.&lt;/li&gt;
&lt;li&gt;A non-root container user cannot write to a root-owned host volume; fix the ownership.&lt;/li&gt;
&lt;li&gt;An existing database needs its migrations baselined once (P3005) before migrate deploy will run.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>devops</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Building BeatNest: A Cross-Platform Music App in Flutter</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Mon, 22 Jun 2026 16:57:25 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/building-beatnest-a-cross-platform-music-app-in-flutter-4ei</link>
      <guid>https://dev.to/sanketjagtap1/building-beatnest-a-cross-platform-music-app-in-flutter-4ei</guid>
      <description>&lt;p&gt;BeatNest is a cross-platform music streaming app built with Flutter. It streams tracks from the Saavn API and focuses on the things that actually make a music player feel good: &lt;strong&gt;gapless background playback&lt;/strong&gt; , media-style notifications, lock-screen controls and offline listening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Flutter
&lt;/h2&gt;

&lt;p&gt;One codebase, two stores. Flutter let me ship a consistent UI on Android and iOS while still dropping down to native APIs where it mattered — the media session, notifications and storage permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The app follows a clean, service-oriented structure so the UI stays dumb and the logic stays testable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ApiService&lt;/strong&gt; — talks to the Saavn API for search and trending songs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MusicService&lt;/strong&gt; — the playback brain: queue, current track, play/pause/seek, exposed as reactive streams with rxdart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AudioHandler&lt;/strong&gt; — the background audio service that survives the app being backgrounded.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background playback
&lt;/h2&gt;

&lt;p&gt;This is where most music apps fall apart. BeatNest combines &lt;strong&gt;just_audio&lt;/strong&gt; for the player with &lt;strong&gt;audio_service&lt;/strong&gt; for the OS-level media session. That gives you a notification with controls, lock-screen artwork, and playback that keeps going when the app is swiped away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;just_audio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.10.5&lt;/span&gt;
  &lt;span class="na"&gt;audio_service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.18.12&lt;/span&gt;
  &lt;span class="na"&gt;audio_session&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.2.3&lt;/span&gt;
  &lt;span class="na"&gt;rxdart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.28.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Auth and cloud sync
&lt;/h2&gt;

&lt;p&gt;Users can continue as a guest or sign in with email or Google via &lt;strong&gt;Firebase Auth&lt;/strong&gt;. Signing in syncs their liked songs and playlists across devices through Cloud Firestore, so the library follows the user, not the phone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Offline and resilience
&lt;/h2&gt;

&lt;p&gt;Downloads use &lt;strong&gt;dio&lt;/strong&gt; with a local SQLite index so songs are available without a connection, and &lt;strong&gt;connectivity_plus&lt;/strong&gt; gracefully degrades the UI when the network drops. Crashes and usage are tracked with Firebase Crashlytics and Analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat the audio session as the source of truth — the UI should reflect it, never drive it directly.&lt;/li&gt;
&lt;li&gt;Background execution rules differ a lot between Android and iOS; test on real devices early.&lt;/li&gt;
&lt;li&gt;A "Continue as guest" path removes friction and still lets you upsell sync later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BeatNest started as an experiment in "can Flutter really do a proper media app?" The answer turned out to be a confident yes.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>mobile</category>
      <category>music</category>
    </item>
    <item>
      <title>Making a Node.js and Prisma API Production-Ready</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Mon, 22 Jun 2026 16:57:25 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/making-a-nodejs-and-prisma-api-production-ready-5gh8</link>
      <guid>https://dev.to/sanketjagtap1/making-a-nodejs-and-prisma-api-production-ready-5gh8</guid>
      <description>&lt;p&gt;"It works on my machine" and "it is production-ready" are very different statements. Here is the checklist I worked through to take an Express + Prisma + MySQL API from the first to the second — using this very portfolio backend as the guinea pig.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Real migrations, not db push
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;prisma db push&lt;/strong&gt; is great for prototyping and dangerous in production — there is no history and no safe rollback. The fix is committed migrations applied on deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma migrate dev &lt;span class="nt"&gt;--name&lt;/span&gt; init &lt;span class="c"&gt;# generate + commit&lt;/span&gt;
npx prisma migrate deploy &lt;span class="c"&gt;# run on startup (never prompts)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the database already has tables but no migration history you will hit &lt;strong&gt;P3005&lt;/strong&gt;. Baseline it once by marking the migration as already applied, then deploys are clean forever after.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Graceful shutdown
&lt;/h2&gt;

&lt;p&gt;Containers get SIGTERM on every redeploy. Without handling it you drop in-flight requests and leak database connections. Close the server, then disconnect Prisma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGTERM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Map errors to real status codes
&lt;/h2&gt;

&lt;p&gt;A blanket 500 tells the client nothing. A small helper maps known Prisma errors — unique violation to &lt;strong&gt;409&lt;/strong&gt; , record-not-found to &lt;strong&gt;404&lt;/strong&gt; — and keeps the raw error server-side only.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Liveness vs readiness
&lt;/h2&gt;

&lt;p&gt;Two different questions. &lt;strong&gt;/health&lt;/strong&gt; answers "is the process up?" cheaply. &lt;strong&gt;/health/ready&lt;/strong&gt; answers "can I serve traffic?" by actually pinging the database with SELECT 1 — that is what your load balancer should probe.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Config and secrets
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fail fast at startup if a required secret like JWT_SECRET is missing.&lt;/li&gt;
&lt;li&gt;Never ship a hardcoded admin password — seed a random one and print it once.&lt;/li&gt;
&lt;li&gt;Keep .env out of git; commit a .env.example template instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. A lean Docker image
&lt;/h2&gt;

&lt;p&gt;A multi-stage build compiles TypeScript in a builder stage and ships only the runtime deps and compiled output, running as a non-root user. Migrations run as the first thing the container does on boot.&lt;/p&gt;

&lt;p&gt;None of this is exciting, and that is the point. Production-ready means boring, predictable and observable.&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>prisma</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Inside AlgoETF: An Algorithmic ETF Trading Platform</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Mon, 22 Jun 2026 16:57:25 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/inside-algoetf-an-algorithmic-etf-trading-platform-3ep7</link>
      <guid>https://dev.to/sanketjagtap1/inside-algoetf-an-algorithmic-etf-trading-platform-3ep7</guid>
      <description>&lt;p&gt;AlgoETF is an algorithmic trading platform for Indian ETFs. It runs rule-based strategies against live market data, places orders through connected brokers, and lets you research everything with a built-in backtester before risking real money.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core strategy
&lt;/h2&gt;

&lt;p&gt;At its heart is a simple, explainable idea: &lt;strong&gt;buy the dip, sell the rise&lt;/strong&gt; , gated by momentum. The engine watches each ETF and acts when price moves a configured percentage, but only when the &lt;strong&gt;RSI(14)&lt;/strong&gt; filter agrees — so it avoids buying into a falling knife or selling into strength.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buy on dip and sell on rise thresholds, per ETF.&lt;/li&gt;
&lt;li&gt;RSI oversold / overbought gate to filter bad entries.&lt;/li&gt;
&lt;li&gt;Cycle targets so each position has a defined exit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-time architecture
&lt;/h2&gt;

&lt;p&gt;The frontend is Angular; the backend is Node.js + Express. Live prices and order updates stream over &lt;strong&gt;WebSockets&lt;/strong&gt; , &lt;strong&gt;Redis&lt;/strong&gt; handles pub/sub and hot state, and &lt;strong&gt;MySQL&lt;/strong&gt; is the system of record for strategies, cycles and orders. Broker APIs sit behind an adapter layer so new brokers can be added without touching the strategy code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The backtester
&lt;/h2&gt;

&lt;p&gt;You can replay historical 1-minute data through the exact same strategy logic — research only, no orders placed. The best part is the &lt;strong&gt;A/B improvement rules&lt;/strong&gt; : toggle a stop-loss, cap averaging, an EMA trend filter, a volume filter or a trailing exit, and compare the result against the base strategy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parameters: stock, date range, buy dip %, sell rise %
Gate: RSI period, oversold &amp;lt;, overbought &amp;gt;
Risk: qty/order, start capital, brokerage %, slippage %
A/B rules: stop loss, cap averaging, EMA filter, trailing exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Safety first
&lt;/h2&gt;

&lt;p&gt;Trading code is unforgiving, so the platform separates &lt;strong&gt;live&lt;/strong&gt; , &lt;strong&gt;paper&lt;/strong&gt; and &lt;strong&gt;backtest&lt;/strong&gt; modes explicitly. Paper trading mirrors live behaviour with no money at stake, and every order is logged with a clear success / pending / failed status.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make strategies boring and explainable — you have to trust them with money.&lt;/li&gt;
&lt;li&gt;Backtesting and live execution must share the same code path, or your results lie.&lt;/li&gt;
&lt;li&gt;An audit trail of every order is not optional in fintech.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>node</category>
      <category>trading</category>
      <category>websockets</category>
    </item>
    <item>
      <title>Angular Beyond the Docs: What 4+ Years of Production Code Taught Me</title>
      <dc:creator>Sanket Jagtap</dc:creator>
      <pubDate>Wed, 17 Jun 2026 16:54:24 +0000</pubDate>
      <link>https://dev.to/sanketjagtap1/angular-beyond-the-docs-what-4-years-of-production-code-taught-me-96o</link>
      <guid>https://dev.to/sanketjagtap1/angular-beyond-the-docs-what-4-years-of-production-code-taught-me-96o</guid>
      <description>&lt;h1&gt;
  
  
  Angular Beyond the Docs: What 4+ Years of Production Code Taught Me
&lt;/h1&gt;

&lt;p&gt;Most Angular blogs explain what a feature does.&lt;/p&gt;

&lt;p&gt;Very few talk about &lt;strong&gt;when it hurts, when it helps, and when not to use it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After more than &lt;strong&gt;4 years of building Angular applications in production&lt;/strong&gt; , I’ve learned that the hardest problems were never about syntax or APIs — they were about &lt;strong&gt;decisions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This post is for developers who already know Angular and want to &lt;strong&gt;think more clearly while building real systems&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem Was Never Angular — It Was Over-Abstraction
&lt;/h2&gt;

&lt;p&gt;Early in my career, I believed:&lt;/p&gt;

&lt;p&gt;More architecture means better code.&lt;/p&gt;

&lt;p&gt;So I built:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;1. Deep folder hierarchies&lt;/li&gt;
&lt;li&gt;2. Over-generic services&lt;/li&gt;
&lt;li&gt;“Shared” modules that depended on everything&lt;/li&gt;
&lt;li&gt;Reusable components that were rarely reused&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result wasn’t scalability — it was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Slower development&lt;/li&gt;
&lt;li&gt;Harder onboarding&lt;/li&gt;
&lt;li&gt;Fear of touching existing code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Modern Angular didn’t just introduce new features — it &lt;strong&gt;removed the need for unnecessary structure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Simplicity scales better than cleverness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signals Didn’t Replace RxJS — They Replaced Misuse of RxJS
&lt;/h2&gt;

&lt;p&gt;Signals are often described as &lt;em&gt;“Angular without RxJS.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s not accurate.&lt;/p&gt;

&lt;p&gt;RxJS was never the real problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using RxJS for synchronous UI state was.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What went wrong in real projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Observables for button state&lt;/li&gt;
&lt;li&gt;Subscriptions inside components&lt;/li&gt;
&lt;li&gt;Boilerplate like &lt;code&gt;takeUntil(destroy$)&lt;/code&gt; everywhere&lt;/li&gt;
&lt;li&gt;UI bugs caused by async timing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What signals fixed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;UI state became synchronous again&lt;/li&gt;
&lt;li&gt;No subscriptions&lt;/li&gt;
&lt;li&gt;No memory-leak anxiety&lt;/li&gt;
&lt;li&gt;Predictable rendering&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Signals didn’t replace RxJS — they rescued it from being overused.&lt;/p&gt;

&lt;p&gt;Today my rule is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Signals → UI and local state&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RxJS → async streams (HTTP, WebSockets)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Change Detection Wasn’t Slow — Our Mental Model Was
&lt;/h2&gt;

&lt;p&gt;For years, Angular performance advice felt like magic spells:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;OnPush&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;trackBy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid functions in templates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We followed rules without understanding &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Signals changed this by making change detection &lt;strong&gt;explicit&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Angular updates only what reads a signal&lt;/li&gt;
&lt;li&gt;Not the whole component tree&lt;/li&gt;
&lt;li&gt;Not “everything just in case”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Performance improves when the framework matches how developers think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standalone Components Solved a Human Problem
&lt;/h2&gt;

&lt;p&gt;NgModules worked — but they created &lt;strong&gt;cognitive overhead&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where is this provided?&lt;/li&gt;
&lt;li&gt;Why is this imported here?&lt;/li&gt;
&lt;li&gt;Which module owns this component?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Standalone components didn’t just reduce code.&lt;/p&gt;

&lt;p&gt;They reduced &lt;strong&gt;questions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Developers can now open a file and understand it without tracing imports across multiple modules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best abstractions are the ones you don’t have to explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management Is a Cost — Not a Feature
&lt;/h2&gt;

&lt;p&gt;NgRx is powerful.&lt;/p&gt;

&lt;p&gt;It’s also expensive.&lt;/p&gt;

&lt;p&gt;In production, I’ve seen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simple apps buried under actions and reducers&lt;/li&gt;
&lt;li&gt;Teams afraid to touch state logic&lt;/li&gt;
&lt;li&gt;Bugs hidden behind boilerplate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Signals enabled something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Local state that stays local.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My approach today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with signals&lt;/li&gt;
&lt;li&gt;Introduce heavier state management &lt;strong&gt;only when complexity demands it&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;State management should grow with the problem — not ahead of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Biggest Angular Upgrade Is Restraint
&lt;/h2&gt;

&lt;p&gt;Modern Angular gives us:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Signals&lt;/li&gt;
&lt;li&gt;Standalone APIs&lt;/li&gt;
&lt;li&gt;Deferrable views&lt;/li&gt;
&lt;li&gt;Better performance tools&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But the real upgrade isn’t knowing more APIs.&lt;/p&gt;

&lt;p&gt;It’s knowing &lt;strong&gt;when not to use them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I now ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this abstraction reduce thinking?&lt;/li&gt;
&lt;li&gt;Will this still make sense in two years?&lt;/li&gt;
&lt;li&gt;Can someone else debug this easily?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Senior Angular development is about clarity, not cleverness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Angular today is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Faster&lt;/li&gt;
&lt;li&gt;Simpler&lt;/li&gt;
&lt;li&gt;More predictable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But frameworks don’t make applications maintainable — &lt;strong&gt;decisions do&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best code is the one that survives change — not the one that impresses today.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>angular</category>
      <category>frontendengineering</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
