<?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: Evgenii Kalkutin</title>
    <description>The latest articles on DEV Community by Evgenii Kalkutin (@ekalkutin).</description>
    <link>https://dev.to/ekalkutin</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%2F2905673%2F6e4acd0c-a1df-43e2-80b5-18f131ffa271.jpg</url>
      <title>DEV Community: Evgenii Kalkutin</title>
      <link>https://dev.to/ekalkutin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ekalkutin"/>
    <language>en</language>
    <item>
      <title>The Node.js Performance Trap Most Developers Fall Into</title>
      <dc:creator>Evgenii Kalkutin</dc:creator>
      <pubDate>Wed, 23 Apr 2025 17:41:33 +0000</pubDate>
      <link>https://dev.to/ekalkutin/the-nodejs-performance-trap-most-developers-fall-into-2ida</link>
      <guid>https://dev.to/ekalkutin/the-nodejs-performance-trap-most-developers-fall-into-2ida</guid>
      <description>&lt;h2&gt;
  
  
  The Illusion of Optimization
&lt;/h2&gt;

&lt;p&gt;Many Node.js developers believe they're writing efficient code by using modern array methods. They praise the platform's non-blocking nature while unknowingly creating performance bottlenecks. The reality? Their approaches often backfire, leading to sluggish applications and wasted resources.&lt;/p&gt;

&lt;p&gt;Consider this common pattern, an elegant one-liner you wrote:&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;massiveArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expensiveOperation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While seemingly elegant, this approach carries significant drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory Overhead&lt;/strong&gt; - Creates an entirely new copy of your data in memory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eager Execution&lt;/strong&gt; - Processes everything immediately, regardless of need&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking Behavior&lt;/strong&gt; - Ties up the event loop during large operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability Issues&lt;/strong&gt; - Risks crashing when handling substantial datasets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Node.js environments, these problems compound:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strict default memory limits often trigger out-of-memory crashes&lt;/li&gt;
&lt;li&gt;No built-in mechanism for gradual processing or load management&lt;/li&gt;
&lt;li&gt;Complete lack of backpressure handling in synchronous operations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Better Approach: Intelligent Data Processing
&lt;/h2&gt;

&lt;p&gt;The good news is we have better tools at our disposal now. Instead of processing everything up front, modern JavaScript lets us work with data more intelligently through lazy evaluation. This approach only works with items when they're actually needed, which keeps memory usage steady even with massive datasets. It also plays nicely with streaming workflows where data flows continuously.&lt;/p&gt;

&lt;p&gt;Generator functions provide a clean way to implement this pattern. Take this example:&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;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;processData&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;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&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;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;transform&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="c1"&gt;// Natural break point for event loop&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;From an execution model perspective, generators implement cooperative multitasking natively. By yielding control at each iteration, they preserve the event loop's non-blocking characteristics while enabling deterministic interleaving of operations. This execution model provides several key benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Backpressure Implementation&lt;/strong&gt;: The pull-based iteration model creates natural flow control boundaries where downstream consumption rates dictate upstream production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First-Class Async Integration&lt;/strong&gt;: The model extends cleanly to asynchronous contexts through async generators, maintaining consistency across sync/async boundaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream Processing Foundation&lt;/strong&gt;: Generators serve as the primitive building block for Node.js streams, enabling efficient pipeline composition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory-Safe Execution&lt;/strong&gt;: The incremental processing model prevents memory spikes and GC pressure associated with batch operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For asynchronous workflows, the same principles apply with async generators:&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;processStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&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;dataStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;transformAsync&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Evolving Your JavaScript Mindset
&lt;/h2&gt;

&lt;p&gt;Transitioning from traditional array operations to modern iteration protocols requires more than just new syntax - it demands a fundamental shift in how we think about data processing. The table below contrasts these paradigms at a deeper level than just API differences:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;🚫 Old Way&lt;/th&gt;
&lt;th&gt;✅ Better Way&lt;/th&gt;
&lt;th&gt;💡 Benefit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Eager processing&lt;/td&gt;
&lt;td&gt;Lazy evaluation&lt;/td&gt;
&lt;td&gt;Only works when needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy all data&lt;/td&gt;
&lt;td&gt;Process in-place&lt;/td&gt;
&lt;td&gt;O(n) → O(1) memory complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocking&lt;/td&gt;
&lt;td&gt;Non-blocking&lt;/td&gt;
&lt;td&gt;No app freezes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One big batch&lt;/td&gt;
&lt;td&gt;Gradual chunks&lt;/td&gt;
&lt;td&gt;Handles huge data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rigid&lt;/td&gt;
&lt;td&gt;Flexible&lt;/td&gt;
&lt;td&gt;Works in more situations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The JavaScript ecosystem has evolved - and so must your optimization strategies. While Array methods served their purpose, modern systems demand generator patterns that align with Node.js' non-blocking architecture and memory constraints.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://kalkutin.dev" rel="noopener noreferrer"&gt;Evgeny Kalkutin&lt;/a&gt; - &lt;a href="https://www.credly.com/badges/486a76a8-4bc3-40d7-bd63-30f77c68fbca/public_url" rel="noopener noreferrer"&gt;JSNSD&lt;/a&gt;/&lt;a href="https://www.credly.com/badges/b92c0c45-0604-4321-b696-607bb508d1c8/public_url" rel="noopener noreferrer"&gt;JSNAD&lt;/a&gt; Certified specialist  &lt;/p&gt;

&lt;p&gt;Got your own horror story? Share it in the comments — best one gets a thread breakdown on &lt;a href="https://t.me/ecalcutin" rel="noopener noreferrer"&gt;my Telegram&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Building Universal npm Libraries: Supporting Both CJS and ESM</title>
      <dc:creator>Evgenii Kalkutin</dc:creator>
      <pubDate>Tue, 15 Apr 2025 21:05:38 +0000</pubDate>
      <link>https://dev.to/ekalkutin/building-universal-npm-libraries-supporting-both-cjs-and-esm-50lb</link>
      <guid>https://dev.to/ekalkutin/building-universal-npm-libraries-supporting-both-cjs-and-esm-50lb</guid>
      <description>&lt;h2&gt;
  
  
  Why Dual Packages Matter
&lt;/h2&gt;

&lt;p&gt;The JavaScript ecosystem currently operates with two module systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CommonJS (CJS)&lt;/strong&gt; - The traditional Node.js system using require()&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ES Modules (ESM)&lt;/strong&gt; - The modern standard using import/export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This divide creates real challenges. For example, when popular libraries like &lt;a href="https://www.npmjs.com/package/chalk" rel="noopener noreferrer"&gt;&lt;code&gt;chalk&lt;/code&gt;&lt;/a&gt; transitioned to ESM-only in version 5, many existing CommonJS projects faced compatibility issues. While ESM is the future, the reality is that numerous production systems still rely on CJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Dual-Package Support
&lt;/h2&gt;

&lt;p&gt;By building libraries that support both formats, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain backward compatibility&lt;/li&gt;
&lt;li&gt;Support modern JavaScript workflows&lt;/li&gt;
&lt;li&gt;Reduce ecosystem fragmentation&lt;/li&gt;
&lt;li&gt;Provide a smoother migration path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a straightforward approach to implement dual-package support.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-lib/
├── dist/                           # Generated output (added to .gitignore)
├── src/                            # Source files in TypeScript/ES6
│   ├── utils.ts                    # Library functionality
│   └── index.ts                    # Main entry point
├── package.json                    # Dual-package configuration
├── rollup.config.js                # Build setup
├── tsconfig.declarations.json      # TS declarations config 
└── tsconfig.json                   # TS base config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  TypeScript Support
&lt;/h4&gt;

&lt;p&gt;We use two &lt;code&gt;tsconfig&lt;/code&gt; files for optimal compilation:&lt;/p&gt;

&lt;p&gt;Base Config (&lt;code&gt;tsconfig.json&lt;/code&gt;)**&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;"compilerOptions"&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;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ESNext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Preserve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bundler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src"&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;"include"&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;"src/**/*.ts"&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;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles the main transpilation&lt;/li&gt;
&lt;li&gt;Outputs modern JavaScript (ESM by default)&lt;/li&gt;
&lt;li&gt;Used by Rollup during build&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Declarations Config (&lt;code&gt;tsconfig.declarations.json&lt;/code&gt;)&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;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./tsconfig.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&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;"declaration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"emitDeclarationOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/types"&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;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates type definitions (.d.ts files)&lt;/li&gt;
&lt;li&gt;Runs separately from main build&lt;/li&gt;
&lt;li&gt;Ensures clean type output without JS files&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Build Configuration (&lt;code&gt;rollup.config.js&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;typescript&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;@rollup/plugin-typescript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&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="na"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist/esm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;esm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;entryFileNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name].mjs&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="na"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist/cjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;entryFileNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name].cjs&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;typescript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;tsconfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tsconfig.json&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Creates separate ESM (.mjs) and CJS (.cjs) builds&lt;/li&gt;
&lt;li&gt;Uses TypeScript plugin for compilation&lt;/li&gt;
&lt;li&gt;Maintains clean output structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Configure &lt;code&gt;package.json&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; file is crucial for dual-package support. Here are the key configuration aspects:&lt;/p&gt;

&lt;p&gt;Module System Configuration:&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/cjs/index.cjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/esm/index.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/types/index.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exports"&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;"."&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;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/cjs/index.cjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"import"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/esm/index.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/types/index.d.ts"&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;It's critical to properly separate dependencies for build tools (Rollup, TypeScript, etc.)&lt;br&gt;
&lt;code&gt;devDependencies&lt;/code&gt;:&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;"@rollup/plugin-typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^12.1.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@types/node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^22.14.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rollup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.40.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tslib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.8.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.8.3"&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;Use &lt;code&gt;dependencies&lt;/code&gt; only for packages your library actually uses at runtime.&lt;br&gt;
Why this separation matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Installation Efficiency&lt;/strong&gt;: npm/yarn won't install devDependencies for end users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller Bundle Size&lt;/strong&gt;: Prevents unnecessary packages from being included&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear Dependency Documentation&lt;/strong&gt;: Shows what's needed for building vs running&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Reduces potential attack surface in production&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Best Practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only include truly required packages in dependencies&lt;/li&gt;
&lt;li&gt;Keep all build/test tools in &lt;code&gt;devDependencies&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Specify exact versions (or use &lt;code&gt;^&lt;/code&gt;) for important compatibility&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm install --production&lt;/code&gt; to test your runtime dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: Well-structured dependencies make your library more reliable and easier to maintain.&lt;/p&gt;

&lt;p&gt;For a complete working example, check out this boilerplate project on GitHub:&lt;br&gt;
👉 &lt;a href="https://github.com/ecalcutin/toolstack/tree/docs/example-boilerplate" rel="noopener noreferrer"&gt;Dual-Package Library Example&lt;/a&gt;&lt;br&gt;
It includes all the configurations discussed, so you can fork it or use it as a reference.&lt;/p&gt;

&lt;p&gt;If you found this guide helpful:&lt;br&gt;
⭐ Give it a star on GitHub to support the project!&lt;br&gt;
💬 Leave a comment below with your thoughts or questions.&lt;br&gt;
🔄 Share with others who might benefit from it.&lt;/p&gt;

&lt;p&gt;Happy coding, and may your libraries work everywhere! 🚀&lt;br&gt;
With respect,&lt;br&gt;
Evgeny Kalkutin - &lt;a href="https://kalkutin.dev/" rel="noopener noreferrer"&gt;kalkutin.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
