Danial.bakhtiari
توسعه فرانت‌اند و رابط کاربری

تفاوت NPM و NPX چیست؟

Hasti Taheri8 دقیقه مطالعهبازدید: ۹
npm-vs-npx

در مقاله‌های قبلی، اول سراغ npm رفتیم؛ از صفر شروع کردیم و دیدیم این ابزار اصلاً چیه، چه مشکلی رو حل می‌کنه و چطور نصب و نگهداری بسته‌ها رو برای هر برنامه‌نویس جاوااسکریپتی راحت کرده. در قسمت دوم هم پا رو یک قدم جلوتر گذاشتیم و کامل رفتیم سراغ npx ؛ دیدیم از کجا اومده، چطور کار می‌کنه و چه کاربردهای روزمره‌ای داره.

اول یک نگاه کلی: جدول مقایسه

قبل از رفتن سراغ جزئیات، بد نیست یک تصویر کلی از فرق این دو ابزار داشته باشیم:

جدول مقایسه‌ی کلی npm و npx
ویژگی npm npx
وظیفه‌ی اصلی نصب و مدیریت بسته‌ها اجرای یک‌باره‌ی بسته‌ها
نتیجه‌ی نهایی روی سیستم بسته روی دیسک باقی می‌ماند معمولاً چیزی دائمی باقی نمی‌ماند
کاربرد رایج افزودن یک وابستگی به پروژه امتحان سریع یک ابزار یا اجرای یک‌بار
نیاز به نصب قبلی بله، برای استفاده از بسته باید نصبش کنید خیر، در صورت نبودن بسته، خودش موقت می‌گیرد
تأثیر روی package.json می‌تواند وابستگی را ثبت کند هیچ اثری در package.json نمی‌گذارد
مقایسه‌ی سریع تفاوت‌های کلیدی npm و npx در یک نگاه

فرق در فلسفه: «داشتن» در برابر «امتحان‌کردن»

شاید بهترین راه برای فهمیدن این تفاوت، این باشه که به جای کلمات فنی، به هدفشون فکر کنیم. وقتی از npm استفاده می‌کنید، اساساً دارید می‌گویید: «این بسته باید بخشی از پروژه‌ی من باشه، همین حالا و در آینده هم». اما وقتی npx می‌زنید، دارید می‌گویید: «فقط برای همین یک لحظه بهش نیاز دارم، بعدش دیگه لازمش ندارم».

همین تفاوت نگاه، توضیح می‌دهد چرا مثلاً یک کتابخانه مثل react یا express همیشه با npm نصب می‌شود (چون قرار است بخش دائمی کد شما باشد)، ولی یک ابزار داربست‌ساز یا یک اسکریپت تک‌کاره معمولاً با npx اجرا می‌شود.

سناریوهای واقعی: کجا کدام‌یک را انتخاب کنیم؟

وقتی یک کتابخانه بخشی از کد شماست

اگر دارید از یک کتابخانه در کدتان import می‌کنید و بدون آن پروژه اصلاً کار نمی‌کند، جای شک نیست؛ باید با npm نصبش کنید تا هم در node_modules باشد و هم در package.json ثبت شود:

npm install axios

وقتی فقط می‌خواهید یک ابزار را امتحان کنید

فرض کنید کنجکاو شده‌اید ببینید یک ابزار خط‌فرمانی مثل بررسی‌کننده‌ی لینک‌های خراب یک سایت چه خروجی‌ای می‌دهد. نیازی نیست چیزی نصب بماند؛ همین کافی است:

npx broken-link-checker https://example.com

بعد از اجرا، هیچ ردی از این ابزار روی سیستمتان باقی نمی‌ماند.

وقتی ابزار را روزانه در همین پروژه استفاده می‌کنید

اگر یک ابزار خط‌فرمانی مثل prettier یا vite را قرار است بارها و بارها فقط در همین پروژه استفاده کنید، بهتر است به‌عنوان وابستگی توسعه نصبش کنید تا نسخه‌اش برای همه‌ی اعضای تیم یکسان و ثابت بماند:

npm install prettier --save-dev

و بعد هر بار با npx (یا از داخل اسکریپت‌های package.json) صدایش بزنید.

یک روز کاری معمولی: هر دو ابزار کنار هم

برای اینکه ماجرا کاملاً ملموس بشه، بیایید یک روز کاری فرضی رو مرور کنیم. فرض کنید می‌خواهید یک پروژه‌ی تازه با Vite بسازید. اولین دستوری که می‌زنید احتمالاً این است:

npx create-vite my-app
cd my-app
npm install

دقت کنید که همین یک خط، هر دو ابزار رو کنار هم نشون می‌ده: خط اول با npx اجرا شده، چون create-vite فقط یک‌بار قرار است داربست پروژه رو بسازد و بعد دیگر لازم نیست. خط دوم اما با npm است، چون حالا باید تمام وابستگی‌هایی که Vite در package.json نوشته، دائمی روی دیسک نصب بشن. بعد از آن، هر وقت خواستید ابزارهای توسعه مثل eslint یا vitest رو اجرا کنید، دوباره سراغ npx می‌روید، چون این بار npx خودش می‌فهمد که این ابزارها همین‌جا، داخل پروژه، نصب هستند و نیازی به دانلود مجدد نیست. یعنی در یک روز کاری معمولی، این دو ابزار اصلاً رقیب هم نیستند؛ دائم دست‌به‌دست هم می‌دهند.

نکته‌ی کلیدی: npx هم می‌تواند از نصب‌های npm استفاده کند

یک جای گیج‌کننده برای خیلی‌ها همین‌جاست: این دو ابزار رقیب هم نیستند، بلکه مکمل هم‌اند. وقتی داخل یک پروژه دستور npx prettier را می‌زنید، npx اول سراغ نسخه‌ای می‌رود که همان npm از قبل داخل پروژه نصب کرده. یعنی npx فقط برای «بسته‌های ناشناخته و موقت» ساخته نشده؛ یکی از کاربردهای اصلی‌اش، صدا زدن راحت همان بسته‌هایی است که خود npm قبلاً محلی نصب کرده، بدون این‌که لازم باشد مسیر طولانی node_modules/.bin را دستی بنویسید.

تأثیر روی تمیزی سیستم و حجم پروژه

یکی از عوارض جانبی نصب‌های سراسری و بی‌رویه با npm، پر شدن سیستم از ابزارهایی است که شاید فقط یک یا دوبار به آن‌ها نیاز داشته‌اید. با گذشت زمان، دستور npm list -g یک لیست بلندبالا از بسته‌هایی نشانتان می‌دهد که اسمشان را هم فراموش کرده‌اید. این همان جایی است که npx واقعاً به کمکتان می‌آید: چون چیزی را دائمی نگه نمی‌دارد، سیستمتان تمیزتر می‌ماند و لازم نیست هر از گاهی وقت بگذارید و ابزارهای قدیمی و بلااستفاده را دستی پاک کنید.

از طرف دیگر، خود npm هم برای این موضوع بی‌تفاوت نیست. پوشه‌ی node_modules به‌خاطر شهرتش در سنگین بودن معروف است، اما این سنگینی معمولاً مربوط به وابستگی‌های واقعی پروژه است، نه ابزارهای موقتی. به همین دلیل، یک قاعده‌ی خوب این است: هر بسته‌ای که فقط «ابزار کار» است و بخشی از منطق برنامه‌تان نیست، کاندید خوبی برای اجرا با npx است، نه اضافه‌شدن به وابستگی‌های دائمی پروژه.

فرق در کنترل نسخه

یک تفاوت عملی دیگر که خیلی وقت‌ها نادیده گرفته می‌شود، نحوه‌ی برخورد این دو با نسخه‌ی بسته‌هاست. با npm، نسخه‌ای که نصب می‌کنید تا وقتی خودتان دستی آپدیتش نکنید، ثابت می‌ماند و در package-lock.json هم قفل می‌شود. اما npx، اگر بسته را محلی پیدا نکند، معمولاً سراغ آخرین نسخه‌ی منتشرشده در رجیستری می‌رود؛ یعنی هر بار که یک دستور را با npx و بدون نصب قبلی اجرا می‌کنید، ممکن است نسخه‌ی متفاوتی نسبت به بار قبل دریافت کنید، مگر اینکه صریحاً نسخه را مشخص کرده باشید:

npx some-tool@2.0.0

فرق در سرعت: چرا گاهی npx کندتر به‌نظر می‌رسد؟

یک تجربه‌ی رایج این است که وقتی یک ابزار را برای اولین‌بار با npx اجرا می‌کنید، چند ثانیه‌ای معطل می‌مانید، اما همان ابزار وقتی از قبل با npm نصب شده باشد، تقریباً بی‌درنگ اجرا می‌شود. دلیلش هم روشن است: npx در آن حالت اول باید بسته را از رجیستری دانلود کند، بعد اجرایش کند. اما در اجراهای بعدی، اگر بسته هنوز در کش موقت npx باشد، دیگر دانلود مجددی در کار نیست و سرعت به‌مراتب بالاتر می‌رود. با این حال، برای ابزارهایی که روزانه و مکرر استفاده می‌کنید، همچنان بهتر است آن‌ها را با npm محلی نصب کنید تا این وابستگی به کش یا اتصال اینترنت هم از بین برود.

npx در محیط‌های CI/CD

در پایپ‌لاین‌های ساخت خودکار (CI/CD) مثل GitHub Actions یا GitLab CI، این تفاوت اهمیت بیشتری هم پیدا می‌کند. معمولاً اولین قدم در چنین محیط‌هایی اجرای npm ci یا npm install است تا وابستگی‌های ثبت‌شده در package-lock.json دقیقاً همان‌طور که قفل شده‌اند نصب شوند. بعد از آن، برای اجرای ابزارهایی مثل تست‌ها یا لینترها، معمولاً از npx استفاده می‌شود، چون همان نسخه‌ی محلی‌ای که تازه نصب شده را صدا می‌زند، بدون این‌که پایپ‌لاین را با نصب‌های سراسری اضافی شلوغ کند. اما یک نکته‌ی مهم هم هست: در محیط‌های CI که معمولاً هر بار از صفر ساخته می‌شوند، بهتر است از npx با فلگ --no-install استفاده کنید تا در صورت نبودن بسته، پایپ‌لاین بی‌سروصدا یک دانلود ناخواسته انجام ندهد و در عوض خطای واضحی نشان دهد.

چند سوءتفاهم رایج

آیا npx جایگزین کامل npm است؟

نه. npx برای اجرا ساخته شده، نه برای مدیریت وابستگی‌های دائمی پروژه. شما همچنان برای اضافه‌کردن یک کتابخانه به پروژه، افزودنش به package.json یا حذف بسته‌ها به npm نیاز دارید.

آیا هر دستوری که با npm کار می‌کند، با npx هم کار می‌کند؟

خیر. npx برای اجرای بسته‌های اجرایی (که یک فایل باینری یا CLI دارند) ساخته شده، نه برای دستورهایی مثل نصب یا حذف بسته. دستوری مثل npx install معنای درستی ندارد؛ install کار خود npm است.

آیا استفاده از npx همیشه یعنی دانلود از اینترنت؟

نه لزوماً. اگر بسته از قبل در پروژه (یا به‌صورت سراسری) نصب باشد، npx همان نسخه‌ی موجود را اجرا می‌کند و نیازی به دانلود نیست. دانلود موقت فقط وقتی اتفاق می‌افتد که بسته اصلاً هیچ‌جا نصب نباشد.

آیا npx فقط برای پروژه‌های Node.js کاربرد دارد؟

نه دقیقاً. چون npx می‌تواند مستقیم از رجیستری npm یا حتی از یک مخزن گیت‌هاب کد بگیرد و اجرا کند، خیلی وقت‌ها برای اسکریپت‌های عمومی، ابزارهای کوچک تک‌کاره یا حتی اتوماسیون‌هایی که ربطی مستقیم به یک پروژه‌ی خاص ندارند هم استفاده می‌شود. کافی است بسته‌ای در رجیستری npm موجود باشد.

آیا npm و npx نسخه‌های جداگانه‌ای دارند که باید هماهنگ بمانند؟

نه؛ چون npx بخشی از همان بسته‌ی npm است و با هم منتشر می‌شوند، معمولاً نیازی نیست نگران هماهنگی نسخه‌شان باشید. با آپدیت npm، نسخه‌ی npx هم به‌روز می‌شود.

جدول مرجع سریع دستورات

برای وقت‌هایی که فقط یک یادآوری سریع لازم دارید، این جدول کوچک همیشه به کارتان می‌آید:

جدول مرجع سریع دستورات npm و npx
هدف دستور npm دستور npx
افزودن دائمی یک کتابخانه npm install axios
امتحان یک ابزار بدون نصب npx cowsay "سلام"
اجرای ابزار نصب‌شده‌ی محلی پروژه ./node_modules/.bin/jest npx jest
ساخت داربست یک پروژه‌ی تازه npx create-next-app my-app
مرور سریع رایج‌ترین دستورات npm در برابر npx

یک قانون ساده برای انتخاب سریع

اگر هنوز مطمئن نیستید کدام‌یک را استفاده کنید، این قانون ساده معمولاً جواب می‌دهد:

  • اگر قرار است بسته بماند و بخشی از پروژه شود ← npm install
  • اگر فقط می‌خواهید یک‌بار اجرا شود و بروید ← npx
  • اگر بسته از قبل در پروژه نصب است و فقط می‌خواهید صدایش بزنید ← npx (که خودش سراغ نسخه‌ی محلی می‌رود)

جمع‌بندی

npm و npx اصلاً رقیب هم نیستند؛ دو تکه از یک پازل‌اند که هر کدام یک کار مشخص را انجام می‌دهند. npm برای این ساخته شده که بسته‌ها را نصب کند و نگهشان دارد، و npx برای این که سریع و بدون دردسر، یک بسته را اجرا کند و کنار برود. وقتی این فرق را در ذهن داشته باشید، دیگر هیچ‌وقت سردرگم نمی‌شوید که کدام دستور را کجا بزنید.

اگر هنوز مقاله‌های npm چیست؟ و راهنمای کامل npx را نخوانده‌اید، پیشنهاد می‌کنم یک سر به آن‌ها هم بزنید؛ جزئیات فنی و دستورات بیشتری در آن‌ها هست که اینجا فقط به آن‌ها اشاره کردیم.

مطالب مرتبط