<?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: Anshul Jangale</title>
    <description>The latest articles on DEV Community by Anshul Jangale (@anshul_02).</description>
    <link>https://dev.to/anshul_02</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%2F2949416%2Ffd4711e4-ad89-4266-a8aa-a716fac4e8aa.png</url>
      <title>DEV Community: Anshul Jangale</title>
      <link>https://dev.to/anshul_02</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anshul_02"/>
    <language>en</language>
    <item>
      <title>PySpark : The Big Brain of Data Processing</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Tue, 31 Mar 2026 08:46:01 +0000</pubDate>
      <link>https://dev.to/anshul_02/pyspark-the-big-brain-of-data-processing-10pn</link>
      <guid>https://dev.to/anshul_02/pyspark-the-big-brain-of-data-processing-10pn</guid>
      <description>&lt;p&gt;Imagine you run a restaurant. On a quiet Tuesday, one chef can handle everything — take the order, cook the food, plate it, done. Easy.&lt;/p&gt;

&lt;p&gt;Now imagine it's New Year's Eve and 500 people walk in at once. One chef? Absolute chaos. You need a full kitchen team — multiple chefs working on different dishes at the same time, coordinated, fast, efficient.&lt;/p&gt;

&lt;p&gt;That's the difference between regular data tools and &lt;strong&gt;PySpark&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Even Is PySpark?
&lt;/h2&gt;

&lt;p&gt;PySpark is a tool built for processing &lt;strong&gt;huge amounts of data&lt;/strong&gt; — we're talking millions of rows, gigabytes, even terabytes of information — quickly and efficiently.&lt;/p&gt;

&lt;p&gt;The "Spark" part is the engine (Apache Spark), one of the most powerful data processing engines ever built. The "Py" part means you use it with Python, one of the most popular programming languages in the world.&lt;/p&gt;

&lt;p&gt;Together? A seriously powerful combination.&lt;/p&gt;

&lt;p&gt;But here's the key thing that makes Spark special — it doesn't do the work on one machine. It &lt;strong&gt;splits the work across many machines&lt;/strong&gt; (or many cores of the same machine) and does everything at the same time. Just like that kitchen full of chefs — everyone working in parallel, no one waiting around.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does This Even Matter?
&lt;/h2&gt;

&lt;p&gt;Because data has gotten absolutely enormous.&lt;/p&gt;

&lt;p&gt;Ten years ago, a "big" dataset might be a few thousand rows in a spreadsheet. Today, companies are dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Millions of customer transactions every single day&lt;/li&gt;
&lt;li&gt;Billions of social media interactions&lt;/li&gt;
&lt;li&gt;Sensor data streaming in every millisecond from thousands of devices&lt;/li&gt;
&lt;li&gt;Logs from applications that never sleep&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A regular tool chokes on this. PySpark eats it for breakfast.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Is It Different from Other Tools?
&lt;/h2&gt;

&lt;p&gt;Let's put PySpark up against the competition.&lt;/p&gt;




&lt;h3&gt;
  
  
  PySpark vs Excel / Google Sheets
&lt;/h3&gt;

&lt;p&gt;This one's almost unfair.&lt;/p&gt;

&lt;p&gt;Excel is brilliant for what it does — budgets, small reports, a few thousand rows. But try opening a 10 million row file in Excel. It either crashes or takes five minutes just to scroll. Excel is the corner shop. PySpark is the warehouse.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Excel / Sheets&lt;/th&gt;
&lt;th&gt;PySpark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Max rows (practical)&lt;/td&gt;
&lt;td&gt;~1 million&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed on big data&lt;/td&gt;
&lt;td&gt;Crashes&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runs on multiple machines&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Excel is for humans reading data. PySpark is for machines processing data at scale.&lt;/p&gt;




&lt;h3&gt;
  
  
  PySpark vs Pandas (Python)
&lt;/h3&gt;

&lt;p&gt;Pandas is the most popular data tool among Python developers — and it's genuinely excellent. For datasets that fit on your laptop, pandas is fast, flexible, and friendly.&lt;/p&gt;

&lt;p&gt;The problem? It only runs on &lt;strong&gt;one machine&lt;/strong&gt;, and everything has to fit in &lt;strong&gt;RAM&lt;/strong&gt; (your computer's short-term memory). Run out of RAM and the whole thing crashes.&lt;/p&gt;

&lt;p&gt;PySpark solves exactly this. Same concepts, same feel, but now your data is spread across a cluster of machines with combined memory and processing power.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Pandas&lt;/th&gt;
&lt;th&gt;PySpark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data size limit&lt;/td&gt;
&lt;td&gt;Your RAM (~16–32 GB)&lt;/td&gt;
&lt;td&gt;Petabytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed on small data&lt;/td&gt;
&lt;td&gt;Faster&lt;/td&gt;
&lt;td&gt;Slightly slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed on big data&lt;/td&gt;
&lt;td&gt;Crashes&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runs distributed&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Pandas is your everyday car. PySpark is the truck when you need to move something massive.&lt;/p&gt;




&lt;h3&gt;
  
  
  PySpark vs SQL (Traditional Databases)
&lt;/h3&gt;

&lt;p&gt;SQL databases like MySQL or PostgreSQL are the backbone of most applications. They're great at storing data and answering questions — "show me all orders from last month", that kind of thing.&lt;/p&gt;

&lt;p&gt;But traditional SQL databases are designed to run on &lt;strong&gt;one server&lt;/strong&gt;. When data gets huge, they slow down. You can throw better hardware at the problem, but there's a hard limit.&lt;/p&gt;

&lt;p&gt;PySpark can actually run SQL queries too — but it runs them &lt;strong&gt;across a cluster&lt;/strong&gt;, making it far faster for large-scale analytical work. And it can read from almost any source: databases, files, data lakes, cloud storage.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Traditional SQL DB&lt;/th&gt;
&lt;th&gt;PySpark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Storing + querying app data&lt;/td&gt;
&lt;td&gt;Analysing massive datasets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scales to&lt;/td&gt;
&lt;td&gt;One powerful server&lt;/td&gt;
&lt;td&gt;Hundreds of machines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handles files (CSV, JSON)&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Natively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming data&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Built-in support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; SQL databases are where your data lives. PySpark is how you analyse it at scale.&lt;/p&gt;




&lt;h3&gt;
  
  
  PySpark vs Hadoop (MapReduce)
&lt;/h3&gt;

&lt;p&gt;This is PySpark's actual origin story. Before Spark, the king of big data was &lt;strong&gt;Hadoop MapReduce&lt;/strong&gt;. It also processed data across multiple machines — but in a very old-fashioned way.&lt;/p&gt;

&lt;p&gt;Hadoop read data from disk, processed a bit, wrote back to disk, read it again, processed more, wrote again. Every single step meant reading and writing to disk, which is painfully slow.&lt;/p&gt;

&lt;p&gt;Spark changed everything by keeping data &lt;strong&gt;in memory&lt;/strong&gt; (RAM) as much as possible. Processing happens in RAM, results stay in RAM until you actually need them saved. The result? Spark is typically &lt;strong&gt;10 to 100 times faster&lt;/strong&gt; than Hadoop for the same job.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Hadoop MapReduce&lt;/th&gt;
&lt;th&gt;PySpark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Processing location&lt;/td&gt;
&lt;td&gt;Disk (slow)&lt;/td&gt;
&lt;td&gt;Memory (fast)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;10–100x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ease of use&lt;/td&gt;
&lt;td&gt;Complex, verbose&lt;/td&gt;
&lt;td&gt;Much simpler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time processing&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Still widely used?&lt;/td&gt;
&lt;td&gt;Fading&lt;/td&gt;
&lt;td&gt;Growing fast&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Hadoop was the pioneer. Spark made it obsolete for most use cases.&lt;/p&gt;




&lt;h3&gt;
  
  
  PySpark vs Snowflake / BigQuery (Cloud Data Warehouses)
&lt;/h3&gt;

&lt;p&gt;These are the shiny modern tools — cloud-based, managed, very polished. You write SQL, they handle everything else. No servers to manage, no clusters to configure.&lt;/p&gt;

&lt;p&gt;So why would anyone use PySpark instead?&lt;/p&gt;

&lt;p&gt;Because PySpark gives you &lt;strong&gt;full control&lt;/strong&gt;. You can write custom logic, build complex pipelines, process any kind of data (not just structured tables), and integrate deeply with machine learning tools. Snowflake and BigQuery are amazing for querying structured data. PySpark is better when you need to transform, enrich, or build pipelines with complex custom logic.&lt;/p&gt;

&lt;p&gt;Many companies actually use both — Snowflake or BigQuery for storage and querying, PySpark for the heavy transformation work that feeds into them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Snowflake / BigQuery&lt;/th&gt;
&lt;th&gt;PySpark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ease of setup&lt;/td&gt;
&lt;td&gt;Very easy (fully managed)&lt;/td&gt;
&lt;td&gt;Needs configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom logic&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Machine learning&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Deep integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Cloud warehouses are convenient. PySpark is powerful. Often used together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Does PySpark Actually Run?
&lt;/h2&gt;

&lt;p&gt;PySpark isn't something you just install on your laptop. It runs on platforms built for scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Databricks&lt;/strong&gt; — the most popular platform, built by the creators of Spark itself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Fabric&lt;/strong&gt; — Microsoft's modern data platform with Spark built in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EMR&lt;/strong&gt; — AWS's managed Spark service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Dataproc&lt;/strong&gt; — Google Cloud's version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Synapse&lt;/strong&gt; — another Microsoft option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These platforms give you a cluster of machines ready to go — you just write the code and hit run.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should You Use PySpark?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use it when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data is too big for a normal laptop or server&lt;/li&gt;
&lt;li&gt;You need to process data fast — time is money&lt;/li&gt;
&lt;li&gt;You're building pipelines that run automatically on a schedule&lt;/li&gt;
&lt;li&gt;You're combining data from many different sources&lt;/li&gt;
&lt;li&gt;You're doing machine learning on large datasets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't bother when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a small dataset (pandas is simpler and faster for this)&lt;/li&gt;
&lt;li&gt;You need a quick one-off analysis (just use SQL or Excel)&lt;/li&gt;
&lt;li&gt;Your team doesn't have the skills yet (there's a real learning curve)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;PySpark exists because data outgrew the tools that came before it. One machine, one processor, one chunk of RAM — simply not enough anymore.&lt;/p&gt;

&lt;p&gt;Spark took the idea of "what if many machines worked together on the same problem?" and turned it into one of the most widely used data tools in the world. PySpark put Python on top of that, making all that power accessible to millions of developers.&lt;/p&gt;

&lt;p&gt;It's not the right tool for every job. But when you have a serious data problem — the kind that makes regular tools give up and go home — PySpark is the one you call.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Apache Spark was originally created at UC Berkeley in 2009. Today it's used by thousands of companies including Netflix, Uber, Airbnb, and NASA.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>data</category>
      <category>pyspark</category>
      <category>bigdata</category>
      <category>performance</category>
    </item>
    <item>
      <title>Lakehouse or Warehouse : Which one to choose ?</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Sat, 21 Feb 2026 17:03:47 +0000</pubDate>
      <link>https://dev.to/anshul_02/lakehouse-or-warehouse-which-one-to-choose-in-fabric--356k</link>
      <guid>https://dev.to/anshul_02/lakehouse-or-warehouse-which-one-to-choose-in-fabric--356k</guid>
      <description>&lt;h1&gt;
  
  
  Core Concepts
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Data Warehouse
&lt;/h2&gt;

&lt;p&gt;A centralized repository for &lt;strong&gt;cleaned, integrated, structured data&lt;/strong&gt; from multiple sources, using &lt;strong&gt;schema-on-write&lt;/strong&gt; and optimized for SQL analytics and BI.&lt;/p&gt;

&lt;p&gt;It emphasizes strong data quality, conformed dimensions, historical tracking, and tight governance, typically using ETL or ELT pipelines to transform data before loading.&lt;/p&gt;




&lt;h2&gt;
  
  
  Data Lakehouse
&lt;/h2&gt;

&lt;p&gt;An architecture that builds on a &lt;strong&gt;data lake&lt;/strong&gt; (object storage) but adds &lt;strong&gt;warehouse-like capabilities&lt;/strong&gt;—ACID transactions, schema enforcement, indexing, and SQL query performance—over open table formats like Delta, Iceberg, or Hudi.&lt;/p&gt;

&lt;p&gt;It supports &lt;strong&gt;structured, semi-structured, and unstructured&lt;/strong&gt; data in one platform, enabling both BI and AI/ML workloads without separate lake + warehouse stacks.&lt;/p&gt;




&lt;h1&gt;
  
  
  Architectural Differences
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Storage &amp;amp; Schema
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stores data in &lt;strong&gt;relational structures&lt;/strong&gt; (tables, columns, indexes) using schema-on-write—data is conformed to a fixed schema before it’s stored.&lt;/li&gt;
&lt;li&gt;Often uses proprietary or tightly controlled storage engines tuned for OLAP and star schemas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lakehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stores data in &lt;strong&gt;open formats&lt;/strong&gt; (e.g., Parquet + Delta/Iceberg/Hudi) on object storage, with both schema-on-write and schema-on-read patterns.&lt;/li&gt;
&lt;li&gt;Can ingest raw files (CSV, JSON, images, logs) and later layer schemas and table definitions on top for analytics.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Compute &amp;amp; Query Engine
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses a tightly integrated SQL engine optimized for analytic workloads (columnar storage, vectorized execution, cost-based optimizer).&lt;/li&gt;
&lt;li&gt;Often separates compute/storage logically in cloud warehouses but still exposes a single “data warehouse engine” entry point.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lakehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Typically supports &lt;strong&gt;multiple engines&lt;/strong&gt; over the same data: Spark, SQL engines, ML frameworks, streaming engines.&lt;/li&gt;
&lt;li&gt;The same Delta/Iceberg tables can be queried by BI tools and used directly in ML or streaming pipelines.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Data Types &amp;amp; Workloads
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Primarily &lt;strong&gt;structured, relational&lt;/strong&gt; data from OLTP systems, ERP/CRM, etc.&lt;/li&gt;
&lt;li&gt;Optimized for &lt;strong&gt;BI, dashboards, regulatory and financial reporting&lt;/strong&gt;, ad-hoc SQL analytics by analysts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lakehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Handles &lt;strong&gt;structured, semi-structured (JSON, logs), and unstructured&lt;/strong&gt; data (images, audio, documents) in one place.&lt;/li&gt;
&lt;li&gt;Designed for &lt;strong&gt;mixed workloads&lt;/strong&gt;: BI, data science, ML feature engineering, real-time/streaming, and advanced analytics.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Governance &amp;amp; Reliability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong, centralized governance with &lt;strong&gt;RBAC, fixed schemas, data quality rules, and lineage&lt;/strong&gt; built into the platform.&lt;/li&gt;
&lt;li&gt;ACID transactions and strict constraints are standard, which is why warehouses are preferred for financial/regulatory reporting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lakehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;transactional table formats&lt;/strong&gt; (e.g., Delta) to bring ACID guarantees and time travel to lake data.&lt;/li&gt;
&lt;li&gt;Governance is richer than a raw data lake but generally more complex than a classic warehouse because of the broader set of data types and tools.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Performance &amp;amp; Cost
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Highly optimized for &lt;strong&gt;star/snowflake schemas, aggregations, joins&lt;/strong&gt;, and tends to give very predictable performance for BI.&lt;/li&gt;
&lt;li&gt;Usually &lt;strong&gt;more expensive per TB&lt;/strong&gt; due to structured storage and pre-processing (ETL/ELT) but often cheaper in total for pure BI if the workload is well-modeled.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lakehouse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Leverages &lt;strong&gt;cheap object storage&lt;/strong&gt; with decoupled compute, making storage at petabyte scale cost-effective.&lt;/li&gt;
&lt;li&gt;Query performance can be extremely good but may require careful optimization (partitioning, Z-ordering, caching) and may be less predictable for pure BI than a tuned warehouse.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Comparison Table
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Warehouse&lt;/th&gt;
&lt;th&gt;Lakehouse&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary data types&lt;/td&gt;
&lt;td&gt;Structured&lt;/td&gt;
&lt;td&gt;Structured + semi + unstructured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema strategy&lt;/td&gt;
&lt;td&gt;Schema-on-write&lt;/td&gt;
&lt;td&gt;Mix of schema-on-write &amp;amp; schema-on-read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Relational DW engine&lt;/td&gt;
&lt;td&gt;Open formats on object storage (Delta/Iceberg/Hudi)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workloads&lt;/td&gt;
&lt;td&gt;BI, reporting, SQL analytics&lt;/td&gt;
&lt;td&gt;BI + ML/AI + streaming + exploration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Governance&lt;/td&gt;
&lt;td&gt;Strong, centralized, rigid&lt;/td&gt;
&lt;td&gt;Strong but more complex; needs careful design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Very strong for SQL/star schemas&lt;/td&gt;
&lt;td&gt;Strong but more tuning; multi-engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost model&lt;/td&gt;
&lt;td&gt;Higher per-TB; ETL cost&lt;/td&gt;
&lt;td&gt;Cheaper storage; more flexible ELT; ops cost shifts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team focus&lt;/td&gt;
&lt;td&gt;BI devs, SQL, data modeling&lt;/td&gt;
&lt;td&gt;Data engineers, ML, mixed SQL + Spark/ML skills&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Pros &amp;amp; Cons in Practice
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Data Warehouse – Strengths and Weaknesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Strengths
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very strong support for &lt;strong&gt;enterprise BI and reporting&lt;/strong&gt;, especially when you have conformed dimensions and consistent metrics.&lt;/li&gt;
&lt;li&gt;Predictable &lt;strong&gt;query performance and SLAs&lt;/strong&gt;, ideal for executives and operational dashboards.&lt;/li&gt;
&lt;li&gt;Mature tooling for &lt;strong&gt;governance, lineage, security&lt;/strong&gt;, and change control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Weaknesses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Not ideal for large volumes of raw/semi-structured data, IoT logs, clickstream, etc.&lt;/li&gt;
&lt;li&gt;ETL/ELT pipelines need to do significant up-front modeling, which can slow down onboarding new data sources.&lt;/li&gt;
&lt;li&gt;Less natural fit for heavy ML/AI workflows; data often needs to be exported to other systems.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Data Lakehouse – Strengths and Weaknesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Strengths
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single platform&lt;/strong&gt; for all data types and workloads, reducing duplication between lake (for data science) and warehouse (for BI).&lt;/li&gt;
&lt;li&gt;Good support for &lt;strong&gt;AI/ML pipelines&lt;/strong&gt; and feature engineering directly on the same data used for BI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-efficient at scale&lt;/strong&gt;, as raw and curated data both live on cheap cloud object storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Weaknesses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Operational complexity: more moving parts (Spark, SQL engines, catalogs, governance services).&lt;/li&gt;
&lt;li&gt;Query performance for classic star-schema BI can require more tuning than a specialized warehouse.&lt;/li&gt;
&lt;li&gt;Requires stronger &lt;strong&gt;data engineering and platform skills&lt;/strong&gt;, especially around table formats, partitioning, and governance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  When to Choose Which
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Prefer a Warehouse When
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Primary workloads are &lt;strong&gt;classic BI and reporting on structured data&lt;/strong&gt; (ERP/CRM, membership, finance, etc.) with predictable schemas.&lt;/li&gt;
&lt;li&gt;There are &lt;strong&gt;regulatory or financial controls&lt;/strong&gt; where high trust in curated, slowly changing schemas is essential.&lt;/li&gt;
&lt;li&gt;Teams are predominantly &lt;strong&gt;SQL / BI-oriented&lt;/strong&gt;, and speed to deliver stable dashboards is more important than experimentation flexibility.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prefer a Lakehouse When
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You need to manage &lt;strong&gt;diverse data types&lt;/strong&gt; (logs, events, documents, semi-structured API payloads) alongside relational data.&lt;/li&gt;
&lt;li&gt;There is a strong focus on &lt;strong&gt;data science, ML, and streaming analytics&lt;/strong&gt; in addition to BI.&lt;/li&gt;
&lt;li&gt;The platform must scale to very large volumes (multi-TB/PB) while keeping storage costs low.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Hybrid / Unified Architectures
&lt;/h2&gt;

&lt;p&gt;Most modern patterns recommend &lt;strong&gt;hybrid approaches&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a lakehouse (or lake + lakehouse) for &lt;strong&gt;raw and enriched layers&lt;/strong&gt; and ML/experimentation.&lt;/li&gt;
&lt;li&gt;Feed a &lt;strong&gt;curated warehouse&lt;/strong&gt; (or a warehouse-like gold layer) for “single source of truth” BI and regulated reporting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lakehouses are often described as the “third generation” after warehouses and lakes, combining many strengths while still leaving room for specialized warehouses in some scenarios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Data Warehouses and Data Lakehouses serve different but often complementary purposes. Warehouses provide structured, highly governed, and predictable environments ideal for BI and reporting. Lakehouses offer flexibility, scale, and support for diverse data types and AI/ML workloads on a unified platform.&lt;/p&gt;

&lt;p&gt;The right choice depends on your primary workload and organizational goals and in many modern architectures, a thoughtful combination of both delivers the best results.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>azure</category>
      <category>data</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>How Power BI MCP Makes Analytics Faster and Easier</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Mon, 02 Feb 2026 07:15:43 +0000</pubDate>
      <link>https://dev.to/anshul_02/how-power-bi-mcp-makes-analytics-faster-and-easier-4n1f</link>
      <guid>https://dev.to/anshul_02/how-power-bi-mcp-makes-analytics-faster-and-easier-4n1f</guid>
      <description>&lt;p&gt;If you're a data analyst or engineer working with Power BI, you'll want to know about Microsoft's new Power BI MCP (Model Context Protocol) servers. Released in November 2025, this tool lets you talk to your Power BI models using plain English and AI assistants like Claude or GitHub Copilot. Let me show you how this can save you hours of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Power BI MCP?
&lt;/h2&gt;

&lt;p&gt;Think of Power BI MCP as a bridge that lets AI assistants understand and work with your Power BI data models. Instead of clicking through menus and manually configuring things, you just describe what you want in natural language, and the AI does it for you.&lt;/p&gt;

&lt;p&gt;Microsoft released two versions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Power BI Modeling MCP&lt;/strong&gt; - Runs locally and helps you build and modify Power BI models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote Power BI MCP&lt;/strong&gt; - Lets you query your data using natural language&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How It Speeds Up Your Daily Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create Models 30x Faster
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Old way:&lt;/strong&gt; Click through Power BI Desktop, manually create a calendar table, set up columns, define hierarchies, create relationships... takes 15-30 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With MCP:&lt;/strong&gt; Type "Create a calendar table for 2025 with Year, Quarter, Month hierarchies and link it to my Sales table" - done in 30 seconds.&lt;/p&gt;

&lt;p&gt;That's a 97% time saving on routine tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bulk Operations in Seconds
&lt;/h3&gt;

&lt;p&gt;Need to rename 50 measures to match your new naming convention? Or translate all your column descriptions into Spanish? These tasks used to take hours of repetitive work.&lt;/p&gt;

&lt;p&gt;With MCP, you just say "Rename all measures to use underscore_case" or "Translate all descriptions to Spanish" and it handles everything at once. Users report saving 10-20 hours per month on these kinds of bulk operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Instant Documentation
&lt;/h3&gt;

&lt;p&gt;Ever inherit a Power BI model with no documentation? Instead of spending hours exploring tables and relationships manually, just ask the AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Show me all the relationships in this model"&lt;/li&gt;
&lt;li&gt;"Document all the measures with their business logic"&lt;/li&gt;
&lt;li&gt;"Create a diagram of the data model"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You get comprehensive documentation in minutes instead of hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ask Questions in Plain English
&lt;/h3&gt;

&lt;p&gt;Want to know "What were total sales by product category last quarter?" Just ask. The MCP server understands your data model, generates the right DAX query, and gives you the answer instantly.&lt;/p&gt;

&lt;p&gt;No need to export data to Excel and pivot tables. No writing complex DAX yourself. Just ask and get answers.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Optimize Performance Automatically
&lt;/h3&gt;

&lt;p&gt;The MCP can analyze your queries and suggest improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"This measure is slow - try using SUMMARIZECOLUMNS instead"&lt;/li&gt;
&lt;li&gt;"You have a cross join here that's causing performance issues"&lt;/li&gt;
&lt;li&gt;"Add this index to speed up your queries"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You get expert-level optimization advice without being a DAX expert yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Automate Repetitive Work
&lt;/h3&gt;

&lt;p&gt;Set up the AI to handle entire workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check all your Power Query connections&lt;/li&gt;
&lt;li&gt;Update parameters for different environments (dev/test/prod)&lt;/li&gt;
&lt;li&gt;Validate naming conventions across the model&lt;/li&gt;
&lt;li&gt;Commit changes to Git automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What used to be manual checklists becomes automated, consistent, and error-free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Time Savings
&lt;/h2&gt;

&lt;p&gt;Here's what actual users are experiencing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model creation:&lt;/strong&gt; 15-30 minutes → 30 seconds (tasks like calendar tables, basic structures)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk renaming:&lt;/strong&gt; 2-3 hours → 2 minutes (renaming conventions across 50+ objects)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; 4-5 hours → 10 minutes (complete model documentation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data exploration:&lt;/strong&gt; 1-2 hours → 5 minutes (understanding new models)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance tuning:&lt;/strong&gt; Hours of analysis → Minutes with AI suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install Visual Studio Code&lt;/li&gt;
&lt;li&gt;Install GitHub Copilot extension&lt;/li&gt;
&lt;li&gt;Install the Power BI Modeling MCP extension from VS Code marketplace&lt;/li&gt;
&lt;li&gt;Open Copilot chat and connect to your Power BI model&lt;/li&gt;
&lt;li&gt;Start asking questions or giving commands in plain English&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No complicated setup, no learning curve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Uses for MCP
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Great for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating standard structures (calendar tables, common measures)&lt;/li&gt;
&lt;li&gt;Bulk operations (renaming, translations, formatting)&lt;/li&gt;
&lt;li&gt;Model exploration and documentation&lt;/li&gt;
&lt;li&gt;Quick data queries and analysis&lt;/li&gt;
&lt;li&gt;Learning and getting suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Still needs human expertise for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex business logic with nested calculations&lt;/li&gt;
&lt;li&gt;Custom time intelligence for fiscal calendars&lt;/li&gt;
&lt;li&gt;Mission-critical measures that need validation&lt;/li&gt;
&lt;li&gt;Advanced DAX patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tips for Best Results
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use clear, specific language in your requests&lt;/li&gt;
&lt;li&gt;For complex tasks, break them into smaller steps&lt;/li&gt;
&lt;li&gt;Always review AI-generated DAX before deploying to production&lt;/li&gt;
&lt;li&gt;Start with simple tasks to get comfortable with the tool&lt;/li&gt;
&lt;li&gt;Use it alongside your existing tools like DAX Studio or Tabular Editor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Power BI MCP isn't replacing data analysts - it's making them way more productive. The tedious, repetitive parts of your job that eat up hours? Those are now automated. This frees you up to focus on the interesting stuff: understanding business problems, designing solutions, and delivering insights.&lt;/p&gt;

&lt;p&gt;If you spend any significant time working with Power BI models, this tool can easily save you 10-20 hours per month. That's half a work week back in your schedule.&lt;/p&gt;

&lt;p&gt;The best part? It's available now and easy to set up. Give it a try - your future self will thank you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Ready to speed up your Power BI workflow? Install the Power BI Modeling MCP extension today and start working smarter, not harder.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>analytics</category>
      <category>mcp</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Performance Analyzer &amp; DAX Studio</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Tue, 16 Dec 2025 08:43:49 +0000</pubDate>
      <link>https://dev.to/anshul_02/performance-analyzer-dax-studio-4pm9</link>
      <guid>https://dev.to/anshul_02/performance-analyzer-dax-studio-4pm9</guid>
      <description>&lt;h1&gt;
  
  
  A Simple Guide to Power BI Optimization
&lt;/h1&gt;

&lt;p&gt;If your Power BI reports are running slow, don't worry—you're not alone! The good news is that Power BI gives you two powerful tools to find and fix performance issues: Performance Analyzer (built into Power BI) and DAX Studio (a free external tool). Let me show you how to use both.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are These Tools?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Performance Analyzer&lt;/strong&gt; is like a stopwatch for your Power BI report. It tells you exactly how long each visual takes to load and what's slowing it down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DAX Studio&lt;/strong&gt; is like a mechanic's diagnostic tool. It lets you test your DAX formulas, see how they perform, and understand what's happening behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Using Performance Analyzer in Power BI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Open Performance Analyzer
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your Power BI Desktop report&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;View&lt;/strong&gt; tab on the ribbon&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Performance Analyzer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A panel will open on the right side of your screen&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Start Recording
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click the &lt;strong&gt;Start recording&lt;/strong&gt; button in the Performance Analyzer panel&lt;/li&gt;
&lt;li&gt;Interact with your report—click on visuals, use slicers, switch pages&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Stop recording&lt;/strong&gt; when you're done&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Read the Results
&lt;/h3&gt;

&lt;p&gt;Performance Analyzer breaks down the time for each visual into three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DAX query&lt;/strong&gt;: Time spent calculating your measures and formulas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual display&lt;/strong&gt;: Time spent drawing the chart or table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other&lt;/strong&gt;: Background tasks like sending queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any visual taking more than 2-3 seconds is a problem&lt;/li&gt;
&lt;li&gt;High DAX query times mean your formulas need work&lt;/li&gt;
&lt;li&gt;High visual display times mean you might have too much data in one visual&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Take Action
&lt;/h3&gt;

&lt;p&gt;Click the &lt;strong&gt;Copy query&lt;/strong&gt; button next to any slow visual. This copies the DAX query so you can analyze it further in DAX Studio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Using DAX Studio for Deep Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install and Connect
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download DAX Studio for free from daxstudio.org&lt;/li&gt;
&lt;li&gt;Install and open it&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Connect&lt;/strong&gt; and choose your Power BI file or dataset&lt;/li&gt;
&lt;li&gt;Your data model is now loaded&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Test Your DAX Queries
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Paste the query you copied from Performance Analyzer (or write your own measure)&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Run&lt;/strong&gt; button (or press F5)&lt;/li&gt;
&lt;li&gt;Look at the results and timing at the bottom&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Use Server Timings
&lt;/h3&gt;

&lt;p&gt;This is where the magic happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;strong&gt;Server Timings&lt;/strong&gt; button (looks like a stopwatch) in the toolbar&lt;/li&gt;
&lt;li&gt;Run your query again&lt;/li&gt;
&lt;li&gt;A new tab opens showing you exactly where time is being spent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storage Engine (SE) queries&lt;/strong&gt;: Time spent reading data from your tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Formula Engine (FE)&lt;/strong&gt;: Time spent doing calculations&lt;/li&gt;
&lt;li&gt;If SE time is high, you might need better data modeling or filters&lt;/li&gt;
&lt;li&gt;If FE time is high, your DAX formula might be inefficient&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Analyze Query Plans
&lt;/h3&gt;

&lt;p&gt;For advanced optimization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Query Plan&lt;/strong&gt; button before running a query&lt;/li&gt;
&lt;li&gt;Run your query&lt;/li&gt;
&lt;li&gt;Review the physical and logical query plans to see exactly how your query is executed&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Performance Issues and Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue 1: Slow Measures with Iterators
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Using functions like SUMX, FILTER, or CALCULATE over large tables&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Pre-calculate values in calculated columns when possible&lt;/li&gt;
&lt;li&gt;Use variables (VAR) to avoid repeating calculations&lt;/li&gt;
&lt;li&gt;Filter data early in your formulas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 2: Too Many Visuals on One Page
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Page takes forever to load&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Split content across multiple pages&lt;/li&gt;
&lt;li&gt;Use bookmarks to show/hide sections&lt;/li&gt;
&lt;li&gt;Remove unnecessary visuals&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 3: Large Data Model
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; The entire report is slow&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Remove unused columns and tables&lt;/li&gt;
&lt;li&gt;Use aggregations for summarized data&lt;/li&gt;
&lt;li&gt;Check your relationships—avoid bi-directional filters unless necessary&lt;/li&gt;
&lt;li&gt;Consider using Import mode instead of DirectQuery when possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 4: Complex DAX Formulas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Measures with nested CALCULATE statements run slowly&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Break complex measures into simpler intermediate measures&lt;/li&gt;
&lt;li&gt;Use measure branching—store parts of calculations in separate measures&lt;/li&gt;
&lt;li&gt;Avoid using ALL() functions unnecessarily&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Optimization Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist after analyzing your report:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Model:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove unused columns and tables&lt;/li&gt;
&lt;li&gt;[ ] Hide columns not needed in reports&lt;/li&gt;
&lt;li&gt;[ ] Use star schema design (fact and dimension tables)&lt;/li&gt;
&lt;li&gt;[ ] Avoid bi-directional relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DAX Formulas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use variables (VAR) to store intermediate results&lt;/li&gt;
&lt;li&gt;[ ] Filter early, calculate late&lt;/li&gt;
&lt;li&gt;[ ] Replace iterators with simpler aggregations when possible&lt;/li&gt;
&lt;li&gt;[ ] Avoid nested CALCULATE statements&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;[ ] Limit visuals to 10-15 per page&lt;/li&gt;
&lt;li&gt;[ ] Reduce data points in charts (use aggregation)&lt;/li&gt;
&lt;li&gt;[ ] Turn off visual interactions that aren't needed&lt;/li&gt;
&lt;li&gt;[ ] Use page navigation instead of cramming everything on one page&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pro Tips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tip 1:&lt;/strong&gt; Always test performance with realistic data volumes. A report that works fast with 100 rows might crawl with 100,000 rows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 2:&lt;/strong&gt; Use DAX Studio's "Clear Cache" button before testing to get accurate timings without cached results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 3:&lt;/strong&gt; Start by optimizing the slowest visuals first—fixing one 10-second visual is better than fixing ten 0.5-second visuals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 4:&lt;/strong&gt; Document your changes. Keep notes on what you changed and how it improved performance.&lt;/p&gt;

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

&lt;p&gt;Performance optimization doesn't have to be overwhelming. Start with Performance Analyzer to identify slow visuals, then use DAX Studio to understand and fix the underlying queries. Focus on the biggest problems first, and you'll see dramatic improvements.&lt;/p&gt;

&lt;p&gt;Remember: a fast report isn't just nice to have—it's essential for user adoption and productivity. Take the time to optimize, and your users will thank you!&lt;/p&gt;

&lt;p&gt;Happy optimizing!&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>tooling</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Git Integration in Microsoft Fabric</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Tue, 30 Sep 2025 14:47:31 +0000</pubDate>
      <link>https://dev.to/anshul_02/git-integration-in-microsoft-fabric-b75</link>
      <guid>https://dev.to/anshul_02/git-integration-in-microsoft-fabric-b75</guid>
      <description>&lt;p&gt;This guide walks you through the basic tasks for using Microsoft Fabric’s Git integration tool, including how to connect a workspace to a Git repository, commit changes, update from Git, and disconnect from Git.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Fabric Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Access to a Fabric capacity is required to use all supported Fabric items. You can sign up for a free trial if you don't have one.&lt;/li&gt;
&lt;li&gt;The following tenant switches must be enabled from the Admin portal:

&lt;ul&gt;
&lt;li&gt;Users can create Fabric items&lt;/li&gt;
&lt;li&gt;Users can synchronize workspace items with their Git repositories&lt;/li&gt;
&lt;li&gt;Create workspaces (needed if branching out to a new workspace)&lt;/li&gt;
&lt;li&gt;Users can synchronize workspace items with GitHub repositories (for GitHub users)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;These switches can be enabled by tenant admin, capacity admin, or workspace admin depending on organizational settings.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Git Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Git integration supports Azure DevOps or GitHub repositories.&lt;/li&gt;
&lt;li&gt;You must have:

&lt;ul&gt;
&lt;li&gt;An active Azure account registered to the same user as the Fabric workspace.&lt;/li&gt;
&lt;li&gt;Access to an existing Git repository in Azure DevOps or GitHub.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Connect a Workspace to a Git Repo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Connect to a Git Repo
&lt;/h2&gt;

&lt;p&gt;Only workspace admins can connect a workspace to a Git repository, though anyone with permission can work in the connected workspace.&lt;/p&gt;

&lt;p&gt;To connect:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign in to Microsoft Fabric and navigate to the workspace.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Workspace settings.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose your Git provider—Azure DevOps or GitHub.&lt;/li&gt;
&lt;li&gt;For Azure DevOps, click &lt;strong&gt;Connect&lt;/strong&gt; to automatically sign in using the Azure Repos account associated with your Microsoft Entra user.&lt;/li&gt;
&lt;/ol&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%2F6v58zkfd03uhwv4jjh6g.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%2F6v58zkfd03uhwv4jjh6g.png" alt=" " width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect to a Workspace Branch
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;From the dropdown menu, specify:

&lt;ul&gt;
&lt;li&gt;Organization&lt;/li&gt;
&lt;li&gt;Project&lt;/li&gt;
&lt;li&gt;Git repository&lt;/li&gt;
&lt;li&gt;Branch (select an existing branch or create a new one)&lt;/li&gt;
&lt;li&gt;Folder (existing or new folder; blank creates content in root)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Far88agmi0ag3mgjvnqey.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%2Far88agmi0ag3mgjvnqey.png" alt=" " width="800" height="788"&gt;&lt;/a&gt;&lt;br&gt;
Click &lt;strong&gt;Connect and sync&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On initial sync, if one side (workspace or Git branch) is empty, content copies from the nonempty side.&lt;/li&gt;
&lt;/ul&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%2F0jjmlpmbctt9uwkgwg4z.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%2F0jjmlpmbctt9uwkgwg4z.png" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If both sides have content, you choose the sync direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit Changes to Git
&lt;/h2&gt;

&lt;p&gt;After connecting, you can edit the workspace normally. Changes are saved only in the workspace until committed to the Git branch.&lt;/p&gt;

&lt;p&gt;To commit changes:&lt;/p&gt;

&lt;p&gt;Go to the workspace and click the &lt;strong&gt;Source control&lt;/strong&gt; icon which shows the number of uncommitted changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose items to commit or select all.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a comment (default added if empty).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Commit&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fx6q409vzy43v7smulqel.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%2Fx6q409vzy43v7smulqel.png" alt=" " width="380" height="740"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After commit, items are removed from the changes list, and the status changes from &lt;strong&gt;Uncommitted&lt;/strong&gt; to &lt;strong&gt;Synced&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When others commit changes to the connected Git branch, a notification shows in the workspace.&lt;/p&gt;

&lt;p&gt;To update:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the workspace.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Source control&lt;/strong&gt; icon.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Updates&lt;/strong&gt; to see changes since the last sync.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Update all&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2F8yymwqqpiavpx57ph0lm.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%2F8yymwqqpiavpx57ph0lm.png" alt=" " width="536" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a successful update, changes are applied, and status changes to &lt;strong&gt;Synced&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Only workspace admins can disconnect a workspace.&lt;/p&gt;

&lt;p&gt;Steps to disconnect:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Workspace settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Git integration&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Disconnect workspace&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Confirm by selecting &lt;strong&gt;Disconnect&lt;/strong&gt; again.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Manage Branches in Microsoft Fabric Workspaces
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration Workspace (Main Branch)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The collaboration workspace is connected to the &lt;strong&gt;main branch&lt;/strong&gt; of the repo.&lt;/li&gt;
&lt;li&gt;This workspace contains the consolidated, reviewed, and approved versions of the work shared by the team.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature Branch Workspaces (Developer Workspaces)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Each developer can create their own &lt;strong&gt;feature branch&lt;/strong&gt; in the workspace setting of Git Integration created off of main (e.g., "feature1", "feature2").&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Fr1rc1ro5s198fi1qlfle.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%2Fr1rc1ro5s198fi1qlfle.png" alt=" " width="402" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each developer works in their own workspace connected to their respective feature branch.&lt;/li&gt;
&lt;li&gt;Developers make changes, commit them locally, and push to their feature branches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull Requests and Merging&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Changes from feature branches are merged into the main branch via pull requests (PRs) in Azure DevOps.&lt;/li&gt;
&lt;li&gt;PRs require review and approval ensuring code quality and collaboration governance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Syncing and Updating Workspaces&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Once a PR is merged into main, the collaboration workspace can be updated to reflect the merged changes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fd55ks06plz7nsq4ddmsg.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%2Fd55ks06plz7nsq4ddmsg.png" alt=" " width="334" height="681"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers keep their feature branches long-lived, which means they occasionally need to sync their branches with main to get the latest changes. As Fabric does not support direct branch updates inside the workspace, this update is done by creating a PR from main back into the feature branch in Azure DevOps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branch Policies and Permissions&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Branch policies, like requiring minimum reviewers, help protect the main branch from direct commits, ensuring all changes come through PRs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>dataengineering</category>
      <category>fabric</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Why to use Medallion Architecture ?</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Mon, 01 Sep 2025 19:30:04 +0000</pubDate>
      <link>https://dev.to/anshul_02/why-to-use-medallion-architecture--21d3</link>
      <guid>https://dev.to/anshul_02/why-to-use-medallion-architecture--21d3</guid>
      <description>&lt;h1&gt;
  
  
  Understanding the Medallion Architecture: A Comprehensive Guide with a Use Case
&lt;/h1&gt;

&lt;p&gt;Data management is crucial for organizations aiming to optimize efficiency and reliability. Choosing the appropriate data architecture is vital to achieving this. One prominent architecture gaining traction is the &lt;strong&gt;Medallion Architecture&lt;/strong&gt;, often structured in three layers: bronze, silver, and gold. This approach helps organizations systematically improve data quality and usability through progressive refinement.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is the Medallion Architecture?
&lt;/h2&gt;

&lt;p&gt;The Medallion Architecture organizes data into three key layers, each with a distinct role in the data lifecycle:&lt;/p&gt;

&lt;h3&gt;
  
  
  Bronze Layer: Raw Data Ingestion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Capture and store raw, unprocessed data exactly as it arrives from various sources.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Serves as a landing zone preserving original data formats and contents, including logs, streaming, batch, and unstructured data. Basic deduplication can be done here.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Collecting raw membership activity data from various platforms such as website interactions, mobile app usage, and event attendance.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users:&lt;/strong&gt; Data engineers and analysts tasked with ingesting raw data and exploratory analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Silver Layer: Cleansed and Enriched Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Clean, transform, and enrich raw data to improve quality and analytical usability.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Applies data cleansing such as removing duplicates, filling missing values, and applying business rules to create a consistent dataset. Data from multiple sources may be joined or integrated here.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Filtering out incomplete membership records, standardizing member identifiers, and integrating demographic data for enriched profiles.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users:&lt;/strong&gt; Data engineers, data scientists, and analysts performing deeper analysis and feature engineering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Gold Layer: Business-Ready Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Provide highly processed, aggregated data optimized for business intelligence (BI), analytics, and machine learning.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Contains aggregated metrics, KPIs, summaries, and structured datasets tailored for end-user consumption and decision-making.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Calculating monthly active members, average membership duration, and retention rates to guide marketing and engagement strategies.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users:&lt;/strong&gt; Business analysts, executives, data scientists, and AI/ML engineers consuming clean and ready-to-use data.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Use the Medallion Architecture?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Quality Management:&lt;/strong&gt; Ensures quality checks occur progressively, reducing errors and inconsistencies before business use.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Supports diverse data environments and reuse of transformed data, while maintaining modularity for easier maintenance.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance:&lt;/strong&gt; Simplifies compliance and access control by separating raw, cleansed, and business-ready data layers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Lineage:&lt;/strong&gt; Provides transparent data transformation tracking for auditability and trust.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When to Use the Medallion Architecture?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Organizations handling &lt;strong&gt;large volumes&lt;/strong&gt; of data from varied sources.
&lt;/li&gt;
&lt;li&gt;Environments requiring &lt;strong&gt;high data quality and governance&lt;/strong&gt; like healthcare, finance, and regulated industries.
&lt;/li&gt;
&lt;li&gt;Companies aiming for &lt;strong&gt;scalable, maintainable data pipelines&lt;/strong&gt; supporting analytics and machine learning.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Implementing the Medallion Architecture: A Practical Use Case with Azure Tools
&lt;/h2&gt;

&lt;p&gt;Consider an organization analyzing membership data to gain business insights using Azure data engineering tools like Azure Data Factory (ADF) and Microsoft Fabric.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Environment Setup
&lt;/h3&gt;

&lt;p&gt;Prepare your data infrastructure using Azure Data Lake Storage for scalable storage and Azure Data Factory for orchestrating data workflows and pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Ingest Raw Data (Bronze Layer)
&lt;/h3&gt;

&lt;p&gt;Use Azure Data Factory to ingest membership activity data from various sources (e.g., web logs, app data, event registration systems) into the Bronze layer stored in Azure Data Lake. This raw data retains its original format and serves as the source of truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Clean and Enrich Data (Silver Layer)
&lt;/h3&gt;

&lt;p&gt;Transform the raw data in Azure Synapse or Fabric by cleaning (removing duplicates, handling missing values), standardizing member IDs, and enriching with additional profile data from CRM systems. This produces a high-quality curated dataset ready for analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Aggregate and Prepare Business Data (Gold Layer)
&lt;/h3&gt;

&lt;p&gt;Aggregate and summarize membership trends using Synapse or Fabric SQL to create business-ready datasets, such as monthly active members, average membership tenure, and retention rates. These datasets feed Power BI dashboards and support machine learning models for personalized marketing.&lt;/p&gt;




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

&lt;p&gt;The Medallion Architecture offers a powerful framework to organize data into layers of increasing quality and business value. Its layered approach facilitates improved data governance, traceability, and scalability. Leveraging data engineering tools like Azure Data Factory and Microsoft Fabric enables organizations to build robust, scalable, and maintainable data pipelines that empower data-driven decision-making and advanced analytics.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Mastering Cursor Rules: Your Complete Guide to AI-Powered Coding Excellence</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Tue, 08 Jul 2025 17:22:11 +0000</pubDate>
      <link>https://dev.to/anshul_02/mastering-cursor-rules-your-complete-guide-to-ai-powered-coding-excellence-2j5h</link>
      <guid>https://dev.to/anshul_02/mastering-cursor-rules-your-complete-guide-to-ai-powered-coding-excellence-2j5h</guid>
      <description>&lt;p&gt;Cursor AI has revolutionized the way developers write code, but its true power lies in customization through rules. Cursor Rules provide a powerful way to give consistent, reusable instructions to Cursor's AI features, like the Agent and Cmd-K. They help the AI understand your project's context, adhere to specific coding styles, and automate workflows, making it a more effective coding partner.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Cursor Rules?
&lt;/h2&gt;

&lt;p&gt;Cursor Rules are essentially saved prompts or guidelines that are automatically included when the AI processes your requests. Think of them as a way to give the AI persistent memory and instructions tailored to your needs. Large language models don't retain memory between completions. Rules provide persistent, reusable context at the prompt level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Rules in Cursor
&lt;/h2&gt;

&lt;p&gt;Cursor offers three distinct types of rules, each serving different purposes:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Global Rules
&lt;/h3&gt;

&lt;p&gt;Set in Cursor Settings under General &amp;gt; Rules for AI. Located in Cursor Settings -&amp;gt; General, these rules establish core principles for all AI interactions. They define fundamental behavior patterns and are language-agnostic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to Use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting universal coding standards across all projects&lt;/li&gt;
&lt;li&gt;Defining your preferred programming practices&lt;/li&gt;
&lt;li&gt;Establishing consistent AI behavior patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Project Rules
&lt;/h3&gt;

&lt;p&gt;Stored in .cursor/rules, version-controlled and scoped to your codebase. Create rules using the New Cursor Rule command or going to Cursor Settings &amp;gt; Rules. This creates a new rule file in .cursor/rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to Use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project-specific guidelines and conventions&lt;/li&gt;
&lt;li&gt;Team collaboration standards&lt;/li&gt;
&lt;li&gt;Framework-specific instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Legacy .cursorrules Files
&lt;/h3&gt;

&lt;p&gt;Defined in a .cursorrules file in your project's root directory. Still supported, but deprecated. Use Project Rules instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Your First Rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quick Start with Global Rules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open Cursor Settings (Cmd/Ctrl + ,)&lt;/li&gt;
&lt;li&gt;Navigate to General &amp;gt; Rules for AI&lt;/li&gt;
&lt;li&gt;Add your universal coding preferences:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Global Coding Standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use TypeScript for all new code
&lt;span class="p"&gt;-&lt;/span&gt; Follow clean code principles
&lt;span class="p"&gt;-&lt;/span&gt; Prefer async/await over callbacks
&lt;span class="p"&gt;-&lt;/span&gt; Write comprehensive error handling
&lt;span class="p"&gt;-&lt;/span&gt; Include JSDoc comments for functions
&lt;span class="p"&gt;-&lt;/span&gt; Use meaningful variable names
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating Project-Specific Rules
&lt;/h3&gt;

&lt;p&gt;Open the command palette (Cmd+Shift+P or Ctrl+Shift+P) and type Cursor Rules: Add .cursorrules.&lt;/p&gt;

&lt;p&gt;Example project rule structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Project: E-commerce Platform&lt;/span&gt;
&lt;span class="gu"&gt;## Technology Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; React 18 with TypeScript
&lt;span class="p"&gt;-&lt;/span&gt; Node.js backend with Express
&lt;span class="p"&gt;-&lt;/span&gt; PostgreSQL database
&lt;span class="p"&gt;-&lt;/span&gt; Tailwind CSS for styling

&lt;span class="gu"&gt;## Coding Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use functional components with hooks
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper error boundaries
&lt;span class="p"&gt;-&lt;/span&gt; Follow atomic design principles
&lt;span class="p"&gt;-&lt;/span&gt; Use React Query for data fetching
&lt;span class="p"&gt;-&lt;/span&gt; Maintain 80% test coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Rule Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React/TypeScript Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# React TypeScript Rules&lt;/span&gt;
&lt;span class="gu"&gt;## Component Standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use functional components exclusively
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper prop types with interfaces
&lt;span class="p"&gt;-&lt;/span&gt; Follow naming convention: PascalCase for components
&lt;span class="p"&gt;-&lt;/span&gt; Use custom hooks for complex logic
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper error handling

&lt;span class="gu"&gt;## State Management&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use React Query for server state
&lt;span class="p"&gt;-&lt;/span&gt; Use Zustand for client state
&lt;span class="p"&gt;-&lt;/span&gt; Avoid prop drilling beyond 2 levels
&lt;span class="p"&gt;-&lt;/span&gt; Implement optimistic updates where appropriate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Backend API Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Backend API Guidelines&lt;/span&gt;
&lt;span class="gu"&gt;## Architecture&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Follow RESTful conventions
&lt;span class="p"&gt;-&lt;/span&gt; Use middleware for authentication
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper logging
&lt;span class="p"&gt;-&lt;/span&gt; Use environment variables for configuration

&lt;span class="gu"&gt;## Error Handling&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Return consistent error responses
&lt;span class="p"&gt;-&lt;/span&gt; Log all errors with context
&lt;span class="p"&gt;-&lt;/span&gt; Use appropriate HTTP status codes
&lt;span class="p"&gt;-&lt;/span&gt; Implement request validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Database Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Database Guidelines&lt;/span&gt;
&lt;span class="gu"&gt;## Query Optimization&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use indexes for frequently queried fields
&lt;span class="p"&gt;-&lt;/span&gt; Avoid N+1 queries
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper pagination
&lt;span class="p"&gt;-&lt;/span&gt; Use connection pooling

&lt;span class="gu"&gt;## Security&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Sanitize all inputs
&lt;span class="p"&gt;-&lt;/span&gt; Use parameterized queries
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper access controls
&lt;span class="p"&gt;-&lt;/span&gt; Regular security audits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices for Effective Rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Be Specific and Actionable
&lt;/h3&gt;

&lt;p&gt;Instead of vague instructions like "write good code," provide specific guidelines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Good: Specific and actionable&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use camelCase for variable names
&lt;span class="p"&gt;-&lt;/span&gt; Limit functions to 20 lines maximum
&lt;span class="p"&gt;-&lt;/span&gt; Include type annotations for all parameters

&lt;span class="gh"&gt;# Bad: Vague and unhelpful&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Write clean code
&lt;span class="p"&gt;-&lt;/span&gt; Make it efficient
&lt;span class="p"&gt;-&lt;/span&gt; Follow best practices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Include Context and Examples
&lt;/h3&gt;

&lt;p&gt;You might use this to give for context on what you're building, style guidelines, or info on commonly-used methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication Context&lt;/span&gt;
This project uses JWT tokens for authentication.
Example login flow:
&lt;span class="p"&gt;1.&lt;/span&gt; User submits credentials
&lt;span class="p"&gt;2.&lt;/span&gt; Server validates and returns JWT
&lt;span class="p"&gt;3.&lt;/span&gt; Client stores token in httpOnly cookie
&lt;span class="p"&gt;4.&lt;/span&gt; Include token in Authorization header
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Organize Rules Hierarchically
&lt;/h3&gt;

&lt;p&gt;project/ .cursor/rules/ # Project-wide rules backend/ server/ .cursor/rules/ # Backend-specific rules frontend/ .cursor/rules/ # Frontend-specific rules&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Version Control Your Rules
&lt;/h3&gt;

&lt;p&gt;Since rules are stored in &lt;code&gt;.cursor/rules&lt;/code&gt;, they're automatically version-controlled, allowing your team to collaborate on AI behavior guidelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Style Enforcement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Code Style Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use 2 spaces for indentation
&lt;span class="p"&gt;-&lt;/span&gt; No trailing whitespace
&lt;span class="p"&gt;-&lt;/span&gt; Semicolons are required
&lt;span class="p"&gt;-&lt;/span&gt; Use single quotes for strings
&lt;span class="p"&gt;-&lt;/span&gt; Maximum line length: 100 characters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Framework-Specific Guidelines
&lt;/h3&gt;

&lt;p&gt;Great to remind the AI about outdated things (like 'use client' on top of client-side files in Nextjs)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Next.js 13+ App Router Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use 'use client' directive for client components
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper loading and error states
&lt;span class="p"&gt;-&lt;/span&gt; Use Server Components by default
&lt;span class="p"&gt;-&lt;/span&gt; Leverage parallel routes for complex layouts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing Standards
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Testing Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Write tests for all public functions
&lt;span class="p"&gt;-&lt;/span&gt; Use Jest for unit tests
&lt;span class="p"&gt;-&lt;/span&gt; Implement E2E tests with Playwright
&lt;span class="p"&gt;-&lt;/span&gt; Maintain 80% code coverage
&lt;span class="p"&gt;-&lt;/span&gt; Use descriptive test names
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rules Not Working?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check rule syntax&lt;/strong&gt;: Ensure proper markdown formatting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify rule location&lt;/strong&gt;: Confirm rules are in the correct directory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restart Cursor&lt;/strong&gt;: Rules may need a restart to take effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check rule conflicts&lt;/strong&gt;: Global rules may override project rules&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Performance Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keep rules concise but comprehensive&lt;/li&gt;
&lt;li&gt;Avoid redundant instructions&lt;/li&gt;
&lt;li&gt;Use clear, unambiguous language&lt;/li&gt;
&lt;li&gt;Regular review and updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advanced Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dynamic Rules for Different Environments
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Environment-Specific Rules&lt;/span&gt;
&lt;span class="gu"&gt;## Development&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Include detailed console logging
&lt;span class="p"&gt;-&lt;/span&gt; Use development API endpoints
&lt;span class="p"&gt;-&lt;/span&gt; Enable debug mode

&lt;span class="gu"&gt;## Production&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Minimize console output
&lt;span class="p"&gt;-&lt;/span&gt; Use production API endpoints
&lt;span class="p"&gt;-&lt;/span&gt; Implement proper error tracking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integration with External Tools
&lt;/h3&gt;

&lt;p&gt;Reference external style guides and documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# External References&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Follow Google TypeScript Style Guide
&lt;span class="p"&gt;-&lt;/span&gt; Use Prettier for code formatting
&lt;span class="p"&gt;-&lt;/span&gt; Adhere to ESLint configuration
&lt;span class="p"&gt;-&lt;/span&gt; Reference project's README for setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Measuring Success
&lt;/h2&gt;

&lt;p&gt;Track the effectiveness of your rules by monitoring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code review feedback frequency&lt;/li&gt;
&lt;li&gt;Bug reports related to style/standards&lt;/li&gt;
&lt;li&gt;Developer onboarding time&lt;/li&gt;
&lt;li&gt;Code consistency across the team&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Community Resources
&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="https://cursor.directory/" rel="noopener noreferrer"&gt;https://cursor.directory/&lt;/a&gt; to get some sample usage. The community has created numerous rule templates for different technologies and use cases.&lt;/p&gt;

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

&lt;p&gt;Cursor Rules transform the AI from a generic code assistant into a personalized development partner that understands your project's unique requirements. By defining coding standards and best practices in your .cursorrules files, you can ensure more relevant and accurate code suggestions.&lt;/p&gt;

&lt;p&gt;Start with basic global rules, then gradually implement project-specific guidelines. Remember, effective rules are specific, actionable, and regularly updated to reflect your evolving development practices.&lt;/p&gt;

&lt;p&gt;The investment in setting up comprehensive rules pays dividends in code quality, team consistency, and development velocity. Your AI assistant becomes not just a tool, but a knowledgeable team member who understands your standards and helps maintain them across your entire codebase.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Backend Deployment on Azure App Service with Bitbucket CI/CD Pipeline</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Wed, 19 Mar 2025 11:07:12 +0000</pubDate>
      <link>https://dev.to/anshul_02/backend-deployment-on-azure-app-service-with-bitbucket-cicd-pipeline-5dga</link>
      <guid>https://dev.to/anshul_02/backend-deployment-on-azure-app-service-with-bitbucket-cicd-pipeline-5dga</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After successfully setting up CI/CD for our frontend application, our next challenge was deploying the backend API to Azure App Service. This blog post details our approach to automating the backend deployment process using Bitbucket Pipelines and shares important Azure configuration steps that are often overlooked in tutorials.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this guide, you'll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Node.js backend application in a Bitbucket repository&lt;/li&gt;
&lt;li&gt;An Azure subscription&lt;/li&gt;
&lt;li&gt;An Azure App Service plan and web app&lt;/li&gt;
&lt;li&gt;Service principal credentials for Azure deployment&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Backend Pipeline Configuration
&lt;/h2&gt;

&lt;p&gt;Our backend deployment pipeline follows a similar structure to our frontend pipeline, with some key differences tailored to backend requirements. Here's our complete &lt;code&gt;bitbucket-pipelines.yml&lt;/code&gt; file:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:22&lt;/span&gt;

&lt;span class="na"&gt;pipelines&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install&lt;/span&gt;
          &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Installing dependencies..."&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --force&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run build&lt;/span&gt;
              &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Building project..."&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --force&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-get update &amp;amp;&amp;amp; apt-get install -y zip&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zip -r app-$BITBUCKET_BUILD_NUMBER.zip build package.json package-lock.json&lt;/span&gt;
              &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.zip"&lt;/span&gt;

          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security Scan&lt;/span&gt;
              &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Perform a security scan for sensitive data..."&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "See https://bitbucket.org/product/features/pipelines/integrations#security"&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-get update &amp;amp;&amp;amp; apt-get install -y git-secrets&lt;/span&gt;
                &lt;span class="c1"&gt;# Example usage: git secrets --scan&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
          &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;manual&lt;/span&gt;          
          &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/azure-web-apps-deploy:1.0.1&lt;/span&gt;
              &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;AZURE_APP_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_ID&lt;/span&gt;
                &lt;span class="na"&gt;AZURE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_PASSWORD&lt;/span&gt;
                &lt;span class="na"&gt;AZURE_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_TENANT_ID&lt;/span&gt;
                &lt;span class="na"&gt;AZURE_RESOURCE_GROUP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_RESOURCE_GROUP&lt;/span&gt;
                &lt;span class="na"&gt;AZURE_APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_NAME&lt;/span&gt;
                &lt;span class="na"&gt;ZIP_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-$BITBUCKET_BUILD_NUMBER.zip&lt;/span&gt;        
                &lt;span class="na"&gt;DEBUG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pipeline Breakdown
&lt;/h3&gt;

&lt;p&gt;Let's examine each section of the pipeline:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Installation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install&lt;/span&gt;
    &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Installing dependencies..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step installs all dependencies required for the application. The &lt;code&gt;--force&lt;/code&gt; flag helps overcome any dependency conflicts that might arise.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Parallel Execution
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run build&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Building project..."&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --force&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-get update &amp;amp;&amp;amp; apt-get install -y zip&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zip -r app-$BITBUCKET_BUILD_NUMBER.zip build package.json package-lock.json&lt;/span&gt;
        &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.zip"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security Scan&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Perform a security scan for sensitive data..."&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "See https://bitbucket.org/product/features/pipelines/integrations#security"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-get update &amp;amp;&amp;amp; apt-get install -y git-secrets&lt;/span&gt;
          &lt;span class="c1"&gt;# Example usage: git secrets --scan&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section runs two processes in parallel:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build&lt;/strong&gt;: Compiles the Node.js application and packages it for deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Scan&lt;/strong&gt;: Checks for sensitive data in the codebase&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that in our backend build, we're including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;build&lt;/code&gt; directory with compiled code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files for dependency information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is crucial for Azure App Service to correctly install and run the Node.js application.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Deployment
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
    &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;manual&lt;/span&gt;          
    &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/azure-web-apps-deploy:1.0.1&lt;/span&gt;
        &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_APP_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_ID&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_TENANT_ID&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_RESOURCE_GROUP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_RESOURCE_GROUP&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_NAME&lt;/span&gt;
          &lt;span class="na"&gt;ZIP_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-$BITBUCKET_BUILD_NUMBER.zip&lt;/span&gt;        
          &lt;span class="na"&gt;DEBUG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has a manual trigger for controlled deployments&lt;/li&gt;
&lt;li&gt;Uses the Atlassian Azure Web Apps Deploy pipe&lt;/li&gt;
&lt;li&gt;Passes necessary Azure credentials stored as repository variables&lt;/li&gt;
&lt;li&gt;Specifies the zip file created in the build step&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Azure App Service Configuration
&lt;/h2&gt;

&lt;p&gt;Unlike frontend deployments, backend deployments require additional configuration in Azure App Service. Here's a step-by-step guide to setting up your Azure environment for Node.js backend applications:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create an App Service
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the Azure Portal&lt;/li&gt;
&lt;li&gt;Click on "Create a resource" &amp;gt; "Web App"&lt;/li&gt;
&lt;li&gt;Fill in the required details:

&lt;ul&gt;
&lt;li&gt;Resource Group: Choose existing or create new&lt;/li&gt;
&lt;li&gt;Name: A unique name for your app&lt;/li&gt;
&lt;li&gt;Publish: Code&lt;/li&gt;
&lt;li&gt;Runtime stack: Node.js (version matching your application)&lt;/li&gt;
&lt;li&gt;Operating System: Linux (recommended for Node.js)&lt;/li&gt;
&lt;li&gt;Region: Choose appropriate region&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click "Review + create" and then "Create"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Configure Startup Command
&lt;/h3&gt;

&lt;p&gt;For Node.js applications, you need to specify how Azure should start your application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your App Service in the Azure Portal&lt;/li&gt;
&lt;li&gt;Go to "Configuration" &amp;gt; "General settings"&lt;/li&gt;
&lt;li&gt;In the "Startup Command" field, enter your start command:

&lt;ul&gt;
&lt;li&gt;For apps using a build directory: &lt;code&gt;node build/server.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For apps using an express server: &lt;code&gt;npm start&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click "Save"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Backend applications typically require environment variables for database connections, API keys, and other sensitive information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your App Service, go to "Configuration" &amp;gt; "Application settings"&lt;/li&gt;
&lt;li&gt;Click "New application setting" to add each environment variable&lt;/li&gt;
&lt;li&gt;Common variables to add:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NODE_ENV&lt;/code&gt;: Set to &lt;code&gt;production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PORT&lt;/code&gt;: Usually set to &lt;code&gt;8080&lt;/code&gt; (Azure will map this to the public port)&lt;/li&gt;
&lt;li&gt;Database connection strings&lt;/li&gt;
&lt;li&gt;API keys and secrets&lt;/li&gt;
&lt;li&gt;Authentication parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click "Save" after adding all variables&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. Configure CORS (if needed)
&lt;/h3&gt;

&lt;p&gt;If your backend API serves a frontend hosted elsewhere:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your App Service, go to "CORS"&lt;/li&gt;
&lt;li&gt;Add the domains that should be allowed to access your API&lt;/li&gt;
&lt;li&gt;Click "Save"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  5. Set up Deployment Credentials
&lt;/h3&gt;

&lt;p&gt;For the Bitbucket pipeline to deploy to Azure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Azure Portal, go to Azure Active Directory&lt;/li&gt;
&lt;li&gt;Register a new application&lt;/li&gt;
&lt;li&gt;Create a client secret&lt;/li&gt;
&lt;li&gt;Assign the application appropriate permissions to your resource group&lt;/li&gt;
&lt;li&gt;Note down:

&lt;ul&gt;
&lt;li&gt;Application (client) ID&lt;/li&gt;
&lt;li&gt;Directory (tenant) ID&lt;/li&gt;
&lt;li&gt;Client secret&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These values will be used as the &lt;code&gt;AZURE_APP_ID&lt;/code&gt;, &lt;code&gt;AZURE_TENANT_ID&lt;/code&gt;, and &lt;code&gt;AZURE_PASSWORD&lt;/code&gt; in your Bitbucket pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Configure Bitbucket Repository Variables
&lt;/h3&gt;

&lt;p&gt;In Bitbucket:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Repository settings &amp;gt; Repository variables&lt;/li&gt;
&lt;li&gt;Add the following variables:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AZURE_APP_ID&lt;/code&gt;: Your Azure service principal ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_PASSWORD&lt;/code&gt;: Your Azure service principal password&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_TENANT_ID&lt;/code&gt;: Your Azure tenant ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_RESOURCE_GROUP&lt;/code&gt;: The resource group containing your App Service&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_APP_NAME&lt;/code&gt;: The name of your App Service&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Handling Backend-Specific Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Node.js Version Compatibility
&lt;/h3&gt;

&lt;p&gt;Azure App Service supports specific Node.js versions. Ensure your application is compatible with the available versions in Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: In your Azure App Service settings, go to "Configuration" &amp;gt; "General settings" and select the appropriate Node.js version. &lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 2: Server Startup Detection
&lt;/h3&gt;

&lt;p&gt;Azure App Service needs to detect when your Node.js application has successfully started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Ensure your application listens on the port provided by the environment:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;h3&gt;
  
  
  Challenge 3: Application Logging
&lt;/h3&gt;

&lt;p&gt;Troubleshooting deployment issues requires proper logging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Enable application logging in Azure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your App Service &amp;gt; "App Service logs"&lt;/li&gt;
&lt;li&gt;Enable "Application logging"&lt;/li&gt;
&lt;li&gt;Set the log level to "Information" or "Verbose"&lt;/li&gt;
&lt;li&gt;Enable "File System" logging&lt;/li&gt;
&lt;li&gt;Click "Save"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can then view logs in the "Log stream" section or download them for analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the Deployment
&lt;/h2&gt;

&lt;p&gt;After deploying, verify that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your application is running by accessing the Azure App Service URL&lt;/li&gt;
&lt;li&gt;API endpoints are accessible and returning expected responses&lt;/li&gt;
&lt;li&gt;Environment variables are correctly loaded&lt;/li&gt;
&lt;li&gt;Your application can connect to external services (databases, etc.)&lt;/li&gt;
&lt;li&gt;Logs show no errors or warnings&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Deploying a Node.js backend to Azure App Service using Bitbucket Pipelines provides a robust and automated deployment solution. By properly configuring both the pipeline and the Azure environment, you can ensure smooth and reliable deployments.&lt;/p&gt;

&lt;p&gt;The key takeaways are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Include all necessary files in your deployment package&lt;/li&gt;
&lt;li&gt;Configure the correct startup command in Azure&lt;/li&gt;
&lt;li&gt;Set up environment variables for your application&lt;/li&gt;
&lt;li&gt;Configure CORS if needed&lt;/li&gt;
&lt;li&gt;Enable proper logging for troubleshooting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this setup, your backend deployments will be consistent, reliable, and easy to manage.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>bitbucket</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Deploying a Frontend Application to Azure App Service with Bitbucket CI/CD Pipeline</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Wed, 19 Mar 2025 10:50:46 +0000</pubDate>
      <link>https://dev.to/anshul_02/deploying-a-frontend-application-to-azure-app-service-with-bitbucket-cicd-pipeline-7p8</link>
      <guid>https://dev.to/anshul_02/deploying-a-frontend-application-to-azure-app-service-with-bitbucket-cicd-pipeline-7p8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Deploying frontend applications to production environments can be challenging, especially when dealing with single-page applications (SPAs) like React. In this blog post, I'll walk through the process of setting up a complete CI/CD pipeline for deploying a frontend application to Azure App Service using Bitbucket Pipelines, and how to overcome common challenges like path mapping and URL rewriting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, make sure you have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Bitbucket repository with your frontend code&lt;/li&gt;
&lt;li&gt;An Azure subscription&lt;/li&gt;
&lt;li&gt;An Azure App Service plan and web app&lt;/li&gt;
&lt;li&gt;Service principal credentials for Azure deployment&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding the Pipeline Architecture
&lt;/h2&gt;

&lt;p&gt;Our deployment pipeline follows these key steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install dependencies&lt;/strong&gt; - Prepare the environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel processes&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build the application&lt;/strong&gt; - Compile, bundle, and package the app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security scan&lt;/strong&gt; - Check for sensitive data in code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual deployment trigger&lt;/strong&gt; - Deploy to production with approval&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Bitbucket Pipeline Configuration
&lt;/h2&gt;

&lt;p&gt;Here's our complete &lt;code&gt;bitbucket-pipelines.yml&lt;/code&gt; file:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:20&lt;/span&gt;

&lt;span class="na"&gt;pipelines&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install&lt;/span&gt;
        &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -rf node_modules package-lock.json&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --legacy-peer-deps&lt;/span&gt; 

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
          &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -rf node_modules package-lock.json&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --legacy-peer-deps&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;              
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mv web.config dist/&lt;/span&gt;  &lt;span class="c1"&gt;# Move web.config inside dist/&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt update &amp;amp;&amp;amp; apt install zip&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zip -r app-$BITBUCKET_BUILD_NUMBER.zip dist package.json -x *.git* bitbucket-pipelines.yml&lt;/span&gt;
          &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.zip"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security Scan&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Run a security scan for sensitive data.&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/git-secrets-scan:0.5.1&lt;/span&gt;            

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
        &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;manual&lt;/span&gt;
        &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/azure-web-apps-deploy:1.2.3&lt;/span&gt;
            &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;AZURE_APP_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_ID&lt;/span&gt;
              &lt;span class="na"&gt;AZURE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;AZURE_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_TENANT_ID&lt;/span&gt;
              &lt;span class="na"&gt;AZURE_RESOURCE_GROUP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_RESOURCE_GROUP&lt;/span&gt;
              &lt;span class="na"&gt;AZURE_APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_NAME&lt;/span&gt;
              &lt;span class="na"&gt;ZIP_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app-$BITBUCKET_BUILD_NUMBER.zip'&lt;/span&gt;
              &lt;span class="na"&gt;DEBUG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down each section:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install&lt;/span&gt;
    &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -rf node_modules package-lock.json&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --legacy-peer-deps&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step cleans any existing dependencies and installs fresh ones. The &lt;code&gt;--legacy-peer-deps&lt;/code&gt; flag helps avoid compatibility issues between packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Parallel Execution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
      &lt;span class="na"&gt;caches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -rf node_modules package-lock.json&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install --legacy-peer-deps&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;              
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mv web.config dist/&lt;/span&gt;  &lt;span class="c1"&gt;# Move web.config inside dist/&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt update &amp;amp;&amp;amp; apt install zip&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;zip -r app-$BITBUCKET_BUILD_NUMBER.zip dist package.json -x *.git* bitbucket-pipelines.yml&lt;/span&gt;
      &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.zip"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security Scan&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/git-secrets-scan:0.5.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section runs two processes in parallel:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build&lt;/strong&gt;: Compiles the frontend application and packages it for deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Scan&lt;/strong&gt;: Checks the codebase for accidentally committed secrets or sensitive data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The build step is particularly important as it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builds the application&lt;/li&gt;
&lt;li&gt;Moves the &lt;code&gt;web.config&lt;/code&gt; file into the distribution folder&lt;/li&gt;
&lt;li&gt;Creates a zip archive with a unique name based on the build number&lt;/li&gt;
&lt;li&gt;Defines the zip file as an artifact to be used in later steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
    &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;manual&lt;/span&gt;
    &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;atlassian/azure-web-apps-deploy:1.2.3&lt;/span&gt;
        &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_APP_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_ID&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_TENANT_ID&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_RESOURCE_GROUP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_RESOURCE_GROUP&lt;/span&gt;
          &lt;span class="na"&gt;AZURE_APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$AZURE_APP_NAME&lt;/span&gt;
          &lt;span class="na"&gt;ZIP_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app-$BITBUCKET_BUILD_NUMBER.zip'&lt;/span&gt;
          &lt;span class="na"&gt;DEBUG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has a manual trigger for controlled deployments&lt;/li&gt;
&lt;li&gt;Uses the Atlassian Azure Web Apps Deploy pipe&lt;/li&gt;
&lt;li&gt;Passes necessary Azure credentials stored as repository variables&lt;/li&gt;
&lt;li&gt;Specifies the zip file created in the build step&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuring web.config for React SPA on Azure
&lt;/h2&gt;

&lt;p&gt;One of the most challenging aspects of deploying a React SPA to Azure App Service is configuring URL rewriting correctly. Since SPAs use client-side routing, all routes need to be redirected to the &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here's the &lt;code&gt;web.config&lt;/code&gt; file we're using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;system.webServer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;rewrite&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;rule&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"React SPA"&lt;/span&gt; &lt;span class="na"&gt;stopProcessing=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;match&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;".*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;conditions&lt;/span&gt; &lt;span class="na"&gt;logicalGrouping=&lt;/span&gt;&lt;span class="s"&gt;"MatchAll"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"{REQUEST_FILENAME}"&lt;/span&gt; &lt;span class="na"&gt;matchType=&lt;/span&gt;&lt;span class="s"&gt;"IsFile"&lt;/span&gt; &lt;span class="na"&gt;negate=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"{REQUEST_FILENAME}"&lt;/span&gt; &lt;span class="na"&gt;matchType=&lt;/span&gt;&lt;span class="s"&gt;"IsDirectory"&lt;/span&gt; &lt;span class="na"&gt;negate=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/conditions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"Rewrite"&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;"/index.html"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/rule&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/rewrite&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;staticContent&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mimeMap&lt;/span&gt; &lt;span class="na"&gt;fileExtension=&lt;/span&gt;&lt;span class="s"&gt;".json"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mimeMap&lt;/span&gt; &lt;span class="na"&gt;fileExtension=&lt;/span&gt;&lt;span class="s"&gt;".js"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"application/javascript"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mimeMap&lt;/span&gt; &lt;span class="na"&gt;fileExtension=&lt;/span&gt;&lt;span class="s"&gt;".css"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mimeMap&lt;/span&gt; &lt;span class="na"&gt;fileExtension=&lt;/span&gt;&lt;span class="s"&gt;".ts"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"application/javascript"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mimeMap&lt;/span&gt; &lt;span class="na"&gt;fileExtension=&lt;/span&gt;&lt;span class="s"&gt;".tsx"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"application/javascript"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/staticContent&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;httpProtocol&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;customHeaders&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Origin"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"X-Content-Type-Options"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"nosniff"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/customHeaders&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/httpProtocol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/system.webServer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding the web.config configuration
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;URL Rewriting&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The rule matches all URLs (&lt;code&gt;match url=".*"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;It applies only when the requested URL doesn't match an existing file or directory&lt;/li&gt;
&lt;li&gt;It redirects all such requests to &lt;code&gt;/index.html&lt;/code&gt;, allowing the React router to handle them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MIME Type Configuration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures proper MIME types for various file extensions&lt;/li&gt;
&lt;li&gt;Critical for browsers to correctly interpret JavaScript, CSS, and JSON files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HTTP Headers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt; - Enables cross-origin resource sharing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt; - Prevents MIME type sniffing security vulnerabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Overcoming Common Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Path Mapping Differences in Azure
&lt;/h3&gt;

&lt;p&gt;Azure App Service has a unique architecture that uses different virtual and physical path mappings, which can cause issues when deploying frontend applications:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding Azure's Path Structure&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Physical Path&lt;/strong&gt;: The actual location on the server where your files are stored (e.g., &lt;code&gt;D:\home\site\wwwroot&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Path&lt;/strong&gt;: The URL path that users access (e.g., &lt;code&gt;https://yourapp.azurewebsites.net/path&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Root Path Configuration&lt;/strong&gt;: By default, Azure deploys your application to the root of the App Service (&lt;code&gt;/&lt;/code&gt;). If your frontend expects to be served from a subdirectory, path conflicts will occur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Virtual Directory Mapping&lt;/strong&gt;: Azure allows you to map different physical folders to different virtual paths through the Azure Portal or configuration files.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;In the Azure Portal, navigate to your App Service → Configuration → Path mappings&lt;/li&gt;
&lt;li&gt;Ensure your application files are correctly mapped to the appropriate virtual path&lt;/li&gt;
&lt;li&gt;For single-page applications, make sure the root directory (&lt;code&gt;/&lt;/code&gt;) is correctly mapped to your application's distribution folder&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alternatively, you can define virtual applications and directories in your &lt;code&gt;web.config&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;system.webServer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;virtualDirectory&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;physicalPath=&lt;/span&gt;&lt;span class="s"&gt;"%SystemDrive%\home\site\wwwroot\dist"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Other configurations --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/system.webServer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that when a user accesses the root URL, they're served content from the &lt;code&gt;dist&lt;/code&gt; folder where your built frontend application resides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 2: Web.config Configuration
&lt;/h3&gt;

&lt;p&gt;The biggest challenge is often configuring the web.config file correctly for client-side routing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Our web.config file above solves this by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using the URL Rewrite module to redirect all non-file, non-directory requests to index.html&lt;/li&gt;
&lt;li&gt;Configuring proper MIME types for all static assets&lt;/li&gt;
&lt;li&gt;Setting appropriate HTTP headers for security and cross-origin requests&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting Up Azure Environment Variables
&lt;/h2&gt;

&lt;p&gt;For the deployment to work, you need to configure these repository variables in Bitbucket:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AZURE_APP_ID&lt;/code&gt;: Your Azure service principal ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_PASSWORD&lt;/code&gt;: Your Azure service principal password&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_TENANT_ID&lt;/code&gt;: Your Azure tenant ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_RESOURCE_GROUP&lt;/code&gt;: The resource group containing your App Service&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_APP_NAME&lt;/code&gt;: The name of your App Service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can set these variables in Bitbucket by going to:&lt;br&gt;
Repository settings &amp;gt; Repository variables&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the Deployment
&lt;/h2&gt;

&lt;p&gt;After deploying, you should verify that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your application loads correctly&lt;/li&gt;
&lt;li&gt;Deep linking works (you can navigate directly to any route)&lt;/li&gt;
&lt;li&gt;Static assets (images, CSS, JavaScript) load properly&lt;/li&gt;
&lt;li&gt;API calls work as expected&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Deploying a frontend application to Azure App Service using Bitbucket Pipelines provides a robust and automated deployment workflow. The key challenges around path mapping and web.config configuration can be overcome with proper configuration.&lt;/p&gt;

&lt;p&gt;By following this guide, you'll have a reliable CI/CD pipeline that builds, tests, and deploys your frontend application to Azure App Service, with proper routing for single-page applications.&lt;/p&gt;

&lt;p&gt;Remember that the most critical parts are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The correct web.config configuration&lt;/li&gt;
&lt;li&gt;Proper understanding of Azure's virtual and physical path mapping&lt;/li&gt;
&lt;li&gt;Secure handling of Azure credentials&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these in place, your deployments should be smooth and reliable.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Migrations with Sequelize-Typescript</title>
      <dc:creator>Anshul Jangale</dc:creator>
      <pubDate>Mon, 17 Mar 2025 10:44:20 +0000</pubDate>
      <link>https://dev.to/anshul_02/migrations-with-sequelize-typescript-174j</link>
      <guid>https://dev.to/anshul_02/migrations-with-sequelize-typescript-174j</guid>
      <description>&lt;p&gt;Sequelize is a popular ORM for Node.js, but using it with TypeScript—especially for migrations—can be challenging. This guide will walk you through setting up Sequelize properly with TypeScript, focusing on database migrations.&lt;/p&gt;

&lt;p&gt;Sequelize officially supports TypeScript, but its Sequelize-cli tool generates JavaScript files for migrations. This creates several issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript errors in your project&lt;/li&gt;
&lt;li&gt;ESLint parsing errors&lt;/li&gt;
&lt;li&gt;Inconsistent codebase with mixed JS/TS files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution Overview&lt;/strong&gt;&lt;br&gt;
We'll implement a proper TypeScript setup for Sequelize migrations by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a custom .sequelizerc configuration&lt;/li&gt;
&lt;li&gt;Setting up a workflow for TypeScript migrations&lt;/li&gt;
&lt;li&gt;Configuring project files correctly&lt;/li&gt;
&lt;li&gt;Creating a script to automate migration generation&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;
  
  
  Step 1: Project Setup
&lt;/h1&gt;

&lt;p&gt;First, ensure your tsconfig.json is properly configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "compilerOptions": {
    "target": "es2016",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "commonjs",
    "rootDir": "./src",
    "baseUrl": "./",
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "exclude": ["node_modules", "__tests__"],
  "include": ["src/**/*.ts"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Create a Custom .sequelizerc File
&lt;/h1&gt;

&lt;p&gt;Create a .sequelizerc file in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { resolve } = require('path');

module.exports = {
    config: resolve('build/db/config.js'),
    'seeders-path': resolve('build/db/seeders'),
    'migrations-path': resolve('build/db/migrations'),
    'models-path': resolve('db/models')
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: TypeScript Migration Workflow
&lt;/h1&gt;

&lt;p&gt;To create and run migrations with TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate migration files using the CLI:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npx sequelize-cli migration:create --name add-some-table&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The migration file will be generated in "build/db/migrations". Move the generated file to your actual application TypeScript migrations folder and rename it with a .ts extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the content with this TypeScript template:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { QueryInterface, DataTypes, QueryTypes } from 'sequelize';

/** @type {import("sequelize-cli").Migration} */
module.exports = {
    up: (queryInterface: QueryInterface): Promise&amp;lt;void&amp;gt; =&amp;gt; queryInterface.sequelize.transaction(
        async (transaction) =&amp;gt; {
          // here go all migration changes
        }
    ),

    down: (queryInterface: QueryInterface): Promise&amp;lt;void&amp;gt; =&amp;gt; queryInterface.sequelize.transaction(
        async (transaction) =&amp;gt; {
          // here go all migration undo changes
        }
    )
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;add necessary changes to the migration file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OR ANOTHER OPTION (RUNNING SCRIPT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TO AUTOMATE THIS STEP YOU CAN CREATE A SCRIPT WHICH WILL AUTOMATICALLY CREATE THIS FILE &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate migration files using the CLI:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npx sequelize-cli migration:create --name add-some-table&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import fs from 'fs';
import path from 'path';

// Get migration name from command-line arguments
const migrationName = process.argv[2];

if (!migrationName) {
  console.error('❌ Please provide a migration name.');
  process.exit(1);
}

// Define paths
const migrationsDir = path.resolve(__dirname, 'db/migrations');
const timestamp = new Date().toISOString().replace(/\D/g, '').slice(0, 14); // YYYYMMDDHHMMSS
const fileName = `${timestamp}-${migrationName}.ts`;
const filePath = path.join(migrationsDir, fileName);

// Migration template
const migrationTemplate = `import { QueryInterface, DataTypes } from "sequelize";

/** @type {import("sequelize-cli").Migration} */
export default {
  up: async (queryInterface: QueryInterface): Promise&amp;lt;void&amp;gt; =&amp;gt; {
    await queryInterface.sequelize.transaction(async (transaction) =&amp;gt; {

    //your code here 

    });
  },

  down: async (queryInterface: QueryInterface): Promise&amp;lt;void&amp;gt; =&amp;gt; {
    await queryInterface.sequelize.transaction(async (transaction) =&amp;gt; {

      //your code here

    });
  },
};

`;

// Ensure migrations directory exists
if (!fs.existsSync(migrationsDir)) {
  fs.mkdirSync(migrationsDir, { recursive: true });
}

// Write migration file
fs.writeFileSync(filePath, migrationTemplate);

console.log(`✅ Migration created: ${filePath}`);

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

&lt;/div&gt;



&lt;p&gt;To run this script: &lt;br&gt;
npx ts-node path/to/generateMigration.ts add-some-table&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 4: Running Migrations
&lt;/h1&gt;

&lt;p&gt;To run migrations, you need to:&lt;/p&gt;

&lt;p&gt;Compile your TypeScript files&lt;br&gt;
Run the migrations on the compiled JavaScript files&lt;/p&gt;

&lt;p&gt;Add these scripts to your package.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
"scripts": {
  "dev": "ts-node-dev --respawn --transpile-only src/index.ts",
  "build": "tsc -p .",
  "start": "node build/dist/index.js",
  "prestart": "npm install --production",
  "migrate:generate":"npx ts-node src/generateMigration.ts",
  "migrate": "tsc -p . &amp;amp; npx sequelize-cli db:migrate ",
  "migrate:undo": "npx sequelize-cli db:migrate:undo ",
  "migrate:undo:all": "npx sequelize-cli db:migrate:undo:all "
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;By following these steps, you've successfully set up Sequelize with TypeScript for migrations. This approach gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type safety in your migrations&lt;/li&gt;
&lt;li&gt;Consistent codebase with TypeScript throughout&lt;/li&gt;
&lt;li&gt;Properly working ESLint&lt;/li&gt;
&lt;li&gt;Streamlined migration workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your development process is now more robust and you can enjoy the benefits of TypeScript while using Sequelize migrations.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
