<?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: Masanori Onoue</title>
    <description>The latest articles on DEV Community by Masanori Onoue (@ugaya40).</description>
    <link>https://dev.to/ugaya40</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%2F3264375%2F4f4cc4f9-5e28-4b33-9ef8-6269d19cad21.jpeg</url>
      <title>DEV Community: Masanori Onoue</title>
      <link>https://dev.to/ugaya40</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ugaya40"/>
    <language>en</language>
    <item>
      <title>[ShowDev]NPM Scripts Deck - VSCode and Stream Deck Integration Framework with NPM Scripts Provider</title>
      <dc:creator>Masanori Onoue</dc:creator>
      <pubDate>Tue, 03 Feb 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/ugaya40/showdevnpm-scripts-deck-vscode-and-stream-deck-integration-framework-with-npm-scripts-provider-7k4</link>
      <guid>https://dev.to/ugaya40/showdevnpm-scripts-deck-vscode-and-stream-deck-integration-framework-with-npm-scripts-provider-7k4</guid>
      <description>&lt;p&gt;Do you know &lt;a href="https://www.elgato.com/us/en/p/stream-deck" rel="noopener noreferrer"&gt;Stream Deck&lt;/a&gt;?&lt;br&gt;
It's so cool, isn't it? I've been admiring it for about two years.&lt;/p&gt;

&lt;p&gt;However, when I looked into it, I found it somewhat lacking for developers—you can't dynamically add buttons, and the only context-switching mechanism is based on which application window has focus...&lt;br&gt;
That would make it just a glorified shortcut launcher, and as a developer, I tend to just memorize the shortcuts I need. So I had no reason to buy one and kept hesitating.&lt;/p&gt;

&lt;p&gt;But about two weeks ago, I had a sudden urge to get a Stream Deck, and I made a decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I just needed to invent a reason to buy one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I built a Stream Deck plugin + VSCode extension that can dynamically display and execute NPM Scripts from VSCode. It occupies one page on the Stream Deck and follows dynamic context changes in VSCode.&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%2Frbbibubyx7oo72c0dndr.jpg" 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%2Frbbibubyx7oo72c0dndr.jpg" alt="Stream Deck showing NPM Scripts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I kept hacking on it with the real device, it somehow evolved into &lt;strong&gt;a multi-language-capable VSCode–Stream Deck integration framework + NPM Scripts provider&lt;/strong&gt;.&lt;br&gt;
I'll explain the VSCode Stream Deck integration framework later.&lt;/p&gt;

&lt;p&gt;This is convenient when you want to run multiple long-running scripts simultaneously, or when executing scripts with long names that are difficult to autocomplete due to NPM Scripts conventions (like &lt;code&gt;test:sub:ui&lt;/code&gt;).&lt;br&gt;
&lt;strong&gt;It supports multiple VSCode instances, monorepos, and multiple Stream Deck devices.&lt;/strong&gt; Display is also customizable.&lt;/p&gt;

&lt;p&gt;Even without a physical Stream Deck device, you can easily try it on your PC using &lt;a href="https://www.elgato.com/us/en/s/virtual-stream-deck" rel="noopener noreferrer"&gt;Virtual Stream Deck&lt;/a&gt;. But of course, trying it on the real device is the best.&lt;/p&gt;

&lt;p&gt;Because it looks this cool!&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Install the VSCode extension NPM Scripts Deck.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ugaya40.npm-scripts-deck" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Install NPM Scripts Deck&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ugaya40.vscode-streamdeck-integration" rel="noopener noreferrer"&gt;Stream Deck Integration&lt;/a&gt; will also be installed as a dependency. This is the VSCode Stream Deck integration framework mentioned later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ugaya40.vscode-streamdeck-integration" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;View Stream Deck Integration&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;You also need to install a plugin on the Stream Deck side. Install VSCode Runner from the Elgato Marketplace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.elgato.com/product/vscode-runner-287cbfd2-4508-4675-b5a2-6f75a52458b7" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Download from Elgato Market Place&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;You can uninstall it using the same procedure as other Stream Deck plugins. Manual installation doesn't leave any extra traces in your environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Just open a folder containing &lt;code&gt;package.json&lt;/code&gt; in VSCode. Even with a monorepo, buttons are displayed based on the ancestor &lt;code&gt;package.json&lt;/code&gt; relative to the active editor file.&lt;/p&gt;

&lt;p&gt;Press a button to execute the target npm script. While running, it shows "Running" status, and success/failure is displayed with visual feedback for a few seconds.&lt;br&gt;
For long-running tasks, you can cancel by pressing the button again. The result is also shown with visual feedback.&lt;/p&gt;

&lt;p&gt;For example, with a &lt;code&gt;package.json&lt;/code&gt; like this:&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;"scripts"&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;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"build:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"build:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"dev:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"dev:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"preview"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;It displays with some color coding by default.&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%2F2xi84k9ukaggr2bwyujr.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%2F2xi84k9ukaggr2bwyujr.png" alt="Default color coding"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ns-deck.json
&lt;/h3&gt;

&lt;p&gt;If you don't want to display certain packages or scripts, want more flexible color coding, or want to change icons, place an &lt;code&gt;ns-deck.json&lt;/code&gt; in the same directory as &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The file can be empty. If there's even one &lt;code&gt;ns-deck.json&lt;/code&gt; in the workspace opened by VSCode, only the NPM Scripts from &lt;code&gt;package.json&lt;/code&gt; files in the same directory as an &lt;code&gt;ns-deck.json&lt;/code&gt; will be displayed on Stream Deck. NPM Scripts from &lt;code&gt;package.json&lt;/code&gt; files without a corresponding &lt;code&gt;ns-deck.json&lt;/code&gt; in the same directory won't be shown.&lt;/p&gt;

&lt;p&gt;For details, please refer to the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ugaya40.npm-scripts-deck" rel="noopener noreferrer"&gt;NPM Scripts Deck documentation page&lt;/a&gt;, but for example, if you configure &lt;code&gt;ns-deck.json&lt;/code&gt; like this, the default display above changes to this:&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;"styles"&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="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Package"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"textColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&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="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/build/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hammer"&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="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/server/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"textColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#00bfff"&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="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/client/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"textColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ff6600"&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;&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%2Fr8tikavseyucn2vf30cy.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%2Fr8tikavseyucn2vf30cy.png" alt="Customized display"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream Deck Integration
&lt;/h2&gt;

&lt;p&gt;Stream Deck Integration is a VSCode extension that handles communication with Stream Deck, integration of multiple VSCode instances, and coordination of multiple Providers.&lt;/p&gt;

&lt;p&gt;A single VSCode instance can communicate between extensions using the Extension API.&lt;br&gt;
However, there's no built-in way for multiple VSCode windows to communicate with each other. This means Stream Deck cannot follow the context of multiple windows. I implemented this VSCode extension as a foundation to handle all these problems.&lt;br&gt;
Among the VSCode instances with this extension installed, one becomes the &lt;code&gt;Leader&lt;/code&gt;, the others become &lt;code&gt;Followers&lt;/code&gt;, and the &lt;code&gt;Leader&lt;/code&gt; communicates with Stream Deck on behalf of all instances.&lt;/p&gt;

&lt;p&gt;It uses WebSocket and GET/POST for Stream Deck and &lt;code&gt;Leader&lt;/code&gt;↔&lt;code&gt;Follower&lt;/code&gt; communication.&lt;br&gt;
A promotion system when the &lt;code&gt;Leader&lt;/code&gt;  instance crashes is also implemented, and when implementing your own Provider compatible with Stream Deck Integration, you can relatively easily implement your own Provider without being aware of multiple VSCode instances.&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%2Flubebtl4f01nqn4wmlko.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%2Flubebtl4f01nqn4wmlko.png" alt="Architecture diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For details, please see the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ugaya40.vscode-streamdeck-integration" rel="noopener noreferrer"&gt;Stream Deck Integration documentation page&lt;/a&gt;. It also describes settings for when multiple Providers coexist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Custom Providers
&lt;/h2&gt;

&lt;p&gt;By leveraging the Stream Deck Integration framework, you can easily implement providers for other languages or shortcut providers for VSCode. Git, Docker, dotnet, etc.—the possibilities are endless.&lt;/p&gt;

&lt;p&gt;Multiple Providers can coexist on Stream Deck Integration, and no matter how many Providers are added or updated, Stream Deck Integration and VSCode Runner (Stream Deck side plugin) don't need updates.&lt;/p&gt;

&lt;p&gt;For details, please refer to the &lt;a href="https://github.com/ugaya40/vscode-deck/blob/main/packages/streamdeck-integration/custom-provider-guide.md" rel="noopener noreferrer"&gt;Custom Provider Guide&lt;/a&gt;, but there are basically only 4 things a custom Provider needs to implement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call &lt;code&gt;registerProvider&lt;/code&gt; (registration API for Stream Deck Integration)&lt;/li&gt;
&lt;li&gt;Implement &lt;code&gt;getSlots&lt;/code&gt; function (corresponds to &lt;code&gt;/list&lt;/code&gt; in communication—retrieves button data to display)&lt;/li&gt;
&lt;li&gt;Implement &lt;code&gt;run&lt;/code&gt; function (corresponds to &lt;code&gt;/run&lt;/code&gt; in communication—executes command for the button)&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;notifyChange&lt;/code&gt; when the buttons to display on Stream Deck change&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to support long-running tasks for your Provider, you'll also need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement &lt;code&gt;cancel&lt;/code&gt; function (corresponds to &lt;code&gt;/cancel&lt;/code&gt; in communication)&lt;/li&gt;
&lt;li&gt;Notify status through &lt;code&gt;notifyTaskComplete&lt;/code&gt; when task completes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. By implementing just these without worrying about multiple VSCode instances, you automatically get multiple VSCode instance support.&lt;/p&gt;

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

&lt;p&gt;This project itself is a monorepo (NPM Scripts Deck / Stream Deck Integration / VSCode Runner), and I developed it with just one &lt;code&gt;ns-deck.json&lt;/code&gt; placed in the same directory as the root &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's quite convenient, so please buy a Stream Deck!&lt;br&gt;
It boosts your development mood too!&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%2Fckqkclzcsyd5x5g2437y.jpg" 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%2Fckqkclzcsyd5x5g2437y.jpg" alt="Stream Deck in action"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published in Japanese on &lt;a href="https://zenn.dev/ugaya40/articles/1cda5836812218" rel="noopener noreferrer"&gt;Zenn&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>vscode</category>
      <category>streamdeck</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
