<?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: Antonio Cardenas </title>
    <description>The latest articles on DEV Community by Antonio Cardenas  (@antoniocardenas).</description>
    <link>https://dev.to/antoniocardenas</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%2F175287%2F355839ae-97e4-4466-8e8e-53a4b48782f4.jpg</url>
      <title>DEV Community: Antonio Cardenas </title>
      <link>https://dev.to/antoniocardenas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antoniocardenas"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Fri, 03 Apr 2026 07:42:13 +0000</pubDate>
      <link>https://dev.to/antoniocardenas/-42e5</link>
      <guid>https://dev.to/antoniocardenas/-42e5</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/angular/whats-new-in-taiga-ui-v5-a-modern-angular-ui-kit-7lm" class="crayons-story__hidden-navigation-link"&gt;What's New in Taiga UI v5: A Modern Angular UI Kit&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/angular"&gt;
            &lt;img alt="Angular logo" 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%2Forganization%2Fprofile_image%2F802%2F39aa2792-6183-496a-8513-1a38c76dbfb6.png" class="crayons-logo__image" width="800" height="800"&gt;
          &lt;/a&gt;

          &lt;a href="/nsbarsukov" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F857015%2F62fc9803-5d13-4219-8601-661ca0ee3241.jpg" alt="nsbarsukov profile" class="crayons-avatar__image" width="800" height="1066"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/nsbarsukov" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Barsukov Nikita
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Barsukov Nikita
                
              
              &lt;div id="story-author-preview-content-3448416" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/nsbarsukov" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F857015%2F62fc9803-5d13-4219-8601-661ca0ee3241.jpg" class="crayons-avatar__image" alt="" width="800" height="1066"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Barsukov Nikita&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/angular" class="crayons-story__secondary fw-medium"&gt;Angular&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/angular/whats-new-in-taiga-ui-v5-a-modern-angular-ui-kit-7lm" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 3&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/angular/whats-new-in-taiga-ui-v5-a-modern-angular-ui-kit-7lm" id="article-link-3448416"&gt;
          What's New in Taiga UI v5: A Modern Angular UI Kit
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/angular"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;angular&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/frontend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;frontend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/angular/whats-new-in-taiga-ui-v5-a-modern-angular-ui-kit-7lm" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/angular/whats-new-in-taiga-ui-v5-a-modern-angular-ui-kit-7lm#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            13 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Wed, 25 Mar 2026 23:50:01 +0000</pubDate>
      <link>https://dev.to/antoniocardenas/-5dcp</link>
      <guid>https://dev.to/antoniocardenas/-5dcp</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dezkareid/sincronizando-mi-agentsmd-4e0c" class="crayons-story__hidden-navigation-link"&gt;Sincronizando mi AGENTS.md&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dezkareid" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F461615%2Fb7e9c050-6fa6-4365-b06a-48ceb6c71ea3.jpg" alt="dezkareid profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dezkareid" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Joel Humberto Gómez Paredes
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Joel Humberto Gómez Paredes
                
              
              &lt;div id="story-author-preview-content-3249844" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dezkareid" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F461615%2Fb7e9c050-6fa6-4365-b06a-48ceb6c71ea3.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Joel Humberto Gómez Paredes&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dezkareid/sincronizando-mi-agentsmd-4e0c" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 11&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dezkareid/sincronizando-mi-agentsmd-4e0c" id="article-link-3249844"&gt;
          Sincronizando mi AGENTS.md
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwaredevelopment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwaredevelopment&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/dezkareid/sincronizando-mi-agentsmd-4e0c" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/dezkareid/sincronizando-mi-agentsmd-4e0c#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Mon, 23 Mar 2026 07:35:27 +0000</pubDate>
      <link>https://dev.to/antoniocardenas/-11m1</link>
      <guid>https://dev.to/antoniocardenas/-11m1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck" class="crayons-story__hidden-navigation-link"&gt;MCP Skills vs MCP Tools: La forma correcta de configurar MCP Server&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/angularfirebase"&gt;
            &lt;img alt="Angular Firebase logo" 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%2Forganization%2Fprofile_image%2F821%2Fd43c326b-2812-4d5d-a7e0-f13d3a9567d7.png" class="crayons-logo__image" width="768" height="768"&gt;
          &lt;/a&gt;

          &lt;a href="/antoniocardenas" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F175287%2F355839ae-97e4-4466-8e8e-53a4b48782f4.jpg" alt="antoniocardenas profile" class="crayons-avatar__image" width="625" height="625"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/antoniocardenas" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Antonio Cardenas 
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Antonio Cardenas 
                
              
              &lt;div id="story-author-preview-content-3383081" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/antoniocardenas" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F175287%2F355839ae-97e4-4466-8e8e-53a4b48782f4.jpg" class="crayons-avatar__image" alt="" width="625" height="625"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Antonio Cardenas &lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/angularfirebase" class="crayons-story__secondary fw-medium"&gt;Angular Firebase&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 22&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck" id="article-link-3383081"&gt;
          MCP Skills vs MCP Tools: La forma correcta de configurar MCP Server
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/angular"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;angular&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/spanish"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;spanish&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>angular</category>
      <category>mcp</category>
      <category>spanish</category>
      <category>webdev</category>
    </item>
    <item>
      <title>MCP Skills vs MCP Tools: La forma correcta de configurar MCP Server</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 22 Mar 2026 08:59:35 +0000</pubDate>
      <link>https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck</link>
      <guid>https://dev.to/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Las skills y las herramientas MCP no son lo mismo — y confundirlos tiene un costo real. Aprende la diferencia, los problemas reales y cómo combinarlos para un flujo de trabajo agéntico que sí funcione.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Todo el mundo habla de MCP. Todo el mundo habla de skills.&lt;/p&gt;

&lt;p&gt;La mayoría los usa como sinónimos — y ese es exactamente el problema.&lt;/p&gt;

&lt;p&gt;No son lo mismo. No resuelven el mismo problema. Y si usas el incorrecto, lo vas a sentir: alucinaciones, contexto desbordado, agentes que pierden el hilo y flujos de trabajo que se rompen bajo presión.&lt;/p&gt;

&lt;p&gt;Vamos a resolverlo.&lt;/p&gt;




&lt;h2&gt;
  
  
  El modelo mental
&lt;/h2&gt;

&lt;p&gt;Piénsalo como una cocina.&lt;/p&gt;

&lt;p&gt;Las &lt;strong&gt;herramientas MCP&lt;/strong&gt; son tus electrodomésticos e ingredientes — el horno, el refrigerador, los vegetales frescos. Capacidad pura. Sin ellos, no se cocina nada.&lt;/p&gt;

&lt;p&gt;Los &lt;strong&gt;skills&lt;/strong&gt; son tus recetas — las instrucciones paso a paso que le dicen a un chef exactamente cómo convertir esos ingredientes en algo bueno. Sin ellas, tienes poder, pero sin dirección.&lt;/p&gt;

&lt;p&gt;Un agente con solo herramientas MCP &lt;em&gt;puede&lt;/em&gt; hacer cosas, pero no necesariamente sabe &lt;em&gt;cómo&lt;/em&gt; hacerlas bien. Un agente con solo skills tiene excelentes instrucciones, pero no puede actuar sobre ellas.&lt;/p&gt;

&lt;p&gt;Necesitas los dos.&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Qué es una herramienta MCP?
&lt;/h2&gt;

&lt;p&gt;El &lt;strong&gt;Model Context Protocol&lt;/strong&gt; es un estándar abierto — ahora bajo la Agentic AI Foundation de la Linux Foundation — que le da a los agentes de IA una forma estandarizada de conectarse a sistemas externos: bases de datos, APIs, sistemas de archivos, GitHub, Slack, tu Angular CLI.&lt;/p&gt;

&lt;p&gt;Cuando conectas un servidor MCP a tu cliente —ya sea Claude Code, la CLI de Gemini o un agente personalizado—, este accede a un conjunto de &lt;strong&gt;herramientas deterministas y tipadas&lt;/strong&gt;. Cada herramienta tiene un esquema claro de entrada y salida. Cuando el agente la llama, se ejecuta — sin interpretación, sin riesgo de alucinación a nivel de ejecución. Es una llamada de API estructurada, no una sugerencia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP es como el agente &lt;em&gt;alcanza fuera de sí mismo&lt;/em&gt;. Es el sistema nervioso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usa MCP cuando el agente necesite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leer o escribir en un sistema real (base de datos, sistema de archivos, API)&lt;/li&gt;
&lt;li&gt;Ejecutar acciones con entradas y salidas claras y auditables.&lt;/li&gt;
&lt;li&gt;Conectarse a herramientas que no controlas&lt;/li&gt;
&lt;li&gt;Integrar múltiples servicios a través de una interfaz consistente.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué es un skill?
&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;skill&lt;/strong&gt; es una carpeta que contiene un archivo Markdown (con frontmatter YAML) más scripts y recursos opcionales. No es ejecutable por sí solo — es un playbook.&lt;/p&gt;

&lt;p&gt;Cuando la solicitud de un usuario coincide con los criterios de relevancia de un skill, el agente carga esas instrucciones dinámicamente y las sigue. Es como darle al agente memoria procedural de nivel experto, bajo demanda.&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="nn"&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;angular-component-review&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Revisar componentes Angular para cumplimiento de Signals y arquitectura standalone&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Revisión de Componente Angular&lt;/span&gt;

Al revisar un componente Angular:
&lt;span class="p"&gt;1.&lt;/span&gt; Verificar que todo el estado use &lt;span class="sb"&gt;`signal()`&lt;/span&gt; o &lt;span class="sb"&gt;`computed()`&lt;/span&gt; — nunca mutación directa
&lt;span class="p"&gt;2.&lt;/span&gt; Confirmar que el componente es &lt;span class="sb"&gt;`standalone: true`&lt;/span&gt;
&lt;span class="p"&gt;3.&lt;/span&gt; Asegurar que no queden dependencias de &lt;span class="sb"&gt;`NgModule`&lt;/span&gt;
&lt;span class="p"&gt;4.&lt;/span&gt; Validar que se use &lt;span class="sb"&gt;`@if`&lt;/span&gt; / &lt;span class="sb"&gt;`@for`&lt;/span&gt; en lugar de &lt;span class="sb"&gt;`*ngIf`&lt;/span&gt; / &lt;span class="sb"&gt;`*ngFor`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente lo carga solo cuando es relevante. Cuando no lo es — no te cuesta nada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usa un skill cuando el agente lo necesite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seguir un proceso o checklist consistente.&lt;/li&gt;
&lt;li&gt;Aplicar experiencia específica del dominio (tus estándares de código, criterios de revisión).&lt;/li&gt;
&lt;li&gt;Codificar conocimiento que no cambia frecuentemente.&lt;/li&gt;
&lt;li&gt;Reutilizar el mismo flujo de trabajo en distintas conversaciones.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Los desventajas reales
&lt;/h2&gt;

&lt;p&gt;Aquí es donde la mayoría de las guías se detienen. No deberían.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: El Impuesto de Tokens
&lt;/h3&gt;

&lt;p&gt;Cada herramienta MCP que conectas inyecta su esquema completo en la ventana de contexto &lt;em&gt;antes de que el agente procese un solo mensaje&lt;/em&gt;. Cada herramienta cuesta 550–1,400 tokens. Conecta GitHub, Slack y Sentry y estás mirando &lt;strong&gt;55,000 tokens quemados de entrada&lt;/strong&gt; — más de un cuarto del límite de 200k de Claude antes de hacer cualquier trabajo real.&lt;/p&gt;

&lt;p&gt;Un equipo reportó conectar tres servidores MCP y consumir &lt;strong&gt;143,000 de 200,000 tokens&lt;/strong&gt; solo en definiciones de herramientas. Al agente le quedaban 57,000 tokens para la conversación real.&lt;/p&gt;

&lt;p&gt;Y si usas Gemini con su ventana de contexto de 1M+ tokens, podrías pensar que puedes ignorar esto. No lo hagas. Incluso si te sobra espacio, inyectar 55,000 tokens de esquema JSON crudo en cada iteración de la conversación aumenta la latencia, incrementa los costos de la API y diluye el enfoque del modelo.&lt;/p&gt;

&lt;p&gt;La buena noticia: clientes modernos como Claude Code y la CLI de Gemini han adoptado el &lt;strong&gt;progressive discovery&lt;/strong&gt; para MCP — cargando solo nombres y descripciones de herramientas al inicio (~20–50 tokens cada una), y obteniendo los esquemas completos solo cuando el agente realmente necesita una herramienta. El overhead de tokens cayó ~85%. Pero esto solo funciona si tu configuración MCP está preparada para usarlo — y la mayoría todavía no lo está.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skills: El Problema de la Desactualización
&lt;/h3&gt;

&lt;p&gt;Los skills son archivos Markdown. No se actualizan solos. Si tus patrones de Angular evolucionan — digamos que migraste de &lt;code&gt;setInput()&lt;/code&gt; a la nueva API declarativa en Angular 20 — tu Skill sigue enseñando la forma antigua hasta que alguien lo actualice manualmente.&lt;/p&gt;

&lt;p&gt;Cuantos más skills creas, mayor es la carga de mantenimiento. Y si un skill está sutilmente equivocado, el agente lo seguirá con confianza — sin error, solo output silenciosamente incorrecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambos: El problema de selección
&lt;/h3&gt;

&lt;p&gt;Dale a un agente demasiadas herramientas o demasiados skills y empieza a tomar las decisiones equivocadas — llama a la herramienta incorrecta, activa el playbook equivocado, o los combina de formas que producen instrucciones contradictorias. Los expertos recomiendan no superar &lt;strong&gt;10–15 herramientas MCP activas&lt;/strong&gt; al mismo tiempo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cómo combinarlos
&lt;/h2&gt;

&lt;p&gt;El patrón más poderoso es usarlos como capas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 1 — MCP provee acceso.&lt;/strong&gt;&lt;br&gt;
Conecta solo lo que el agente genuinamente necesita para la tarea actual. Angular CLI, una base de datos, un sistema de archivos. Mantenlo simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 2 — Skills proveen experiencia.&lt;/strong&gt;&lt;br&gt;
Crea un Skill que le diga al agente &lt;em&gt;cómo&lt;/em&gt; usar esas herramientas en tu contexto específico. No solo "ejecuta el Angular CLI" — sino "al migrar un componente, ejecuta &lt;code&gt;ng generate&lt;/code&gt; con estos flags, luego valida contra estos patrones."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 3 — Skills pueden orquestar MCP.&lt;/strong&gt;&lt;br&gt;
Un skill puede definir un flujo de trabajo multipaso que llame a múltiples herramientas MCP en secuencia. Ejemplo: un skill de "Deploy &amp;amp; Notify" que usa el MCP de GitHub para hacer push, un MCP de CI/CD para lanzar el build, y un MCP de Slack para notificar al equipo — todo bajo un playbook coherente.&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="nn"&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;angular-migration-workflow&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Flujo completo para migrar un componente Angular a patrones v21&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Flujo de Migración&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Usa el MCP del Angular CLI para verificar la versión actual del componente
&lt;span class="p"&gt;2.&lt;/span&gt; Ejecuta &lt;span class="sb"&gt;`ng update`&lt;/span&gt; para el paquete afectado
&lt;span class="p"&gt;3.&lt;/span&gt; Aplica el schematic de migración zoneless
&lt;span class="p"&gt;4.&lt;/span&gt; Revisa el output contra el Skill de angular-component-review
&lt;span class="p"&gt;5.&lt;/span&gt; Ejecuta los tests y reporta resultados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Guía de Decisión Práctica
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situación&lt;/th&gt;
&lt;th&gt;Usar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Necesito consultar una base de datos real&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito seguir un checklist de code review&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito hacer push a GitHub&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito aplicar el formato de commits de mi equipo&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito leer una API en vivo&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito enseñarle al agente mis reglas de arquitectura Angular&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito acceso Y proceso consistente&lt;/td&gt;
&lt;td&gt;Ambos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Mejorando el Flujo de Trabajo
&lt;/h2&gt;

&lt;p&gt;Algunos patrones que realmente funcionan en producción:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Un servidor MCP por dominio.&lt;/strong&gt; No cargues todo al mismo tiempo. Crea configuraciones separadas para "desarrollo Angular", "despliegue" y "comunicación" — y activa solo la que necesitas para cada sesión.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Versiona tus Skills como código.&lt;/strong&gt; Ponlos en tu repositorio. Revísalos cuando actualices tu stack. Un Skill para patrones de Angular 19 te va a perjudicar activamente en Angular 21.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Usa Skills para escribir guardrails de MCP.&lt;/strong&gt; En lugar de confiar en que el agente sepa cuándo llamar a una acción MCP destructiva, escribe un Skill que diga explícitamente: &lt;em&gt;"Antes de ejecutar cualquier &lt;code&gt;ng update&lt;/code&gt;, siempre crea un branch de git primero."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Mide tu presupuesto de contexto.&lt;/strong&gt; Antes de que el agente haga cualquier trabajo real, conoce cuántos tokens consume tu configuración MCP. Si superas el 30% de tu ventana de contexto solo en definiciones de herramientas, tienes un problema de configuración.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Deja que el agente mantenga los Skills simples.&lt;/strong&gt; Para áreas de cambio rápido — como mantener actualizadas las convenciones de versión de Angular de tu equipo — deja que el agente actualice el archivo Skill cuando se lo indiques. Es más rápido que hacerlo manualmente y mantiene el Skill honesto.&lt;/p&gt;




&lt;h2&gt;
  
  
  La conclusión
&lt;/h2&gt;

&lt;p&gt;MCP les da a los agentes la capacidad de actuar. Los skills les enseñan cómo actuar bien.&lt;/p&gt;

&lt;p&gt;El debate de "MCP vs Skills" es falso. La pregunta real es: &lt;em&gt;¿necesitas acceso, experiencia, o ambos?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;En la mayoría de los flujos de trabajo reales con Angular, necesitas los dos. Un agente que puede ejecutar tu CLI, pero no conoce tu arquitectura, es solo una forma más rápida de cometer los mismos errores. Un agente que conoce tus patrones, pero no puede tocar tu proyecto real, es solo un buscador caro.&lt;/p&gt;

&lt;p&gt;Usados juntos, con límites claros y configuración lean, son la base del desarrollo agéntico que realmente funciona.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Anteriormente escribí sobre &lt;a href="https://www.yeou.dev/articulos/angular-21-mcp-migraciones" rel="noopener noreferrer"&gt;Angular 21, MCP y el fin de las migraciones manuales&lt;/a&gt; — un buen punto de partida si eres nuevo en la configuración del servidor MCP para Angular.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>mcp</category>
      <category>spanish</category>
      <category>webdev</category>
    </item>
    <item>
      <title>MCP Skills vs MCP Tools: The Right Way to Configure Your Server</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 22 Mar 2026 08:40:00 +0000</pubDate>
      <link>https://dev.to/turingsoracle/mcp-skills-vs-mcp-tools-the-right-way-to-configure-your-server-562c</link>
      <guid>https://dev.to/turingsoracle/mcp-skills-vs-mcp-tools-the-right-way-to-configure-your-server-562c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Skills and MCP tools are not the same thing — and confusing them costs you. Learn the real difference, the real downsides, and how to combine both for a better agentic workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  MCP Skills vs MCP Tools: What's the Difference and How to Combine Them
&lt;/h1&gt;

&lt;p&gt;Everyone is talking about MCP. Everyone is talking about skills.&lt;/p&gt;

&lt;p&gt;Most people are using them interchangeably — and that's exactly the problem.&lt;/p&gt;

&lt;p&gt;They are not the same thing. They don't solve the same problem. And if you reach for the wrong one, you will feel it: hallucinations, context blowups, agents that drift off-task, and workflows that fall apart under pressure.&lt;/p&gt;

&lt;p&gt;Let's fix that.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Mental Model
&lt;/h2&gt;

&lt;p&gt;Think of it like a kitchen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP tools&lt;/strong&gt; are your appliances and ingredients — the oven, the fridge, the fresh vegetables. Raw capability. Without them, nothing gets cooked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills&lt;/strong&gt; are your recipes — the step-by-step instructions that tell a skilled chef exactly how to turn those ingredients into something good. Without them, you have power with no direction.&lt;/p&gt;

&lt;p&gt;An agent with only MCP tools can &lt;em&gt;do&lt;/em&gt; things but doesn't necessarily know &lt;em&gt;how&lt;/em&gt; to do them well. An agent with only skills has great instructions but no way to act on them.&lt;/p&gt;

&lt;p&gt;You need both.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is an MCP Tool?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Model Context Protocol&lt;/strong&gt; is an open standard — now under the Linux Foundation's Agentic AI Foundation — that gives AI agents a standardized way to connect to external systems: databases, APIs, file systems, GitHub, Slack, your Angular CLI.&lt;/p&gt;

&lt;p&gt;When you connect an MCP server to your client—whether that's Claude Code, the Gemini CLI, or a custom agent—it gets access to a set of typed, deterministic tools. Each tool has a clear input/output schema. When the agent calls it, it executes — no interpretation, no hallucination risk at the execution level. It's a structured API call, not a suggestion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP is how the agent &lt;em&gt;reaches outside itself&lt;/em&gt;. It's the nervous system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use MCP when you need the agent to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read or write to a real system (database, filesystem, API)&lt;/li&gt;
&lt;li&gt;Execute actions with clear, auditable inputs and outputs&lt;/li&gt;
&lt;li&gt;Connect to tools you don't own or control&lt;/li&gt;
&lt;li&gt;Integrate multiple services through a consistent interface&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Is a Skill?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Skill&lt;/strong&gt; is a folder containing a Markdown file (with YAML frontmatter) plus optional scripts and resources. It's not executable by itself — it's a playbook.&lt;/p&gt;

&lt;p&gt;When a user's request matches a Skill's relevance criteria, the agent loads those instructions dynamically and follows them. Think of it as giving the agent expert-level procedural memory on demand.&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="nn"&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;angular-component-review&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Review Angular components for Signal compliance and standalone architecture&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Angular Component Review&lt;/span&gt;

When reviewing an Angular component:
&lt;span class="p"&gt;1.&lt;/span&gt; Check that all state uses &lt;span class="sb"&gt;`signal()`&lt;/span&gt; or &lt;span class="sb"&gt;`computed()`&lt;/span&gt; — never direct property mutation
&lt;span class="p"&gt;2.&lt;/span&gt; Verify the component is &lt;span class="sb"&gt;`standalone: true`&lt;/span&gt;
&lt;span class="p"&gt;3.&lt;/span&gt; Confirm no &lt;span class="sb"&gt;`NgModule`&lt;/span&gt; dependencies remain
&lt;span class="p"&gt;4.&lt;/span&gt; Validate that &lt;span class="sb"&gt;`@if`&lt;/span&gt; / &lt;span class="sb"&gt;`@for`&lt;/span&gt; is used instead of &lt;span class="sb"&gt;`*ngIf`&lt;/span&gt; / &lt;span class="sb"&gt;`*ngFor`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent loads this only when it's relevant. When it's not — it costs you nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a skill when you need the agent to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow a consistent process or checklist&lt;/li&gt;
&lt;li&gt;Apply domain-specific expertise (your coding standards, review criteria)&lt;/li&gt;
&lt;li&gt;Encode knowledge that doesn't change often&lt;/li&gt;
&lt;li&gt;Reuse the same workflow across different conversations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Real Downsides
&lt;/h2&gt;

&lt;p&gt;This is where most guides stop. They shouldn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: The Token Tax
&lt;/h3&gt;

&lt;p&gt;Every MCP tool you connect injects its full schema into the context window &lt;em&gt;before the agent processes a single message&lt;/em&gt;. Each tool costs 550–1,400 tokens. Connect GitHub, Slack, and Sentry, and you're looking at &lt;strong&gt;55,000 tokens burned upfront&lt;/strong&gt; — over a quarter of Claude's 200k limit before any real work begins. And if you are using Gemini with its 1M+ token window, you might think you can just ignore this. Don't. Even if you have the space to spare, dumping 55,000 tokens of raw JSON schema into every single turn of a conversation drives up your latency, increases API costs, and dilutes the model's focus.&lt;/p&gt;

&lt;p&gt;One team reported connecting three MCP servers and consuming &lt;strong&gt;143,000 of 200,000 tokens&lt;/strong&gt; on tool definitions alone. The agent had 57,000 tokens left for the actual conversation.&lt;/p&gt;

&lt;p&gt;The good news: modern clients like Claude Code and the Gemini CLI have adopted progressive discovery for MCP—loading only tool names and descriptions upfront (~20–50 tokens each) and fetching full schemas only when the agent actually needs a tool. Token overhead declined by ~85%. But this feature only works if your MCP setup is configured to use it, and most setups still aren't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skills: The Staleness Problem
&lt;/h3&gt;

&lt;p&gt;Skills are Markdown files. They don't update themselves. If your Angular patterns evolve — say you migrate from &lt;code&gt;setInput()&lt;/code&gt; to the new declarative API in Angular 20 — your Skill still teaches the old way until someone updates it manually.&lt;/p&gt;

&lt;p&gt;The more skills you create, the more maintenance burden you carry. And if a skill is subtly wrong, the agent will follow it confidently — no error, just quietly incorrect output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Both: The Selection Problem
&lt;/h3&gt;

&lt;p&gt;Give an agent too many tools or too many skills, and it starts making the wrong choices — calling the wrong tool, triggering the wrong playbook, or combining them in ways that produce contradictory instructions. Experts recommend staying under &lt;strong&gt;10–15 active MCP tools&lt;/strong&gt; at any time.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Combine Them
&lt;/h2&gt;

&lt;p&gt;The most powerful pattern is using them as layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — MCP provides access.&lt;/strong&gt;&lt;br&gt;
Connect only what the agent genuinely needs for the current task. Angular CLI, a database, and a file system. Keep it lean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2 — Skills provide expertise.&lt;/strong&gt;&lt;br&gt;
Create a skill that tells the agent &lt;em&gt;how&lt;/em&gt; to use those tools in your specific context. Not just "run the Angular CLI" — but "when migrating a component, run &lt;code&gt;ng generate&lt;/code&gt; with these flags, then validate against these patterns."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 — Skills can orchestrate MCP.&lt;/strong&gt;&lt;br&gt;
A Skill can define a multi-step workflow that calls multiple MCP tools in sequence. Example: a "Deploy &amp;amp; Notify" Skill that uses GitHub MCP to push, a CI/CD MCP to trigger a build, and a Slack MCP to notify the team — all under one coherent playbook.&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="nn"&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;angular-migration-workflow&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Full workflow for migrating an Angular component to v21 patterns&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Migration Workflow&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Use the Angular CLI MCP to check the current component version
&lt;span class="p"&gt;2.&lt;/span&gt; Run &lt;span class="sb"&gt;`ng update`&lt;/span&gt; for the affected package
&lt;span class="p"&gt;3.&lt;/span&gt; Apply the zoneless migration schematic
&lt;span class="p"&gt;4.&lt;/span&gt; Review the output against the angular-component-review Skill
&lt;span class="p"&gt;5.&lt;/span&gt; Run tests and report results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Practical Decision Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Need to query a real database&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to follow a code review checklist&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to push to GitHub&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to apply your team's commit message format&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to read a live API&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to teach the agent your Angular architecture rules&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need both access and consistent process&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Improving Your Workflow
&lt;/h2&gt;

&lt;p&gt;A few patterns that actually work in production:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. One MCP server per domain.&lt;/strong&gt; Don't load everything at once. Create separate configs for "Angular development," "deployment," and "communication" — and activate only the one you need for a given session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Version your Skills like code.&lt;/strong&gt; Put them in your repository. Review them when you update your stack. A Skill for Angular 19 patterns will actively hurt you on Angular 21.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Use Skills to write MCP guardrails.&lt;/strong&gt; Instead of relying on the agent to figure out when to call a destructive MCP action, write a Skill that explicitly says: &lt;em&gt;"Before running any &lt;code&gt;ng update&lt;/code&gt;, always create a git branch first."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Measure your context budget.&lt;/strong&gt; Before your agent does any real work, know how many tokens your MCP setup consumes. If you're over 30% of your context window is on tool definitions, you have a configuration problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Let the agent maintain simple Skills.&lt;/strong&gt; For fast-moving areas — like keeping track of your team's current Angular version conventions — let the agent update the Skill file itself when you tell it to. It's faster than doing it manually and keeps the Skill honest.&lt;/p&gt;




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

&lt;p&gt;MCP gives agents the ability to act. Skills teach them how to act well.&lt;/p&gt;

&lt;p&gt;The debate of "MCP vs Skills" is a false one. The real question is: &lt;em&gt;do you need access, expertise, or both?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In most real Angular workflows, you need both. An agent that can run your CLI but doesn't know your architecture is just a faster way to make the same mistakes. An agent that knows your patterns but can't touch your actual project is just an expensive search engine.&lt;/p&gt;

&lt;p&gt;Used together, with clear boundaries and lean configuration, they're the foundation of agentic development that actually works.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Previously I wrote about &lt;a href="https://www.yeou.dev/articles/angular-21-mcp-migrations" rel="noopener noreferrer"&gt;Angular 21 MCP and the end of manual migrations&lt;/a&gt; — a good starting point if you're new to the MCP server setup for Angular.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>Angular 20 to 21 Upgrade: The Practical Survival Guide</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:48:14 +0000</pubDate>
      <link>https://dev.to/turingsoracle/angular-20-to-21-upgrade-the-practical-survival-guide-1km9</link>
      <guid>https://dev.to/turingsoracle/angular-20-to-21-upgrade-the-practical-survival-guide-1km9</guid>
      <description>&lt;p&gt;A clear and concise guide to upgrading from Angular 20 to 21. that Covers the essentials like the Karma full removal, the new default Zoneless mode, automatic HttpClient, and how to fix your breaking builds.&lt;/p&gt;

&lt;p&gt;If you thought Angular 20 was a big shift, welcome to Angular 21.&lt;/p&gt;

&lt;p&gt;While version 20 was about stabilizing Signals, version 21 is about removing most of the old patterns. The "Angular Way" has fundamentally changed: &lt;code&gt;zone.js&lt;/code&gt; is optional, Karma is dead, and RxJS is slowly retreating to the edges.&lt;/p&gt;

&lt;p&gt;This isn't just an update; it's a new ecosystem. Here is what is going to break and how to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚨 The "Stop Everything" Breaking Changes
&lt;/h2&gt;

&lt;p&gt;Before you run &lt;code&gt;ng update&lt;/code&gt;, be aware that your build will likely fail if you rely on these legacy patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Karma Extinction Event (Vitest is Default)
&lt;/h3&gt;

&lt;p&gt;The most immediate shock for many teams will be &lt;code&gt;ng test&lt;/code&gt;. Angular 21 has officially swapped Karma for Vitest as the default test runner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What breaks:&lt;/strong&gt; If you have a custom &lt;code&gt;karma.conf.js&lt;/code&gt; or rely on specific Karma plugins/reporters, your test suite is now legacy code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;New Projects:&lt;/strong&gt; You get Vitest out of the box. It's faster, cleaner, and uses Vite.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Existing Projects:&lt;/strong&gt; You aren't forced to switch immediately, but the writing is on the wall. The CLI will nag you.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Migration:&lt;/strong&gt; Run the schematic &lt;code&gt;ng generate @angular/core:karma-to-vitest&lt;/code&gt; to attempt an auto-migration. It's remarkably good at converting standard configs, but custom Webpack hacks in your test setup will need manual rewriting for Vite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. HttpClient is "Just There"
&lt;/h3&gt;

&lt;p&gt;Remember adding &lt;code&gt;provideHttpClient()&lt;/code&gt; to your &lt;code&gt;app.config.ts&lt;/code&gt; or importing &lt;code&gt;HttpClientModule&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Change:&lt;/strong&gt; &lt;code&gt;HttpClient&lt;/code&gt; is now injected by default in the root injector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What breaks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you have tests that mock &lt;code&gt;HttpClient&lt;/code&gt; by expecting it not to be there, they might fail.&lt;/li&gt;
&lt;li&gt;  If you rely on &lt;code&gt;HttpClientModule&lt;/code&gt; for complex interceptor ordering in a mixed NgModule/Standalone app, you might see subtle behavior changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Remove explicit &lt;code&gt;provideHttpClient()&lt;/code&gt; calls unless you are passing configuration options (like &lt;code&gt;withInterceptors&lt;/code&gt; or &lt;code&gt;withFetch&lt;/code&gt;). It cleans up your config, but check your interceptor execution order.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. zone.js is Gone (For New Apps)
&lt;/h3&gt;

&lt;p&gt;New apps generated with &lt;code&gt;ng new&lt;/code&gt; will exclude &lt;code&gt;zone.js&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What breaks:&lt;/strong&gt; Nothing for existing apps (yet). Your &lt;code&gt;polyfils.ts&lt;/code&gt; will keep importing Zone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Warning:&lt;/strong&gt; If you copy-paste code from a new v21 tutorial into your existing v20 app, it might assume Zoneless behavior (using &lt;code&gt;ChangeDetectorRef&lt;/code&gt; less often, relying on Signals). If you mix the two paradigms without understanding them, you'll get "changed after checked" errors or views that don't update.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ The New Toys: Features You'll Actually Use
&lt;/h2&gt;

&lt;p&gt;Once you fix the build, v21 offers some incredible DX improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Signal Forms (Experimental but Stable)
&lt;/h3&gt;

&lt;p&gt;This is the feature we've been waiting for. No more &lt;code&gt;valueChanges.pipe(...)&lt;/code&gt;spaghetti.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define a reactive form model&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Access values directly as signals!&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="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why use it:&lt;/strong&gt; It's type-safe by default and doesn't require RxJS mastery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Status:&lt;/strong&gt; Experimental. Use it for new features, but maybe don't rewrite your checkout flow just yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Angular Aria (Developer Preview)
&lt;/h3&gt;

&lt;p&gt;A new library of headless primitives for accessibility.&lt;/p&gt;

&lt;p&gt;Instead of fighting with &lt;code&gt;aria-expanded&lt;/code&gt; and &lt;code&gt;role="button"&lt;/code&gt;, you use directives that handle the a11y logic while you handle the CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Handles keyboard nav, focus, and ARIA roles automatically --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;ariaMenu&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Option 1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Option 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Regex in Templates
&lt;/h3&gt;

&lt;p&gt;Small but mighty. You can finally use regex literals in templates, perfect for &lt;code&gt;@if&lt;/code&gt;logic without creating a helper function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (email() | match: /@company\.com$/) {
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Employee&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ The Upgrade Checklist
&lt;/h2&gt;

&lt;p&gt;Ready to jump? Follow this order to minimize pain.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Backup:&lt;/strong&gt; Commit everything. Seriously.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update the Global CLI:&lt;/strong&gt;&lt;br&gt;
Updating Angular generally involves two parts: the global CLI and the local project dependencies. Ensure your global CLI is up to date first (you might need sudo or Administrator privileges).&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Optional: Uninstall the old global version first to avoid conflicts&lt;/span&gt;
npm uninstall &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli

&lt;span class="c"&gt;# Verify the npm cache&lt;/span&gt;
npm cache verify

&lt;span class="c"&gt;# Install the latest global CLI version&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update Local Project:&lt;/strong&gt;&lt;br&gt;
Now update your local project dependencies:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli@21 @angular/core@21
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run the Diagnostics:&lt;/strong&gt;&lt;br&gt;
Angular 21 includes smarter diagnostics. Pay attention to warnings about &lt;code&gt;ngClass&lt;/code&gt; (soft deprecated in favor of &lt;code&gt;[class.my-class]&lt;/code&gt;) and standalone migration opportunities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Your Tests:&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;ng test&lt;/code&gt;. If it explodes, decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Path A:&lt;/strong&gt; Keep Karma (add &lt;code&gt;@angular/build:karma&lt;/code&gt; manually if removed).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Path B:&lt;/strong&gt; Migrate to Vitest (Recommended).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optional: Go Zoneless:&lt;/strong&gt;&lt;br&gt;
If you're feeling brave, run the experimental migration:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:zoneless-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;This is "Agentic" territory. See our &lt;a href="https://dev.to/turingsoracle/angular-21-mcp-the-end-of-manual-migrations-4hdh"&gt;MCP Guide&lt;/a&gt; for how to let AI handle this complex refactor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Angular 21 is the "clean slate" release. It sheds the weight of the last decade (Zone, Karma, Modules) to compete with modern frameworks like Svelte and Solid.&lt;/p&gt;

&lt;p&gt;The upgrade might be bumpy due to the testing changes, but the destination—a faster, simpler, signal-driven framework—is absolutely worth it.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>upgrade</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Angular 21 &amp; MCP: The End of "Manual" Migrations?</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:48:04 +0000</pubDate>
      <link>https://dev.to/angular/angular-21-mcp-the-end-of-manual-migrations-4hdh</link>
      <guid>https://dev.to/angular/angular-21-mcp-the-end-of-manual-migrations-4hdh</guid>
      <description>&lt;h3&gt;
  
  
  Angular 21 introduces the Model Context Protocol (MCP) server.
&lt;/h3&gt;

&lt;p&gt;Learn how to connect your AI editor directly to the Angular CLI to automate upgrades, refactoring, and architectural shifts like Zoneless.&lt;/p&gt;

&lt;p&gt;We used to treat AI like a smart stranger. We would copy-paste error messages or file contents into ChatGPT, hoping it understood our project's architecture. It was helpful, but it was blind.&lt;/p&gt;

&lt;p&gt;With Angular 21, that stranger has moved into your house.&lt;/p&gt;

&lt;p&gt;The release of the Angular CLI MCP Server (&lt;code&gt;ng mcp&lt;/code&gt;) marks a fundamental shift in how we maintain applications. It isn't just a new command; it's a protocol that allows AI agents (like Cursor, Windsurf, or VS Code Copilot) to "interview" your project, understand your specific constraints, and run migrations that actually compile.&lt;/p&gt;

&lt;p&gt;Here is why the "manual migration" era might be ending and how to survive the new Agentic Workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP? (The "USB Port" for AI)
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol (MCP) is an open standard that lets AI models connect to local tools and data.&lt;/p&gt;

&lt;p&gt;Think of it this way:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before MCP:&lt;/strong&gt; You paste &lt;code&gt;angular.json&lt;/code&gt; into the chat so the AI knows your file structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After MCP:&lt;/strong&gt; The AI simply asks the Angular CLI, "Hey, list all the projects in this workspace," and the CLI responds with the exact structure, build targets, and library dependencies.&lt;/p&gt;

&lt;p&gt;In Angular 21, the CLI is an MCP server. It exposes "tools" that your AI editor can call directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting It Up: 5 Minutes to "Agentic" Angular
&lt;/h2&gt;

&lt;p&gt;The setup is surprisingly trivial because the Angular team baked it directly into the CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initialize the Server
&lt;/h3&gt;

&lt;p&gt;In your Angular 21 workspace terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command doesn't start a daemon; it generates the configuration snippets you need for your specific IDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Connect Your Editor (e.g., Cursor)
&lt;/h3&gt;

&lt;p&gt;If you are using Cursor (which you probably should be if you're interested in MCP), create or edit &lt;code&gt;.cursor/mcp.json&lt;/code&gt; or if you are using Antigravity (which you probably should be if you're interested in MCP), create or edit &lt;code&gt;.gemini/antigravity/mcp.json&lt;/code&gt; in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To double-check the CURSOR configuration, in cursor click in the three dots in the top right corner and select "Agent Settings."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxz5vt7pnp80r01rg9y5.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%2Fqxz5vt7pnp80r01rg9y5.png" alt="cursor configuration steps" width="628" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then click in "Tools &amp;amp; MCP." if everything is configured correctly, you should see angular as installed MCP server listed with the name of the tool as "ai_tutor."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1wqb8h5gqvobmhm4xc.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%2Fcx1wqb8h5gqvobmhm4xc.png" alt="angular mcp server listed" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To double-check the Antigravity configuration, in Antigravity click on the three dots in the top right corner and select "MCP Servers."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F061revsz4nxdbs2wdv96.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%2F061revsz4nxdbs2wdv96.png" alt="antigravity Manage MCP servers" width="594" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then you will see 'angular-cli' listed, and you can manage the tools, having the ability to enable or disable them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbginapctq8cx8oiw9or8.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%2Fbginapctq8cx8oiw9or8.png" alt="angular tools toggle" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;br&gt;
The &lt;code&gt;-y&lt;/code&gt; flag is crucial to prevent the "Press y to install" prompt from hanging the background process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Available Tools
&lt;/h2&gt;

&lt;p&gt;The Angular CLI MCP server provides several tools to assist you in your development workflow. By default, the following tools are enabled:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool Name&lt;/th&gt;
&lt;th&gt;Read-Only&lt;/th&gt;
&lt;th&gt;Local-Only&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ai_tutor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find_examples&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_best_practices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_projects&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;angular.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onpush_zoneless_migration&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_documentation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Experimental Tools
&lt;/h3&gt;

&lt;p&gt;Some tools are provided in experimental/preview status. You can enable them explicitly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool Name&lt;/th&gt;
&lt;th&gt;Read-Only&lt;/th&gt;
&lt;th&gt;Local-Only&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;modernize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;br&gt;
The &lt;code&gt;-y&lt;/code&gt; flag is crucial to prevent the "Press y to install" prompt from hanging the background process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The "Killer App": Context-Aware Migrations
&lt;/h2&gt;

&lt;p&gt;Why go through this trouble? Because &lt;strong&gt;Context-Aware Migrations&lt;/strong&gt; blow standard schematics out of the water.&lt;/p&gt;

&lt;p&gt;Traditional &lt;code&gt;ng update&lt;/code&gt; scripts are rigid. They follow a strict "If A, then B" logic. If your architecture is weird (and let's be honest, every enterprise architecture is weird), the script breaks or produces code you have to rewrite.&lt;/p&gt;

&lt;p&gt;The MCP Server exposes tools that change this dynamic:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool 1: &lt;code&gt;get_best_practices&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The AI can fetch the current Angular team recommendations. It won't hallucinate that you should use &lt;code&gt;SharedModule&lt;/code&gt; in 2025 because it "read it on a blog from 2021." It asks the CLI for the ground truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool 2: &lt;code&gt;onpush_zoneless_migration&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the big one for v21. Instead of blindly changing &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; to &lt;code&gt;OnPush&lt;/code&gt;, the AI uses this tool to analyze your dependency graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; "Hey, I want to migrate &lt;code&gt;user-profile.ts&lt;/code&gt; to Zoneless. Check if it's safe."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI (Internal Thought):&lt;/strong&gt; I need to check the component style. I'll call &lt;code&gt;list_projects&lt;/code&gt; to find the root, then read the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI (Internal Thought):&lt;/strong&gt; I see an Observable subscription in &lt;code&gt;ngOnInit&lt;/code&gt;. I'll check &lt;code&gt;get_best_practices&lt;/code&gt; for handling async in Zoneless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI (Action):&lt;/strong&gt; "I detected an unmanaged subscription. In Zoneless, this won't trigger a render. I recommend converting this &lt;code&gt;user$&lt;/code&gt; observable to a Signal using &lt;code&gt;toSignal()&lt;/code&gt; before we switch the strategy."&lt;/p&gt;

&lt;p&gt;It doesn't just apply a fix; it negotiates the refactor with you based on the framework's internal logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool 3: &lt;code&gt;search_documentation&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The AI doesn't need to guess API signatures. It queries the local offline documentation index provided by the MCP server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Scenario: The "Legacy" Cleanup
&lt;/h2&gt;

&lt;p&gt;Let's say you have an Angular 17-style component using &lt;code&gt;HttpClientModule&lt;/code&gt; (deprecated approach) and RxJS for simple state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt to Cursor (with MCP active):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Refactor &lt;code&gt;dashboard.component.ts&lt;/code&gt; to align with Angular 21 best practices. Use the &lt;code&gt;get_best_practices&lt;/code&gt; tool to verify your plan first."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The AI calls &lt;code&gt;get_best_practices&lt;/code&gt; and learns that &lt;code&gt;standalone: true&lt;/code&gt;, &lt;code&gt;inject()&lt;/code&gt;, and Signals are the standard.&lt;/li&gt;
&lt;li&gt;It calls &lt;code&gt;modernize&lt;/code&gt; (an experimental tool in v21) to run the standard schematics.&lt;/li&gt;
&lt;li&gt;It manually cleans up the leftovers—converting &lt;code&gt;constructor(private http: HttpClient)&lt;/code&gt; to &lt;code&gt;private http = inject(HttpClient)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It converts your &lt;code&gt;BehaviorSubject&lt;/code&gt; state to &lt;code&gt;signal&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is code that looks like it was written in v21, not just patched to run in v21.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future: Continuous Maintenance
&lt;/h2&gt;

&lt;p&gt;This release signals a change in how Google views the CLI. It's no longer just a build tool; it's an interface for agents.&lt;/p&gt;

&lt;p&gt;In the near future, we likely won't "stop development" to upgrade. We will have a background agent running via MCP that opens PRs:&lt;/p&gt;

&lt;p&gt;"I noticed you used a &lt;code&gt;ControlValueAccessor&lt;/code&gt; here. I've created a PR to refactor this to the new Signal Forms input API."&lt;/p&gt;

&lt;p&gt;"Angular v22 just dropped. I've updated your &lt;code&gt;angular.json&lt;/code&gt; and verified your tests via vitest."&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary: Don't Upgrade Alone
&lt;/h2&gt;

&lt;p&gt;If you are moving to Angular 21, do not just run &lt;code&gt;ng update&lt;/code&gt; and fight the compile errors manually.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the MCP server.&lt;/li&gt;
&lt;li&gt;Let the AI map your project.&lt;/li&gt;
&lt;li&gt;Ask it to plan the migration for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The code is still your responsibility, but the grunt work? That belongs to the machine now.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>mcp</category>
      <category>terminal</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Actualizando a Angular 21 usando ng mcp</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:47:54 +0000</pubDate>
      <link>https://dev.to/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn</link>
      <guid>https://dev.to/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn</guid>
      <description>&lt;p&gt;Angular 21 introduce el servidor Model Context Protocol (MCP). Aprende cómo conectar tu editor de IA directamente al CLI de Angular para automatizar actualizaciones, refactorizaciones y cambios arquitectónicos como Zoneless.&lt;/p&gt;

&lt;p&gt;Solíamos tratar a la IA como a un extraño inteligente. Copiábamos y pegábamos mensajes de error o contenidos de archivos en ChatGPT, esperando que entendiera la arquitectura de nuestro proyecto. Era útil, pero estaba ciega.&lt;/p&gt;

&lt;p&gt;Con Angular 21, ese extraño se ha mudado a tu casa.&lt;/p&gt;

&lt;p&gt;El lanzamiento del servidor MCP del CLI de Angular (&lt;code&gt;ng mcp&lt;/code&gt;) marca un cambio fundamental en la forma en que mantenemos las aplicaciones.&lt;/p&gt;

&lt;p&gt;No es solo un nuevo comando; es un protocolo que permite a los agentes de IA (como Cursor, Windsurf o VS Code Copilot) "entrevistar" a tu proyecto, entender tus restricciones específicas y ejecutar migraciones que realmente compilen.&lt;/p&gt;

&lt;p&gt;He aquí por qué la era de la "migración manual" podría estar terminando, y cómo sobrevivir al nuevo flujo de trabajo agéntico.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MCP? (El "puerto USB" para la IA)
&lt;/h2&gt;

&lt;p&gt;El Model Context Protocol (MCP) es un estándar abierto que permite a los modelos de IA conectarse a herramientas y datos locales.&lt;/p&gt;

&lt;p&gt;Piénsalo de esta manera:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Antes de MCP:&lt;/strong&gt; Pegabas &lt;code&gt;angular.json&lt;/code&gt; en el chat para que la IA conociera tu estructura de archivos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Después de MCP:&lt;/strong&gt; La IA simplemente pregunta al CLI de Angular: "Oye, lista todos los proyectos en este espacio de trabajo", y el CLI responde con la estructura exacta, los objetivos de compilación y las dependencias de bibliotecas.&lt;/p&gt;

&lt;p&gt;En Angular 21, el CLI es un servidor MCP. Expone "herramientas" que tu editor de IA puede llamar directamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración: 5 minutos para un Angular "agéntico"
&lt;/h2&gt;

&lt;p&gt;La configuración es sorprendentemente trivial porque el equipo de Angular la integró directamente en el CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Inicializar el servidor.
&lt;/h3&gt;

&lt;p&gt;En tu terminal del espacio de trabajo de Angular 21:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando no inicia un demonio; genera los fragmentos de configuración que necesitas para tu IDE específico.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Conectar tu editor (por ejemplo, Cursor).
&lt;/h3&gt;

&lt;p&gt;Si estás usando Cursor (que probablemente deberías estar usando si te interesa MCP), crea o edita &lt;code&gt;.cursor/mcp.json&lt;/code&gt; o, si usas Antigravity, crea o edita &lt;code&gt;.gemini/antigravity/mcp.json&lt;/code&gt; en la raíz de tu proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para verificar la configuración de CURSOR, haz clic en los tres puntos en la esquina superior derecha y selecciona "Agent Settings".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxz5vt7pnp80r01rg9y5.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%2Fqxz5vt7pnp80r01rg9y5.png" alt="Pasos de configuración de cursor" width="628" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego haz clic en "Tools &amp;amp; MCP". Si todo está configurado correctamente, deberías ver angular listado como servidor MCP instalado con el nombre de la herramienta como "ai_tutor".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1wqb8h5gqvobmhm4xc.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%2Fcx1wqb8h5gqvobmhm4xc.png" alt="Servidor Angular MCP listado." width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para verificar la configuración de Antigravity, haz clic en los tres puntos en la esquina superior derecha y selecciona "MCP Servers".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F061revsz4nxdbs2wdv96.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%2F061revsz4nxdbs2wdv96.png" alt="Gestionar servidores MCP Antigravity." width="594" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego verás listado 'angular-cli' y podrás gestionar las herramientas, teniendo la capacidad de habilitarlas o deshabilitarlas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbginapctq8cx8oiw9or8.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%2Fbginapctq8cx8oiw9or8.png" alt="Interruptor herramientas angular" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[NOTE]&lt;br&gt;
La flag &lt;code&gt;-y&lt;/code&gt; es crucial para evitar que el mensaje "Press y to install" bloquee el proceso en segundo plano.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Herramientas disponibles
&lt;/h2&gt;

&lt;p&gt;El servidor MCP del CLI de Angular proporciona varias herramientas para ayudarte en tu flujo de trabajo de desarrollo. Por defecto, las siguientes herramientas están habilitadas:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Solo lectura&lt;/th&gt;
&lt;th&gt;Solo local&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ai_tutor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find_examples&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_best_practices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_projects&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;angular.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onpush_zoneless_migration&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_documentation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Herramientas experimentales
&lt;/h3&gt;

&lt;p&gt;Algunas herramientas se proporcionan en estado experimental / vista previa. Puedes habilitarlas explícitamente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Solo lectura&lt;/th&gt;
&lt;th&gt;Solo local&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;modernize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  La "killer app": Migraciones conscientes del contexto
&lt;/h2&gt;

&lt;p&gt;¿Por qué pasar por este problema? Porque las &lt;strong&gt;migraciones conscientes del contexto&lt;/strong&gt; superan con creces a los esquemáticos estándar.&lt;/p&gt;

&lt;p&gt;Los scripts tradicionales de &lt;code&gt;ng update&lt;/code&gt; son rígidos. Siguen una lógica estricta de "Si A, entonces B". Si tu arquitectura es rara (y seamos honestos, cada arquitectura empresarial es rara), el script se rompe o produce código que tienes que reescribir.&lt;/p&gt;

&lt;p&gt;El servidor MCP expone herramientas que cambian esta dinámica:&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 1: &lt;code&gt;get_best_practices&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La IA puede obtener las recomendaciones actuales del equipo de Angular. No alucinará que deberías usar &lt;code&gt;SharedModule&lt;/code&gt; en 2025 porque "lo leyó en un blog de 2021". Pregunta al CLI por la verdad fundamental.&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 2: &lt;code&gt;onpush_zoneless_migration&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta es la grande para la v21. En lugar de cambiar ciegamente &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; a &lt;code&gt;OnPush&lt;/code&gt;, la IA utiliza esta herramienta para analizar tu gráfico de dependencias.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El flujo de trabajo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tú:&lt;/strong&gt; "Oye, quiero migrar &lt;code&gt;user-profile.ts&lt;/code&gt; a Zoneless. Comprueba si es seguro."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Pensamiento Interno):&lt;/strong&gt; Necesito comprobar el estilo del componente. Llamaré a &lt;code&gt;list_projects&lt;/code&gt; para encontrar la raíz, luego leeré el archivo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Pensamiento Interno):&lt;/strong&gt; Veo una suscripción a Observable en &lt;code&gt;ngOnInit&lt;/code&gt;. Comprobaré &lt;code&gt;get_best_practices&lt;/code&gt; para manejar asincronía en Zoneless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Acción):&lt;/strong&gt; "Detecté una suscripción no gestionada. En Zoneless, esto no activará un renderizado. Recomiendo convertir este observable &lt;code&gt;user$&lt;/code&gt; a una Signal usando &lt;code&gt;toSignal()&lt;/code&gt; antes de cambiar la estrategia."&lt;/p&gt;

&lt;p&gt;No solo aplica una solución; negocia la refactorización contigo basándose en la lógica interna del marco.&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 3: &lt;code&gt;search_documentation&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La IA no necesita adivinar las firmas de la API. Consulta el índice de documentación local fuera de línea proporcionado por el servidor MCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escenario del mundo real: La limpieza "Legacy"
&lt;/h2&gt;

&lt;p&gt;Digamos que tienes un componente al estilo Angular 17 usando &lt;code&gt;HttpClientModule&lt;/code&gt; (enfoque obsoleto) y RxJS para estado simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt a Cursor (con MCP activo):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Refactoriza &lt;code&gt;dashboard.component.ts&lt;/code&gt; para alinearlo con las mejores prácticas de Angular 21. Usa la herramienta &lt;code&gt;get_best_practices&lt;/code&gt; para verificar tu plan primero."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué sucede:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;La IA llama a &lt;code&gt;get_best_practices&lt;/code&gt; y aprende que &lt;code&gt;standalone: true&lt;/code&gt;, &lt;code&gt;inject()&lt;/code&gt; y Signals son el estándar.&lt;/li&gt;
&lt;li&gt;Llama a &lt;code&gt;modernize&lt;/code&gt; (una herramienta experimental en v21) para ejecutar los esquemáticos estándar.&lt;/li&gt;
&lt;li&gt;Limpia manualmente los restos: convirtiendo &lt;code&gt;constructor(private http: HttpClient)&lt;/code&gt; a &lt;code&gt;private http = inject(HttpClient)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Convierte tu estado &lt;code&gt;BehaviorSubject&lt;/code&gt; a &lt;code&gt;signal&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El resultado es código que parece escrito en v21, no solo parcheado para ejecutarse en v21.&lt;/p&gt;

&lt;h2&gt;
  
  
  El futuro: Mantenimiento continuo
&lt;/h2&gt;

&lt;p&gt;Este lanzamiento señala un cambio en cómo Google ve el CLI. Ya no es solo una herramienta de construcción; es una interfaz para agentes.&lt;/p&gt;

&lt;p&gt;En el futuro cercano, probablemente no "pararemos el desarrollo" para actualizar. Tendremos un agente en segundo plano ejecutándose vía MCP que abre PRs:&lt;/p&gt;

&lt;p&gt;"Noté que usaste un &lt;code&gt;ControlValueAccessor&lt;/code&gt; aquí. He creado un PR para refactorizar esto a la nueva API de entrada de Signal Forms."&lt;/p&gt;

&lt;p&gt;"Angular v22 acaba de salir. He actualizado tu &lt;code&gt;angular.json&lt;/code&gt; y verificado tus pruebas vía vitest."&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumen: No actualices solo.
&lt;/h2&gt;

&lt;p&gt;Si te estás moviendo a Angular 21, no ejecutes simplemente &lt;code&gt;ng update&lt;/code&gt; y pelees con los errores de compilación manualmente.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instala el servidor MCP.&lt;/li&gt;
&lt;li&gt;Deja que la IA mapee tu proyecto.&lt;/li&gt;
&lt;li&gt;Pídele que planifique la migración por ti.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El código sigue siendo tu responsabilidad, ¿pero el trabajo pesado? Eso pertenece a la máquina ahora.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Migrando Angular 20 a 21: Guía.</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:47:46 +0000</pubDate>
      <link>https://dev.to/angularfirebase/migrando-angular-20-a-21-guia-4ac2</link>
      <guid>https://dev.to/angularfirebase/migrando-angular-20-a-21-guia-4ac2</guid>
      <description>&lt;p&gt;Una guía sin rodeos para actualizar de Angular 20 a 21. Cubre la eliminación de Karma, el nuevo modo Zoneless por defecto, HttpClient automático y cómo arreglar tus compilaciones rotas.&lt;/p&gt;

&lt;p&gt;Si pensabas que Angular 20 fue un gran cambio, bienvenido a Angular 21.&lt;/p&gt;

&lt;p&gt;Mientras la versión 20 trataba de estabilizar Signals, la versión 21 trata de mejorar la experiencia del desarrollador. Angular ha cambiado fundamentalmente: &lt;code&gt;zone.js&lt;/code&gt; es opcional, Karma está muerto y RxJS parece ser reemplazado lentamente.&lt;/p&gt;

&lt;p&gt;Esto no es solo una actualización; se siente como todo un ecosistema nuevo. Aquí está lo que se va a romper y cómo arreglarlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lo crítico que detienen todo
&lt;/h2&gt;

&lt;p&gt;Antes de ejecutar &lt;code&gt;ng update&lt;/code&gt;, ten en cuenta que tu compilación probablemente fallará si dependes de estos patrones heredados.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. El Evento de Extinción de Karma (Vitest es el predeterminado)
&lt;/h3&gt;

&lt;p&gt;El choque más inmediato para muchos equipos será &lt;code&gt;ng test&lt;/code&gt;. Angular 21 ha cambiado oficialmente Karma por Vitest como el ejecutor de pruebas predeterminado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt; Si tienes un &lt;code&gt;karma.conf.js&lt;/code&gt; personalizado o dependes de complementos/reportadores específicos de Karma, tu suite de pruebas es ahora código heredado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La solución:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Nuevos proyectos:&lt;/strong&gt; Obtienes Vitest desde el principio. Es más rápido, más limpio y usa Vite.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Proyectos existentes:&lt;/strong&gt; No estás obligado a cambiar inmediatamente, pero el final está cerca. El CLI te insistirá.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Migración:&lt;/strong&gt; Ejecuta el s &lt;code&gt;ng generate @angular/core:karma-to-vitest&lt;/code&gt; para intentar una auto-migración. Es notablemente bueno convirtiendo configuraciones estándar, pero los trucos personalizados de Webpack en tu configuración de pruebas necesitarán reescritura manual para Vite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. HttpClient está "simplemente ahí".
&lt;/h3&gt;

&lt;p&gt;¿Recuerdas añadir &lt;code&gt;provideHttpClient()&lt;/code&gt; a tu &lt;code&gt;app.config.ts&lt;/code&gt; o importar &lt;code&gt;HttpClientModule&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El cambio:&lt;/strong&gt; &lt;code&gt;HttpClient&lt;/code&gt; ahora se inyecta por defecto en el inyector raíz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Si tienes pruebas que simulan &lt;code&gt;HttpClient&lt;/code&gt; esperando que no esté allí, podrían fallar.&lt;/li&gt;
&lt;li&gt;  Si dependes de &lt;code&gt;HttpClientModule&lt;/code&gt; para un orden complejo de interceptores en una aplicación mixta NgModule/Standalone, podrías ver cambios sutiles de comportamiento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;La solución&lt;/strong&gt;: Elimina las llamadas explícitas a &lt;code&gt;provideHttpClient()&lt;/code&gt; a menos que estés pasando opciones de configuración (como &lt;code&gt;withInterceptors&lt;/code&gt; o &lt;code&gt;withFetch&lt;/code&gt;). Limpia tu configuración, pero comprueba el orden de ejecución de tus interceptores.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. zone.js se ha ido (para nuevas apps).
&lt;/h3&gt;

&lt;p&gt;Las nuevas aplicaciones generadas con &lt;code&gt;ng new&lt;/code&gt; excluirán &lt;code&gt;zone.js&lt;/code&gt; por defecto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt; Nada para las aplicaciones existentes (todavía). Tu &lt;code&gt;polyfils.ts&lt;/code&gt; seguirá importando Zone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La advertencia:&lt;/strong&gt; Si copias y pegas código de un tutorial nuevo de v21 en tu aplicación v20 existente, podría asumir un comportamiento Zoneless (usando menos &lt;code&gt;ChangeDetectorRef&lt;/code&gt;, confiando en Signals). Si mezclas los dos paradigmas sin entenderlos, obtendrás errores "changed after checked" o vistas que no se actualizan.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Las nuevas características
&lt;/h2&gt;

&lt;p&gt;Una vez que arregles la compilación, la v21 ofrece algunas mejoras increíbles en la experiencia de desarrollo (DX).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Signal Forms (Experimental pero estable)
&lt;/h3&gt;

&lt;p&gt;Esta es la característica que hemos estado esperando. No más espagueti de &lt;code&gt;valueChanges.pipe(...)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Definir un modelo de formulario reactivo&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ¡Accede a los valores directamente como signals!&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="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Por qué usarlo:&lt;/strong&gt; Es seguro en cuanto a tipos por defecto y no requiere maestría en RxJS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estado:&lt;/strong&gt; Experimental. Úsalo para nuevas características, pero tal vez no reescribas tu flujo de pago todavía.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Angular Aria (Developer Preview)
&lt;/h3&gt;

&lt;p&gt;Una nueva biblioteca de primitivas "headless" para accesibilidad.&lt;/p&gt;

&lt;p&gt;En lugar de pelear con &lt;code&gt;aria-expanded&lt;/code&gt; y &lt;code&gt;role="button"&lt;/code&gt;, usas directivas que manejan la lógica de accesibilidad mientras tú manejas el CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Maneja navegación por teclado, foco y roles ARIA automáticamente --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;ariaMenu&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Opción 1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Opción 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Regex en plantillas
&lt;/h3&gt;

&lt;p&gt;Pequeño pero poderoso. Finalmente, puedes usar literales de expresiones regulares en plantillas, perfecto para la lógica &lt;code&gt;@if&lt;/code&gt; sin crear una función auxiliar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (email() | match: /@company\.com$/) {
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Empleado&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ La lista de verificación de actualización
&lt;/h2&gt;

&lt;p&gt;¿Listo para saltar? Sigue este orden para minimizar el dolor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Copia de seguridad:&lt;/strong&gt; Haz commit de todo. En serio.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Actualizar el CLI Global:&lt;/strong&gt;&lt;br&gt;
Actualizar Angular generalmente implica dos partes: el CLI global y las dependencias locales del proyecto. Asegúrate de que tu CLI global esté actualizado primero (podrías necesitar sudo o privilegios de administrador).&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Opcional: Desinstalar la versión global antigua primero para evitar conflictos&lt;/span&gt;
npm uninstall &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli

&lt;span class="c"&gt;# Verificar la caché de npm&lt;/span&gt;
npm cache verify

&lt;span class="c"&gt;# Instalar la última versión global del CLI&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Actualizar proyecto local:&lt;/strong&gt;&lt;br&gt;
Ahora actualiza las dependencias locales de tu proyecto:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli@21 @angular/core@21
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ejecutar los diagnósticos:&lt;/strong&gt;&lt;br&gt;
Angular 21 incluye diagnósticos más inteligentes. Presta atención a las advertencias sobre &lt;code&gt;ngClass&lt;/code&gt; (obsoleto a favor de &lt;code&gt;[class.my-class]&lt;/code&gt;) y oportunidades de migración standalone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Comprobar tus pruebas:&lt;/strong&gt;&lt;br&gt;
Ejecuta &lt;code&gt;ng test&lt;/code&gt;. Si explota, decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ruta A:&lt;/strong&gt; Mantener Karma (añadir &lt;code&gt;@angular/build:karma&lt;/code&gt; manualmente si se eliminó).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruta B:&lt;/strong&gt; Migrar a Vitest (recomendado).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Opcional: Ir zoneless:&lt;/strong&gt;&lt;br&gt;
Si te sientes valiente, ejecuta la migración experimental:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:zoneless-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota&lt;br&gt;
Esto es territorio "Agéntico". Mira nuestra &lt;a href="https://dev.to/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn"&gt;Guía MCP&lt;/a&gt; para saber cómo dejar que la IA maneje esta refactorización compleja.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resumen
&lt;/h2&gt;

&lt;p&gt;Angular 21 es el lanzamiento de "borrón y cuenta nueva". Se deshace del peso de la última década (Zone, Karma, Modules) para competir con marcos modernos como Svelte y Solid.&lt;/p&gt;

&lt;p&gt;La actualización puede ser irregular debido a los cambios en las pruebas, pero el destino —un marco más rápido, más simple e impulsado por signals— vale absolutamente la pena.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>spanish</category>
    </item>
    <item>
      <title>El cambio declarativo de Angular</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 19 Oct 2025 09:02:30 +0000</pubDate>
      <link>https://dev.to/angularfirebase/el-cambio-declarativo-de-angular-27ai</link>
      <guid>https://dev.to/angularfirebase/el-cambio-declarativo-de-angular-27ai</guid>
      <description>&lt;h2&gt;
  
  
  Cómo la Nueva Estructura de Carpetas lo Cambia Todo
&lt;/h2&gt;

&lt;p&gt;Si no has actualizado a la versión 20, la primera y segunda parte de esta guía te pueden ayudar a comprender qué cambia y actualizar. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parte 1: La actualización en sí misma 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Primero, resolvamos lo básico. Antes de ejecutar cualquier comando, asegúrate de que tu entorno esté listo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerrequisitos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt;: v20.11.1 o posterior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt;: v5.8 o posterior.&lt;/li&gt;
&lt;li&gt;**Copia de seguridad del proyecto: Asegúrate de confirmar todos tus cambios actuales en Git. En serio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;El Comando de Actualización&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Una vez que hayas confirmado tu versión de Node.js, ejecuta el comando que se ajuste a tu proyecto.&lt;/p&gt;

&lt;p&gt;Para un proyecto estándar de Angular:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si utilizas Angular Material:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core @angular/material 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El proceso de actualización se ejecutará, pero es probable que te encuentres con tu primer obstáculo de inmediato.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 2: Lo que se rompe inmediatamente *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A diferencia de las actualizaciones anteriores, Angular 20 introduce un cambio significativo que detendrá tu compilación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. La Historia Completa Detrás de la Eliminación de Karma&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lo primero que notarás es que &lt;code&gt;ng test&lt;/code&gt; fallará. Esto no es solo un error; es un cambio fundamental en las herramientas de compilación de Angular. Con Angular 20, el paquete de compilación predeterminado cambia de &lt;code&gt;@angular-devkit/build-angular&lt;/code&gt; al nuevo &lt;code&gt;@angular/build&lt;/code&gt;. Este nuevo paquete &lt;strong&gt;no incluye Karma&lt;/strong&gt;. El ecosistema web ha avanzado hacia ejecutores de pruebas más rápidos y modernos como &lt;strong&gt;Vitest&lt;/strong&gt; y &lt;strong&gt;Jest&lt;/strong&gt;, y Karma se había convertido en un cuello de botella.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La solución temporal:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que tus pruebas se ejecuten sin migrar todo hoy, debes reinstalar manualmente la antigua herramienta de compilación. Esto obliga a la CLI a usar el antiguo compilador que aún es compatible con Karma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular-devkit/build-angular &lt;span class="nt"&gt;--save-dev&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este es un puente de compatibilidad. El mensaje del equipo de Angular es claro: comienza a planificar tu migración a Jest o Vitest pronto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. browserslist y soporte de navegadores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aquí hay un detalle menor que podría sorprenderte. Angular 20 &lt;strong&gt;oficialmente ya no es compatible con Opera&lt;/strong&gt;. Si tienes "Opera" listado en tu archivo &lt;code&gt;.browserslistrc&lt;/code&gt;, tu compilación puede fallar o arrojar advertencias. Quítalo para resolver el problema.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 3: La Nueva Arquitectura *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Más allá de los cambios importantes, Angular 20 impulsa una arquitectura más moderna, explícita y escalable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Componentes standalone por defecto.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Los nuevos proyectos generados con &lt;code&gt;ng new&lt;/code&gt; ahora son &lt;em&gt;standalone&lt;/em&gt; (independientes) por defecto. Esto marca un cambio arquitectónico fundamental que se aleja de los NgModules. Al listar las dependencias directamente en el &lt;em&gt;array&lt;/em&gt; &lt;code&gt;imports&lt;/code&gt; de un componente, cada componente se vuelve autocontenido.&lt;/p&gt;

&lt;p&gt;¿Qué implica este cambio?:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arquitectura más clara y definida&lt;/strong&gt;: Sabes exactamente lo que necesita cada componente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mejora el *tree-shaking&lt;/strong&gt;*: Conduce a paquetes más pequeños y optimizados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para migrar tus proyectos existentes, puedes ejecutar el &lt;em&gt;schematic&lt;/em&gt; de migración &lt;em&gt;standalone&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:standalone 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Una estructura de carpetas que cuenta una historia&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Una buena estructura de carpetas no solo contiene archivos, sino que te dice lo que hace la aplicación. Vale la pena hacer énfasis en la guía de estilo oficial de Angular, ya que sus recomendaciones se basan en años de experiencia comunitaria. Esta filosofía, detallada en su &lt;a href="https://angular.dev/reference/configs/file-structure" rel="noopener noreferrer"&gt;página de referencia de estructura de archivos&lt;/a&gt;, a menudo se resume con el acrónimo &lt;strong&gt;LIFT&lt;/strong&gt; (por sus siglas en inglés: Localizar, Identificar, Plano, Tratar de ser DRY):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt;ocate (Localiza) tu código fácilmente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;dentify (Identifica) lo que hace un archivo de un vistazo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F&lt;/strong&gt;lat Flat (Plano): Mantén estructura plana tanto como puedas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;ry to be DRY: Don't Repeat Yourself (Trata de no repetirte).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La conclusión principal es &lt;strong&gt;organizar por característica, no por tipo&lt;/strong&gt;. En lugar de una carpeta &lt;code&gt;components&lt;/code&gt; y una carpeta &lt;code&gt;services&lt;/code&gt;, crea carpetas para características como &lt;code&gt;user-profile&lt;/code&gt; o &lt;code&gt;product-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Usemos un ejemplo práctico para una aplicación de comercio electrónico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/app/
├── core/
│   ├── auth/          &lt;span class="c"&gt;# Lógica de autenticación usada en todas partes&lt;/span&gt;
│   │   ├── auth-store.ts
│   │   └── auth-interceptor.ts
│   └── layout/        &lt;span class="c"&gt;# El shell de la aplicación: barra de navegación, pie de página&lt;/span&gt;
│       ├── navbar.ts
│       └── footer.ts
│
├── features/
│   ├── products/      &lt;span class="c"&gt;# Todo para navegar por los productos&lt;/span&gt;
│   │   ├── product-list.ts
│   │   ├── product-details.ts
│   │   └── product-search.ts
│   │
│   └── cart/          &lt;span class="c"&gt;# La característica del carrito de compras&lt;/span&gt;
│       ├── cart-store.ts
│       ├── cart-view.ts
│       └── add-to-cart.ts
│
└── shared/            &lt;span class="c"&gt;# Componentes "tontos" reutilizables y utilidades&lt;/span&gt;
    └── ui/
        ├── button.ts
        ├── spinner.ts
        └── price.pipe.ts 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Por qué funciona esto?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;core (Proporcionar una vez):&lt;/strong&gt; Servicios y componentes que la aplicación necesita para ejecutarse, cargados solo una vez (&lt;code&gt;AuthStore&lt;/code&gt;, &lt;code&gt;Navbar&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Features  (Lo que hace tu aplicación):&lt;/strong&gt; El corazón de tu aplicación. Cada carpeta es una característica autocontenida.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;shared (Bloques de construcción reutilizables):&lt;/strong&gt; Componentes "tontos", &lt;em&gt;pipes&lt;/em&gt; y directivas que no saben nada sobre las características en las que se utilizan (&lt;code&gt;Button&lt;/code&gt;,
&lt;code&gt;Spinner&lt;/code&gt;). Son importados por los módulos de características.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;3. La Nueva Convención de Nombres&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular 20 introduce una nueva convención oficial de nombres que &lt;strong&gt;elimina los sufijos tradicionales&lt;/strong&gt; como &lt;code&gt;.component.ts&lt;/code&gt; o &lt;code&gt;.service.ts&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Nomenclatura Antigua&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Nueva Nomenclatura&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Intención&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;user-profile.component.ts&lt;/td&gt;
&lt;td&gt;user-profile.ts&lt;/td&gt;
&lt;td&gt;Componente de Interfaz de Usuario&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;auth.service.ts&lt;/td&gt;
&lt;td&gt;auth-store.ts&lt;/td&gt;
&lt;td&gt;Gestión de estado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;highlight.directive.ts&lt;/td&gt;
&lt;td&gt;highlight.ts&lt;/td&gt;
&lt;td&gt;Directiva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user-api.service.ts&lt;/td&gt;
&lt;td&gt;user-api.ts&lt;/td&gt;
&lt;td&gt;Cliente HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El objetivo es centrarse en la &lt;strong&gt;intención&lt;/strong&gt; del archivo en lugar de su tipo técnico. Una clase que maneja el estado es un "store" (almacén), y una que realiza peticiones HTTP es una "api". Esto hace que el propósito de tu código sea mucho más claro, especialmente en una estructura de carpetas basada en características.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 4: Las nuevas herramientas y sintaxis *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finalmente, veamos las nuevas herramientas que mejorarán tu desarrollo diario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. El flujo de control es más que syntactic sugar (azúcar sintáctico).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El nuevo bloque &lt;code&gt;@for&lt;/code&gt; reemplaza a &lt;code&gt;*ngFor&lt;/code&gt; y es una mejora importante.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis antigua:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;ngFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;let item of items; trackBy: trackItemById&lt;/span&gt;&lt;span class="dl"&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nueva sintaxis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;track&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;empty&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;hay&lt;/span&gt; &lt;span class="nx"&gt;elementos&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;mostrar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mejoras clave:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;track&lt;/code&gt; es &lt;strong&gt;obligatorio&lt;/strong&gt;, lo que impone una mejor práctica de rendimiento que a menudo se olvidaba.&lt;/li&gt;
&lt;li&gt;El bloque &lt;code&gt;@empty&lt;/code&gt; incorporado limpia las plantillas al eliminar la necesidad de un &lt;code&gt;*ngIf&lt;/code&gt; separado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Puedes usar la CLI para refactorizar automáticamente tus plantillas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:control-flow 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Zoneless: Escapando de la "magia de la detección de cambios".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aunque todavía es experimental, el camino hacia un Angular sin zonas (&lt;em&gt;zoneless&lt;/em&gt;) se está volviendo más claro. En un mundo sin zonas, la interfaz de usuario solo se actualiza cuando se lo indicas explícitamente.&lt;/p&gt;

&lt;p&gt;Los &lt;strong&gt;signals&lt;/strong&gt; (señales) son la herramienta principal para esto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta línea le indica directamente a Angular que actualice solo las partes específicas del DOM que dependen de esa señal. Es un enfoque quirúrgico, predecible y de alto rendimiento que elimina la sobrecarga y la imprevisibilidad de Zone.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular 20 es una versión significativa. La actualización requiere intervención manual para las pruebas, pero impulsa el &lt;em&gt;framework&lt;/em&gt; hacia un futuro más moderno, explícito y de alto rendimiento. Al adoptar componentes &lt;em&gt;standalone&lt;/em&gt;, una arquitectura basada en características y el nuevo flujo de control, no solo estás actualizando, sino que estás preparando tu aplicación para la próxima era del desarrollo web.&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>angular</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Angular's Declarative Shift</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 19 Oct 2025 08:00:09 +0000</pubDate>
      <link>https://dev.to/angular/updating-to-angular-20-a-real-world-guide-2h9o</link>
      <guid>https://dev.to/angular/updating-to-angular-20-a-real-world-guide-2h9o</guid>
      <description>&lt;h2&gt;
  
  
  How the New Folder Structure Changes Everything
&lt;/h2&gt;

&lt;p&gt;If you haven't updated to version 20, the first and second parts of this guide can help you understand what's changing and how to update.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: The Upgrade Itself 🛠️
&lt;/h2&gt;

&lt;p&gt;First, let's get the basics out of the way. Before running any commands, make sure your environment is ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Node.js&lt;/strong&gt;: v20.11.1 or later.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;TypeScript&lt;/strong&gt;: v5.8 or later.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Project Backup&lt;/strong&gt;: Make sure you commit all your current changes in Git. Seriously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Update Command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you've confirmed your Node.js version, run the command that fits your project.&lt;/p&gt;

&lt;p&gt;For a standard Angular project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use Angular Material:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core @angular/material
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The update process will run, but you're likely to hit your first roadblock immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: What Breaks Immediately 🛑
&lt;/h2&gt;

&lt;p&gt;Unlike previous updates, Angular 20 introduces a significant breaking change that will stop your build.&lt;/p&gt;

&lt;h3&gt;
  
  
  1 The Full Story Behind Karma’s Removal
&lt;/h3&gt;

&lt;p&gt;The first thing you'll notice is that &lt;code&gt;ng test&lt;/code&gt; will fail. This isn't just a bug; it's a fundamental change in Angular’s build tools.&lt;/p&gt;

&lt;p&gt;With Angular 20, the default build package changes from &lt;code&gt;@angular-devkit/build-angular&lt;/code&gt; to the new &lt;code&gt;@angular/build&lt;/code&gt;. This new package &lt;strong&gt;does not include Karma&lt;/strong&gt;. The web ecosystem has moved on to faster, more modern test runners like &lt;strong&gt;Vitest&lt;/strong&gt; and &lt;strong&gt;Jest&lt;/strong&gt;, and Karma had become a bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Temporary Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get your tests running without migrating everything today, you need to manually reinstall the old build tool. This forces the CLI to use the old compiler that still supports Karma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular-devkit/build-angular &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a compatibility bridge. The message from the Angular team is clear: start planning your migration to Jest or Vitest soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. browserslist and Browser Support
&lt;/h3&gt;

&lt;p&gt;Here's a smaller detail that might catch you by surprise. Angular 20 &lt;strong&gt;officially no longer supports Opera&lt;/strong&gt;. If you have "Opera" listed in your &lt;code&gt;.browserslistrc&lt;/code&gt; file, your build may fail or throw warnings. Remove it to resolve the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: The New Architecture 🏛️
&lt;/h2&gt;

&lt;p&gt;Beyond the breaking changes, Angular 20 pushes forward a more modern, explicit, and scalable architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Standalone is the Default
&lt;/h3&gt;

&lt;p&gt;New projects generated with &lt;code&gt;ng new&lt;/code&gt; are now standalone by default. This marks a fundamental architectural shift away from NgModules. By listing dependencies directly in a component's &lt;code&gt;imports&lt;/code&gt; array, each component becomes self-contained.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clarifies your architecture&lt;/strong&gt;: You know exactly what each component needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improves tree-shaking&lt;/strong&gt;: Leads to smaller, more optimized bundles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To migrate your existing projects, you can run the standalone migration schematic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:standalone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. A Folder Structure That Tells a Story
&lt;/h3&gt;

&lt;p&gt;A good folder structure doesn't just hold files—it tells you what the application does. It's worth mentioning the official Angular style guide, as its recommendations are built on years of community experience. This philosophy, detailed on their &lt;a href="https://angular.dev/reference/configs/file-structure" rel="noopener noreferrer"&gt;file structure reference page&lt;/a&gt;, is often summarized by the acronym &lt;strong&gt;LIFT&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt;ocate your code easily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;dentify what a file does at a glance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F&lt;/strong&gt;lat structure for as long as you can.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;ry to be DRY (Don't Repeat Yourself).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main takeaway is to &lt;strong&gt;organize by feature, not by type&lt;/strong&gt;. Instead of a &lt;code&gt;components&lt;/code&gt; folder and a &lt;code&gt;services&lt;/code&gt; folder, you create folders for features like &lt;code&gt;user-profile&lt;/code&gt; or &lt;code&gt;product-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's use a practical example for an e-commerce app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/app/
├── core/
│   ├── auth/          &lt;span class="c"&gt;# Authentication logic used everywhere&lt;/span&gt;
│   │   ├── auth-store.ts
│   │   └── auth-interceptor.ts
│   └── layout/        &lt;span class="c"&gt;# The app's shell: navbar, footer&lt;/span&gt;
│       ├── navbar.ts
│       └── footer.ts
│  
├── features/
│   ├── products/      &lt;span class="c"&gt;# Everything for browsing products&lt;/span&gt;
│   │   ├── product-list.ts
│   │   ├── product-details.ts
│   │   └── product-search.ts
│   │  
│   └── cart/          &lt;span class="c"&gt;# The shopping cart feature&lt;/span&gt;
│       ├── cart-store.ts
│       ├── cart-view.ts
│       └── add-to-cart.ts
│  
└── shared/            &lt;span class="c"&gt;# Reusable "dumb" components &amp;amp; utilities&lt;/span&gt;
    └── ui/
        ├── button.ts
        ├── spinner.ts
        └── price.pipe.ts

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why This Works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;core 🏛️ (Provide once):&lt;/strong&gt; Services and components the app needs to run, loaded only once (AuthStore, Navbar).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;features ✨ (What your app does):&lt;/strong&gt; The heart of your application. Each folder is a self-contained feature.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;shared ♻️ (Reusable building blocks):&lt;/strong&gt; "Dumb" components, pipes, and directives that don't know anything about the features they're used in (Button, Spinner). They are imported by feature modules.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. The New Naming Convention
&lt;/h3&gt;

&lt;p&gt;Angular 20 introduces a new official naming convention that &lt;strong&gt;drops traditional suffixes&lt;/strong&gt; like &lt;code&gt;.component.ts&lt;/code&gt; or &lt;code&gt;.service.ts&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old Naming&lt;/th&gt;
&lt;th&gt;New Naming&lt;/th&gt;
&lt;th&gt;Intent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;user-profile.component.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;user-profile.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;UI Component&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;auth.service.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;auth-store.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;State Management&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;highlight.directive.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;highlight.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Directive&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;user-api.service.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;user-api.ts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;HTTP Client&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The goal is to focus on the file's &lt;strong&gt;intent&lt;/strong&gt; rather than its technical type. A class that handles state is a "store," and one that makes HTTP requests is an "api." This makes your codebase's purpose much clearer, especially in a feature-based folder structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 4: The New Tools &amp;amp; Syntax 🚀
&lt;/h2&gt;

&lt;p&gt;Finally, let's look at the new tools that will make your day-to-day development better.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Control Flow is More Than Syntactic Sugar
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;@for&lt;/code&gt; block replaces &lt;code&gt;*ngFor&lt;/code&gt; and is a major improvement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of items; trackBy: trackItemById"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ item.name }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;New Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@for (item of items; track item.id) {
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;{{ item.name }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
} @empty {
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;No items to display.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;track&lt;/code&gt; is &lt;strong&gt;mandatory&lt;/strong&gt;, enforcing a performance best practice that was often forgotten.&lt;/li&gt;
&lt;li&gt;The built-in &lt;code&gt;@empty&lt;/code&gt; block cleans up templates by removing the need for a separate &lt;code&gt;*ngIf&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use the CLI to automatically refactor your templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:control-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Zoneless: Escaping the "Magic" of Change Detection
&lt;/h3&gt;

&lt;p&gt;While still experimental, the path to a zoneless Angular is becoming clearer. In a zoneless world, the UI only updates when you explicitly tell it to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signals&lt;/strong&gt; are the primary tool for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line directly tells Angular to update only the specific parts of the DOM that depend on that signal. It’s a surgical, predictable, and high-performance approach that eliminates the overhead and unpredictability of Zone.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular 20 is a significant release. The upgrade requires manual intervention for testing, but it pushes the framework toward a more modern, explicit, and performant future. By embracing standalone components, a feature-based architecture, and the new control flow, you're not just updating—you're preparing your application for the next era of web development.&lt;/p&gt;

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

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Angular 20: De la programación imperativa a la creación declarativa de componentes dinámicos</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Thu, 09 Oct 2025 15:20:49 +0000</pubDate>
      <link>https://dev.to/angularfirebase/angular-20-de-la-programacion-imperativa-a-la-creacion-declarativa-de-componentes-dinamicos-42e</link>
      <guid>https://dev.to/angularfirebase/angular-20-de-la-programacion-imperativa-a-la-creacion-declarativa-de-componentes-dinamicos-42e</guid>
      <description>&lt;p&gt;Angular 20 llega con &lt;strong&gt;nuevas y geniales características y mejoras&lt;/strong&gt;. Una de las adiciones más significativas es la simplificación de la creación de componentes dinámicos, que la hace &lt;strong&gt;mucho más limpia, consistente y predecible&lt;/strong&gt;. Esta mejora alinea la sintaxis para componentes dinámicos con la forma en que funcionan los &lt;strong&gt;"enlaces"&lt;/strong&gt; (&lt;code&gt;bindings&lt;/code&gt;) en las plantillas de componentes.&lt;/p&gt;

&lt;p&gt;Anteriormente, la creación de componentes dinámicos se sentía como el complejo proceso de &lt;strong&gt;ensamblar una PC personalizada a partir de piezas dispares y manuales&lt;/strong&gt;: funcional, sí, pero requería que el desarrollador lidiara manualmente con cada cable, cada conexión y cada compatibilidad.  Ahora, Angular 20 te da un panel de control unificado.&lt;/p&gt;

&lt;h2&gt;
  
  
  El laberinto de la construcción manual (Pre-Angular 20)
&lt;/h2&gt;

&lt;p&gt;Antes de Angular 20, trabajar con componentes creados dinámicamente era &lt;strong&gt;engorroso&lt;/strong&gt;. El &lt;strong&gt;"enlace de datos bidireccional"&lt;/strong&gt; (&lt;code&gt;two-way data binding&lt;/code&gt;) era &lt;strong&gt;muy incómodo&lt;/strong&gt;, y no existía un estilo unificado para trabajar con &lt;strong&gt;"entradas"&lt;/strong&gt; (&lt;code&gt;inputs&lt;/code&gt;) y &lt;strong&gt;"salidas"&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Para configurar un componente dinámico, era como si tuviéramos que &lt;strong&gt;conectar cada componente (&lt;code&gt;input&lt;/code&gt;) y cable de salida (&lt;code&gt;output&lt;/code&gt;) de forma individual y a mano&lt;/strong&gt;. Para un hipotético &lt;code&gt;NotificationComponent&lt;/code&gt;, los pasos manuales e imperativos eran:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Conexión manual de componentes&lt;/strong&gt;: Se tenía que usar &lt;code&gt;setInput()&lt;/code&gt; para conectar cada componente (propiedad) por separado.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Preparación manual de los datos&lt;/strong&gt;: Si los datos venían de una &lt;strong&gt;"señal"&lt;/strong&gt; (&lt;code&gt;signal&lt;/code&gt;), debían ser &lt;strong&gt;desenvueltos&lt;/strong&gt; (acceder a su valor) para obtener el valor real y no la función.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Gestión de las conexiones de salida&lt;/strong&gt;: Se requería &lt;strong&gt;suscribirse manualmente a las salidas&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;), guardando cada suscripción. Era crucial &lt;strong&gt;recordar desconectar estos cables&lt;/strong&gt; (&lt;code&gt;unsubscribe&lt;/code&gt;) para prevenir &lt;strong&gt;fugas de memoria&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Sincronización manual de datos&lt;/strong&gt;: Para que el componente dinámico reaccionara a los cambios en una &lt;code&gt;signal&lt;/code&gt; del padre, era necesario un &lt;strong&gt;"efecto"&lt;/strong&gt; (&lt;code&gt;effect&lt;/code&gt;) para rastrear el cambio y luego &lt;strong&gt;volver a conectar manualmente el cable&lt;/strong&gt; (&lt;code&gt;setInput&lt;/code&gt;) con el nuevo valor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El código era como un diagrama de cableado muy &lt;strong&gt;imperativo&lt;/strong&gt; y no reactivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enfoque anterior (Imperativo)&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 1: Conexión básica de la placa madre&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NotificationComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 2: Conexión manual de los componentes y datos&lt;/span&gt;
&lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alerta de estado&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// ¡Desenvolver el valor de la signal!&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 3 &amp;amp; 4: Conexión manual de los cables de salida y de sincronización&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dismissed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Lógica de destrucción manual (desconectar del todo)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 5: Reactividad manual usando efecto&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;effect&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="c1"&gt;// Necesario para que el componente se actualice reactivamente&lt;/span&gt;
    &lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... Se necesita más código para la sincronización bidireccional y la limpieza de cables.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La forma de acceder a la &lt;strong&gt;salida&lt;/strong&gt; (&lt;code&gt;output&lt;/code&gt;) requería &lt;strong&gt;acceder directamente a la propiedad de la clase&lt;/strong&gt;, lo que no respetaba el &lt;strong&gt;"alias"&lt;/strong&gt; de la salida y era diferente de cómo funciona en las plantillas.&lt;/p&gt;




&lt;h2&gt;
  
  
  El panel de control unificado (Angular 20)
&lt;/h2&gt;

&lt;p&gt;A partir de Angular 20, la configuración de componentes dinámicos se gestiona a través de la nueva propiedad &lt;strong&gt;&lt;code&gt;bindings&lt;/code&gt;&lt;/strong&gt;. Este nuevo enfoque es &lt;strong&gt;declarativo&lt;/strong&gt; y &lt;strong&gt;reactivo&lt;/strong&gt;, y su corazón es la &lt;strong&gt;"referencia del contenedor de vista"&lt;/strong&gt; (&lt;code&gt;ViewContainerRef&lt;/code&gt;), que actúa como el &lt;strong&gt;"socket" principal&lt;/strong&gt; donde se insertará el nuevo componente.&lt;/p&gt;

&lt;h3&gt;
  
  
  El poder de &lt;code&gt;ViewContainerRef&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Una &lt;strong&gt;"referencia del contenedor de vista"&lt;/strong&gt; (&lt;code&gt;ViewContainerRef&lt;/code&gt;) es el &lt;strong&gt;"socket"&lt;/strong&gt; en el chasis de tu PC donde se puede instalar una tarjeta de video o de sonido. Permite crear, eliminar o incluso mover &lt;strong&gt;"tarjetas"&lt;/strong&gt; (&lt;code&gt;views&lt;/code&gt;) dentro de ese contenedor. Para acceder a él, se puede inyectar con &lt;code&gt;inject()&lt;/code&gt; o, para una ubicación específica, usar una referencia de plantilla.&lt;/p&gt;

&lt;p&gt;Para controlar la ubicación exacta de tu componente dinámico, puedes añadir un &lt;code&gt;&amp;lt;ng-container&amp;gt;&lt;/code&gt; en tu plantilla para definir un lugar de inserción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"createDynamic()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Create Dynamic Component&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ng-container&lt;/span&gt; &lt;span class="na"&gt;#container&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-container&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego, en el código TypeScript, se accede a esa ubicación específica usando &lt;code&gt;viewChild&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, la creación del componente dinámico con &lt;code&gt;createComponent&lt;/code&gt; se realiza directamente en ese contenedor, asegurando que se renderice en el lugar deseado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuración con &lt;code&gt;bindings&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La propiedad &lt;code&gt;bindings&lt;/code&gt; permite definir &lt;strong&gt;"enlaces de entrada"&lt;/strong&gt; (&lt;code&gt;input&lt;/code&gt;), &lt;strong&gt;"enlaces de salida"&lt;/strong&gt; (&lt;code&gt;output&lt;/code&gt;) y &lt;strong&gt;"enlaces bidireccionales"&lt;/strong&gt; (&lt;code&gt;two-way bindings&lt;/code&gt;) en un &lt;strong&gt;estilo unificado&lt;/strong&gt;. Esto elimina la necesidad de &lt;code&gt;setInput()&lt;/code&gt; manuales y de suscripciones.&lt;/p&gt;

&lt;p&gt;Aquí está el código completo para un ejemplo práctico, como un &lt;code&gt;DialogComponent&lt;/code&gt;, que ahora se conecta con un solo "conector modular":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enfoque Angular 20 (Declarativo)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DialogComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dialog/dialog.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button (click)="createDynamic()"&amp;gt;Create Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;ng-container #container&amp;gt;&amp;lt;/ng-container&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;createDynamic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;DialogComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="c1"&gt;// Conexión del cable de entrada 'isOpen'&lt;/span&gt;
          &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isOpen&lt;/span&gt;&lt;span class="dl"&gt;"&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

          &lt;span class="c1"&gt;// Conexión del cable de entrada 'title'&lt;/span&gt;
          &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

          &lt;span class="c1"&gt;// Conexión del cable de salida 'onClose' para que se autodesconecte&lt;/span&gt;
          &lt;span class="nf"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onClose&lt;/span&gt;&lt;span class="dl"&gt;"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La nueva API &lt;strong&gt;gestiona automáticamente la limpieza de suscripciones&lt;/strong&gt; cuando el componente es destruido, eliminando las &lt;strong&gt;pesadillas de gestión de memoria&lt;/strong&gt; y los cables sueltos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Las tres funciones de enlace en detalle
&lt;/h2&gt;

&lt;p&gt;La API de &lt;strong&gt;"enlaces"&lt;/strong&gt; (&lt;code&gt;bindings&lt;/code&gt;) se compone de tres funciones esenciales que deben importarse desde &lt;code&gt;@angular/core&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;inputBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta función se utiliza para conectar las &lt;strong&gt;"entradas"&lt;/strong&gt; (&lt;code&gt;inputs&lt;/code&gt;) del componente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Argumento&lt;/th&gt;
&lt;th&gt;Propósito&lt;/th&gt;
&lt;th&gt;Detalles&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primer Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El nombre de la entrada.&lt;/td&gt;
&lt;td&gt;Es el nombre del conector en la tarjeta.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Segundo Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El valor.&lt;/td&gt;
&lt;td&gt;Es el valor que se transmite. Puede ser un &lt;strong&gt;valor estático&lt;/strong&gt; (un cable con un valor fijo) o una &lt;strong&gt;&lt;code&gt;signal&lt;/code&gt;&lt;/strong&gt; (un cable inteligente que transmite actualizaciones).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cuando se proporciona un &lt;code&gt;signal&lt;/code&gt; directamente, &lt;code&gt;inputBinding&lt;/code&gt; &lt;strong&gt;accede automáticamente al valor de la &lt;code&gt;signal&lt;/code&gt;&lt;/strong&gt; y &lt;strong&gt;rastrea reactivamente los cambios&lt;/strong&gt;, actualizando la entrada del componente sin necesidad de un &lt;code&gt;effect&lt;/code&gt; manual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplos de &lt;code&gt;inputBinding&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Entrada estática: el valor no cambia después de la creación&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Datos cargados&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;// Entrada dinámica: automáticamente reactiva a los cambios en la signal&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;// Entrada calculada: utiliza una función computada (también reactiva)&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statusText&lt;/span&gt;&lt;span class="dl"&gt;'&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="s2"&gt;`Usuario: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt; - Estado: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;systemStatus&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;code&gt;outputBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta función maneja los &lt;strong&gt;"eventos de salida"&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;) emitidos por el componente dinámico.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Argumento&lt;/th&gt;
&lt;th&gt;Propósito&lt;/th&gt;
&lt;th&gt;Detalles&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primer Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El nombre de la salida.&lt;/td&gt;
&lt;td&gt;Es el nombre del cable de salida que emite un evento.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Segundo Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Una función de &lt;strong&gt;"devolución de llamada"&lt;/strong&gt; (&lt;code&gt;callback&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;Es la lógica que se ejecuta cuando el cable emite un evento.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Se puede especificar el tipo de valor emitido usando un &lt;strong&gt;"tipo genérico"&lt;/strong&gt; (&lt;code&gt;generic type&lt;/code&gt;) para mejorar la seguridad de tipos en TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Salida básica: Maneja el evento de cierre&lt;/span&gt;
&lt;span class="nf"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dismissed&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Notificación cerrada!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;

&lt;span class="c1"&gt;// Salida con datos y tipado (UserEvent es un tipo genérico)&lt;/span&gt;
&lt;span class="nx"&gt;outputBinding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userAction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventData&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;
  
  
  3. &lt;code&gt;twoWayBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta es la solución simplificada para el &lt;strong&gt;"enlace de datos bidireccional"&lt;/strong&gt; (&lt;code&gt;two-way data binding&lt;/code&gt;), reemplazando el cableado manual complejo.&lt;/p&gt;

&lt;p&gt;Simplemente se define el nombre de la &lt;strong&gt;"entrada modelo"&lt;/strong&gt; (&lt;code&gt;input model&lt;/code&gt;) y se proporciona la &lt;code&gt;signal&lt;/code&gt; del componente padre que se desea mantener sincronizada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sincroniza la propiedad 'isUrgent' del componente con 'this.urgentModeSignal' del padre&lt;/span&gt;
&lt;span class="nf"&gt;twoWayBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isUrgent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urgentModeSignal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular maneja automáticamente la convención de sufijo &lt;strong&gt;&lt;code&gt;Change&lt;/code&gt;&lt;/strong&gt; (por ejemplo, &lt;code&gt;isUrgent&lt;/code&gt; se empareja con la salida &lt;code&gt;isUrgentChange&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  Directivas aplicadas en tiempo de ejecución
&lt;/h2&gt;

&lt;p&gt;Angular 20 también permite &lt;strong&gt;añadir componentes o características adicionales&lt;/strong&gt; (&lt;code&gt;directives&lt;/code&gt;) al componente creado dinámicamente. Esto se logra mediante la propiedad &lt;code&gt;directives&lt;/code&gt; en la configuración de &lt;code&gt;createComponent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para directivas sencillas, se proporciona el nombre del constructor de la directiva. Para directivas más complejas que requieren configuración, se proporciona un objeto que incluye la clave &lt;code&gt;type&lt;/code&gt; (el constructor de la directiva) y la propiedad &lt;code&gt;bindings&lt;/code&gt; para configurar sus propias entradas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo de directivas de runtime:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configuraremos un &lt;code&gt;NotificationComponent&lt;/code&gt; con una directiva simple (&lt;code&gt;FocusHighlightDirective&lt;/code&gt;) y una directiva compleja de la librería Material (&lt;code&gt;SnackbarDirective&lt;/code&gt;) para mostrar mensajes de estado al pasar el ratón:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NotificationComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mueva el ratón para ver más detalles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;directives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Directiva simple sin configuración&lt;/span&gt;
    &lt;span class="nx"&gt;FocusHighlightDirective&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// Directiva compleja con configuración de entradas&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SnackbarDirective&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// La clase de la directiva&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// Configura las entradas de la directiva&lt;/span&gt;
        &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;snackbarMessage&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Información extra al hacer hover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;snackbarPosition&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;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;p&gt;Esta capacidad permite un diseño más modular y una configuración dinámica de la experiencia del usuario.&lt;/p&gt;




&lt;p&gt;En resumen, el nuevo enfoque de Angular 20 hace que la creación de componentes dinámicos sea &lt;strong&gt;más consistente, limpia y legible&lt;/strong&gt;, ya que la sintaxis de &lt;strong&gt;"enlace"&lt;/strong&gt; (&lt;code&gt;binding&lt;/code&gt;) ahora es idéntica a la de las plantillas de Angular, además de ofrecer reactividad incorporada y gestión simplificada de la memoria. Ahora, en lugar de &lt;strong&gt;ensamblar una PC a mano&lt;/strong&gt;, utilizas un &lt;strong&gt;"panel de control" unificado&lt;/strong&gt; para la configuración y conexión de tus componentes.&lt;/p&gt;

&lt;p&gt;Bonus :  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/~/github.com/AntonioCardenas/ngviewcontainerref" rel="noopener noreferrer"&gt;stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AntonioCardenas/ngviewcontainerref" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>spanish</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
