<?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: Idev.d</title>
    <description>The latest articles on DEV Community by Idev.d (@alan_529cf536b9cf0f88ec8c).</description>
    <link>https://dev.to/alan_529cf536b9cf0f88ec8c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4084614%2F04a5e8e6-573a-415c-9e4a-b27fbebb5165.png</url>
      <title>DEV Community: Idev.d</title>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alan_529cf536b9cf0f88ec8c"/>
    <language>en</language>
    <item>
      <title>CI/CD with GitHub Actions: A Practical Setup for Small Teams</title>
      <dc:creator>Idev.d</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:56:55 +0000</pubDate>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c/cicd-with-github-actions-a-practical-setup-for-small-teams-507m</link>
      <guid>https://dev.to/alan_529cf536b9cf0f88ec8c/cicd-with-github-actions-a-practical-setup-for-small-teams-507m</guid>
      <description>&lt;p&gt;Our deployment used to be: local build, SCP to server, SSH to restart. 15 minutes per deploy, with production incidents from forgotten environment variables.&lt;/p&gt;

&lt;p&gt;Now it is: git push, then tests, build, and deploy run automatically. Zero manual steps, 5 minutes total. Here is how we set it up at &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend Deployment (Vue + Vite)
&lt;/h2&gt;

&lt;p&gt;The GitHub Actions workflow triggers on push to main. Steps: checkout, setup Node 20 with npm cache, run npm ci, lint, build, then SCP the dist folder to the production server and reload Nginx.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend Deployment (Spring Boot)
&lt;/h2&gt;

&lt;p&gt;Similar workflow but with Java 17 and Maven. Key addition: a health check after restart that curls the health endpoint and fails the workflow if the service did not start properly.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1. Cache Dependencies
&lt;/h3&gt;

&lt;p&gt;Using the cache option in setup-node or setup-java saves 60+ seconds per run.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Path Filters
&lt;/h3&gt;

&lt;p&gt;Only trigger backend deploy when backend files change. Add a paths filter so frontend changes do not trigger a backend rebuild.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Deploy Notifications
&lt;/h3&gt;

&lt;p&gt;Send success or failure messages to your team Slack or Lark channel automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Keep Last 5 Versions for Rollback
&lt;/h3&gt;

&lt;p&gt;Copy the current JAR with a timestamp before deploying, then delete all but the 5 most recent backups.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Health Check After Deploy
&lt;/h3&gt;

&lt;p&gt;Always verify the service actually started. If the health check fails, the workflow fails, and you get notified immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before and After
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deploy time&lt;/td&gt;
&lt;td&gt;15 min manual&lt;/td&gt;
&lt;td&gt;5 min automated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy frequency&lt;/td&gt;
&lt;td&gt;1-2x/week&lt;/td&gt;
&lt;td&gt;3-5x/day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failed deploys&lt;/td&gt;
&lt;td&gt;10%/month&lt;/td&gt;
&lt;td&gt;1%/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback time&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;td&gt;2 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GitHub Actions is free for public repos. Private repos get 2,000 free minutes monthly. The ROI is immediate.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small team, big output. &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. &lt;a href="https://idev.my/#contact" rel="noopener noreferrer"&gt;Free consultation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>cicd</category>
      <category>devops</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building a Stateless JWT Auth System with Spring Security 6</title>
      <dc:creator>Idev.d</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:51:02 +0000</pubDate>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c/building-a-stateless-jwt-auth-system-with-spring-security-6-234c</link>
      <guid>https://dev.to/alan_529cf536b9cf0f88ec8c/building-a-stateless-jwt-auth-system-with-spring-security-6-234c</guid>
      <description>&lt;p&gt;Spring Security 6 (Spring Boot 3.x) changed its API significantly. Here is a complete, working JWT authentication setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why JWT for Frontend-Backend Separation
&lt;/h2&gt;

&lt;p&gt;Session-based auth stores state on the server, making horizontal scaling painful. JWT is stateless and perfect for SPA + API architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Changes in Spring Security 6
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;WebSecurityConfigurerAdapter is gone. Use SecurityFilterChain beans instead.&lt;/li&gt;
&lt;li&gt;Lambda DSL is now the standard configuration style.&lt;/li&gt;
&lt;li&gt;Method security defaults to @PreAuthorize.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: JWT Utility Class
&lt;/h2&gt;

&lt;p&gt;Using JJWT 0.12.x (not the old 0.9.x, the API is completely different):&lt;/p&gt;

&lt;p&gt;The core methods are generateToken (builds a JWT with subject, issued-at, expiration, and signing key) and extractUsername (parses and verifies the token, then extracts the subject claim).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Security Configuration
&lt;/h2&gt;

&lt;p&gt;The SecurityFilterChain bean disables CSRF (not needed for stateless APIs), sets session creation policy to STATELESS, permits auth endpoints, requires authentication for admin endpoints, and adds the JWT filter before the UsernamePasswordAuthenticationFilter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Hardening Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Token expiration: 24 hours max&lt;/li&gt;
&lt;li&gt;Passwords: BCrypt, never MD5 or SHA&lt;/li&gt;
&lt;li&gt;JWT secret: environment variable, never hardcoded&lt;/li&gt;
&lt;li&gt;HTTPS only in production&lt;/li&gt;
&lt;li&gt;Rate limit login attempts&lt;/li&gt;
&lt;li&gt;Validate token on every request, not just check for presence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Pitfalls
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using JJWT 0.9.x docs with 0.12.x&lt;/strong&gt; - The API is completely different. Make sure your dependency version matches your code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Forgetting STATELESS session policy&lt;/strong&gt; - Without this, Spring creates sessions alongside JWT, defeating the purpose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not handling expired tokens gracefully&lt;/strong&gt; - Return 401 with a clear message, not a 500 error.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Small team, big output. &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. &lt;a href="https://idev.my/#contact" rel="noopener noreferrer"&gt;Free consultation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>springsecurity</category>
      <category>jwt</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Git Branch Strategy for Small Teams: What Actually Works</title>
      <dc:creator>Idev.d</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:50:55 +0000</pubDate>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c/git-branch-strategy-for-small-teams-what-actually-works-4kg8</link>
      <guid>https://dev.to/alan_529cf536b9cf0f88ec8c/git-branch-strategy-for-small-teams-what-actually-works-4kg8</guid>
      <description>&lt;p&gt;In our early days at &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt;, we made every Git mistake in the book: constant merge conflicts, chaotic releases, nobody knew which branch to hotfix from.&lt;/p&gt;

&lt;p&gt;After trying Git Flow, GitHub Flow, and Trunk-Based Development, here is what actually works for a 5-10 person team.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Git Flow
&lt;/h2&gt;

&lt;p&gt;Git Flow (main, develop, feature, release, hotfix) is designed for large teams with scheduled releases. For a small team shipping continuously, it is overkill: too many long-lived branches, merge conflicts pile up, release branches add ceremony with no value.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Actually Use: Enhanced GitHub Flow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. main is always deployable
&lt;/h3&gt;

&lt;p&gt;Protected branch. Only merge via PR. If main is broken, everything stops until it is fixed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Short-lived feature branches
&lt;/h3&gt;

&lt;p&gt;Branch from main, PR back to main. Branch lifespan: ideally under 3 days.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. PR rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;At least one review approval&lt;/li&gt;
&lt;li&gt;CI must pass&lt;/li&gt;
&lt;li&gt;Squash merge to keep main history clean&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Daily habits
&lt;/h3&gt;

&lt;p&gt;Start of day: sync with main via rebase. Stash unfinished work instead of committing half-done code. Clean up merged remote branches periodically.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The One Rule That Changed Everything
&lt;/h3&gt;

&lt;p&gt;Rebase before opening a PR. Not merge, rebase. This keeps the PR diff clean (only your changes, no merge commits) and makes review dramatically easier.&lt;/p&gt;

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

&lt;p&gt;For teams of 5-10: Enhanced GitHub Flow beats Git Flow and Trunk-Based. The strategy is not revolutionary. The discipline of following it consistently is what makes the difference.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small team, big output. &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. &lt;a href="https://idev.my/#contact" rel="noopener noreferrer"&gt;Free consultation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>devops</category>
      <category>teamwork</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>5 Practical Solutions for Large List Rendering in Vue 3</title>
      <dc:creator>Idev.d</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:39:10 +0000</pubDate>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c/5-practical-solutions-for-large-list-rendering-in-vue-3-4lbi</link>
      <guid>https://dev.to/alan_529cf536b9cf0f88ec8c/5-practical-solutions-for-large-list-rendering-in-vue-3-4lbi</guid>
      <description>&lt;p&gt;When rendering hundreds or thousands of items, Vue 3 apps can lag noticeably. We hit this problem in a recent inventory management system — 5,000 items caused 3-second load times and scrolling dropped below 15fps.&lt;/p&gt;

&lt;p&gt;Here are 5 solutions we tested, ranked by effectiveness.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Virtual Scrolling (Best Overall)
&lt;/h2&gt;

&lt;p&gt;Only render DOM elements within the visible viewport. We recommend &lt;code&gt;vue-virtual-scroller&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;RecycleScroller&lt;/span&gt; &lt;span class="na"&gt;:items=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt; &lt;span class="na"&gt;:item-size=&lt;/span&gt;&lt;span class="s"&gt;"60"&lt;/span&gt; &lt;span class="na"&gt;key-field=&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#default=&lt;/span&gt;&lt;span class="s"&gt;"{ item }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&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="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/RecycleScroller&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Initial render dropped from 3.2s to 0.1s. Memory from 180MB to 35MB.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Pagination + Infinite Scroll
&lt;/h2&gt;

&lt;p&gt;Use the Intersection Observer API for load-on-scroll, fetching 20-50 items per request. Best when total data volume is unknown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;loadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sentinel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. v-memo Directive
&lt;/h2&gt;

&lt;p&gt;Vue 3.2+'s &lt;code&gt;v-memo&lt;/code&gt; caches subtree render results, skipping re-renders when dependent data hasn't changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item in list"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"item.id"&lt;/span&gt; &lt;span class="na"&gt;v-memo=&lt;/span&gt;&lt;span class="s"&gt;"[item.name, item.price]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ExpensiveComponent&lt;/span&gt; &lt;span class="na"&gt;:data=&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt; &lt;span class="nt"&gt;/&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;p&gt;Great for lists where individual items rarely change.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Web Worker Off-Thread Computing
&lt;/h2&gt;

&lt;p&gt;Move computation-intensive operations like filtering and sorting to Web Workers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./listWorker.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;filter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rawList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&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;filteredList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents main thread blocking during heavy operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. shallowRef + triggerRef
&lt;/h2&gt;

&lt;p&gt;For large lists that don't need deep reactivity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shallowRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hugeArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// After mutation:&lt;/span&gt;
&lt;span class="nf"&gt;triggerRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoids Vue creating deep proxies for every element — significant memory savings.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;th&gt;Render Time (5K items)&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default v-for&lt;/td&gt;
&lt;td&gt;3.2s&lt;/td&gt;
&lt;td&gt;180MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Virtual Scrolling&lt;/td&gt;
&lt;td&gt;0.1s&lt;/td&gt;
&lt;td&gt;35MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v-memo&lt;/td&gt;
&lt;td&gt;1.8s&lt;/td&gt;
&lt;td&gt;160MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shallowRef&lt;/td&gt;
&lt;td&gt;2.1s&lt;/td&gt;
&lt;td&gt;90MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Our recommendation&lt;/strong&gt;: Virtual scrolling first, pagination second. They solve the root cause (too many DOM nodes) rather than optimizing around it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small team, big output. &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. &lt;a href="https://idev.my/#contact" rel="noopener noreferrer"&gt;Free consultation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>Cursor vs Claude Code vs GitHub Copilot: Which AI Coding Tool Should You Use in 2026?</title>
      <dc:creator>Idev.d</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:39:06 +0000</pubDate>
      <link>https://dev.to/alan_529cf536b9cf0f88ec8c/cursor-vs-claude-code-vs-github-copilot-which-ai-coding-tool-should-you-use-in-2026-553n</link>
      <guid>https://dev.to/alan_529cf536b9cf0f88ec8c/cursor-vs-claude-code-vs-github-copilot-which-ai-coding-tool-should-you-use-in-2026-553n</guid>
      <description>&lt;p&gt;AI coding tools have evolved from "nice-to-have" to essential productivity tools. Our team at &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; uses multiple tools daily — here's our hands-on comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Contenders
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;Microsoft's offering, powered by OpenAI models, deeply integrated with VS Code. The most established AI coding assistant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cursor
&lt;/h3&gt;

&lt;p&gt;A standalone IDE forked from VS Code with built-in multi-model support, known for its Chat + Edit modes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Code
&lt;/h3&gt;

&lt;p&gt;Anthropic's CLI tool that works directly in the terminal. It can read/write files, execute commands, manage Git, and autonomously complete complex tasks in Agent mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Copilot&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Code Completion&lt;/td&gt;
&lt;td&gt;Excellent tab completion&lt;/td&gt;
&lt;td&gt;Excellent, multi-line prediction&lt;/td&gt;
&lt;td&gt;No inline completion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context Understanding&lt;/td&gt;
&lt;td&gt;Current file + recent files&lt;/td&gt;
&lt;td&gt;Project-level, indexes entire codebase&lt;/td&gt;
&lt;td&gt;Project-level, reads any file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactoring&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Moderate via Chat&lt;/td&gt;
&lt;td&gt;Strong — Agent mode handles cross-file refactoring autonomously&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terminal Integration&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Built-in terminal&lt;/td&gt;
&lt;td&gt;Native terminal tool with strong command execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-file Editing&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Natively supported, autonomously decides which files to modify&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Our Usage Strategy at iDev
&lt;/h2&gt;

&lt;p&gt;We use a "combo" approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily coding&lt;/strong&gt;: Cursor's inline completion + Chat mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex tasks&lt;/strong&gt;: Claude Code's Agent mode for cross-file modifications and architectural refactoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review&lt;/strong&gt;: Claude Code's built-in code review feature&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Verdict
&lt;/h2&gt;

&lt;p&gt;No single tool perfectly covers all scenarios. The key insight: &lt;strong&gt;use them together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Copilot and Cursor excel at real-time code assistance while you're typing. Claude Code excels at larger-scale tasks where you need an AI that understands your entire project and can make autonomous decisions.&lt;/p&gt;

&lt;p&gt;If you're only picking one, Cursor offers the best all-around experience. But if you're serious about maximizing productivity, the Cursor + Claude Code combination is hard to beat.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small team, big output. &lt;a href="https://idev.my" rel="noopener noreferrer"&gt;iDev&lt;/a&gt; builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. &lt;a href="https://idev.my/#contact" rel="noopener noreferrer"&gt;Free consultation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
