Obfuscation के presets

minify से extreme तक सुरक्षा के पाँच स्तर, हर एक जो complexity target सेट करता है, और zero-config default (light) पहले से क्या गारंटी देता है।

Preset transforms का एक नामित set है जिसकी size और runtime लागत ज्ञात है। भारी preset ज़्यादा transformation लगाता है; यह सुरक्षा में मापी गई बढ़त नहीं है। एक नाम complexity target तय करता है; output size उसी target से तय होता है। complexity को सीधे set करने पर target override हो जाता है, और सीधे set की गई value हमेशा हर token पर लागू होती है, light पर भी।

The five obfuscation presets ranked by complexity target, with light marked as the defaultextremetarget 25hardtarget 12mediumtarget 7lighttarget 5DEFAULTminifytarget 0Zero config gives you light: string literals encoded. Step up per project.

सीढ़ी

Presetcomplexityसामान्य gzipped sizeString floorइसे कब चुनें
minify01.09x से 1.17xबंदकोई obfuscation नहीं। Identifiers rename किए जाते हैं और code compress किया जाता है; string literals पढ़ने योग्य रहते हैं।
light51.29x से 1.60xचालूडिफ़ॉल्ट। minify में string encoding जोड़ता है और syntax को दोबारा लिखता है, बिना किसी संरचनात्मक layer के। पूरे app bundle के लिए सही preset।
medium76.04x से 8.33xचालूऐसा code जिसे आप समझने में उल्लेखनीय रूप से कठिन बनाना चाहते हैं। पूरे app bundle पर यह startup समय को कई गुना कर देता है (load लागत), इसलिए पहले अपने pages मापें।
hard126.62x से 9.23xचालूवह code जो अहम है: pricing, gating, license checks, client-side business logic। इसे एक directive से उसी code पर लक्षित करें; पूरे bundle पर इसकी लागत medium से ज़्यादा है।
extreme258.25x से 11.19xचालूसबसे ऊँची लागू complexity। इसे पूरे bundle के बजाय किसी एक फ़ाइल या region पर लक्षित करें।

ऊपर दिए आँकड़े पाँच असली, पहले से minified production bundles पर, AfterPack 0.2.6 के साथ 2026-10-16 को, पहले से minified उसी फ़ाइल के मुक़ाबले gzipped output का मापा गया आकार हैं; तरीक़ा Performance पर है।

किसी भी positive target के लिए string floor चालू रहता है।

Load लागत

AfterPack 1.0.0 के साथ 2026-10-24 को, Vite और React, Vue, Astro, SvelteKit और Next.js से बने पाँच छोटे apps पर मापा गया। हर app को उसके पूरे bundle को एक preset पर रखकर चलाया गया और उसकी तुलना AfterPack के बिना build किए गए उसी app से की गई; तरीक़ा और हर app का समय Performance पर है।

PresetPage जितना JavaScript load करता है, uncompressedपहले काम करने वाले click तक का समय
light1.12x से 1.42x+4 ms से +32 ms
medium10.2x से 11.9x3.1x से 11x
hard14.3x से 15.8x3.2x से 13.7x
extreme27.1x से 30.7x5.9x से 24x

हर framework पर size लगभग एक ही गुणक से बढ़ता है। Startup समय इस हिसाब से बढ़ता है कि page के respond करने से पहले उस code का कितना हिस्सा चलता है, इसलिए Next.js app ने सबसे ज़्यादा कीमत चुकाई। Framework का अपना runtime bundle का हिस्सा है, और हर preset उसे भी protect करता है।

पूरे app bundle पर light ज़्यादा से ज़्यादा कुछ दसियों milliseconds जोड़ता है। medium और ऊपर, preset को पूरे bundle पर ship करने से पहले अपने pages ख़ुद मापें।

डिफ़ॉल्ट light है

बिना किसी --preset के npx afterpack@latest dist/ चलाएँ, या एक plugin install करके कुछ भी configure न करें, और आपको light मिलता है।

$ npx afterpack@latest dist/
npx afterpack@latest dist/ --preset=hard    # step up

Flags अपनी value को = से जोड़ते हैं। Space से अलग की गई value को एक अज्ञात flag के रूप में अस्वीकार कर दिया जाता है।

light zero-config floor है। हर string literal जिसे यह फिर से लिख सकता है, एक runtime decoder से होकर जाता है। यह identifiers को rename करता है और syntax को दोबारा लिखता है, और कोई संरचनात्मक layer नहीं जोड़ता। Engine 0.2.3 से, minify और light पर loops को अब callback helpers में नहीं बदला जाता, जिससे hot loops में इन helpers की वजह से होने वाली 2-5x धीमी गति ख़त्म हो जाती है। light पर property और global names अब भी encoded constants से होकर जाते हैं, जिसकी बहुत hot code में कुछ लागत होती है। कुछ strings हर preset पर पढ़ने योग्य रहती हैं: directive prologues, typeof के comparands, वे property names जिनकी runtime को ज़रूरत है, और export names। Protection Map उन्हें सूचीबद्ध करता है, और engine हर build पर उनकी गिनती और कुल bytes रिपोर्ट करता है। Preset को medium या उससे ऊपर बढ़ाना हर token पर संरचनात्मक काम जोड़ता है: inflation, control-flow reshaping, और एक साझा runtime value से keyed strings और integers। यह string की पठनीयता नहीं बदलता, जो पहले से ही अपने floor पर है।

minify वह एक पायदान है जो floor को बंद कर देता है। Engine 0.2.3 से, यह केवल identifiers को rename करता है और code को compress करता है, जिसमें कोई obfuscation लागू नहीं होती। Engine 0.2.2 minify पर syntax को भी दोबारा लिखता था।

Size का budget

हर output में engine का निश्चित runtime overhead होता है, यानी decoders और integer-expression interpreter, इसलिए कुछ सौ bytes की छोटी फ़ाइल ऊपर दी सीमाओं से भी आनुपातिक रूप से बड़ी निकलती है। अनुपात किसी असली bundle पर पढ़ें, किसी छोटी फ़ाइल पर नहीं।

inflation.max डिफ़ॉल्ट रूप से unset है, इसलिए complexity target अकेले output size तय करता है। इसे स्वयं तभी सेट करें जब आपके पास एक वास्तविक size budget हो जिसे पार करने के बजाय आप build को विफल होने देना पसंद करें। किसी स्पष्ट रूप से सेट किए मान तक पहुँचना एक error है: DIAG_SIZE_CAP_REACHED, कोई output नहीं, CLI से exit 3, और plugin से build fail। Engine 0.2.3 से, उसकी जगह कम-सुरक्षित output कभी नहीं लिखा जाता: तैयार फ़ाइल को सीमा से जाँचा जाता है, और string encoding हमेशा पहले पूरी होती है। Engine 0.2.2 में एक तंग सीमा string encoding को पहले ही रोक सकती थी और कुछ strings को पढ़ने योग्य छोड़ सकती थी।

Obfuscated bytes, और इसलिए gzip size, design के अनुसार हर build में बदलते हैं। Default रूप से हर build एक नया seed लेता है, और seed: "git" हर commit पर नया seed लेता है, इसलिए हर release एक अलग program ship करती है। Fixed seed bytes को केवल उसी input और उसी engine version पर दोहराता है। Bundle-size budget उस code पर रखें जैसा आपके bundler ने लिखा, यानी AfterPack से पहले, या protected output के budget में margin रखें।

Target को सीधे सेट करना

complexity एक असीमित गैर-ऋणात्मक संख्या है। --complexity=200 एक मान्य Free-tier override है, जो extreme के सेट किए मान से कहीं आगे है।

npx afterpack@latest dist/ --preset=hard --complexity=40

यह hard है जिसका complexity target 40 पर override किया गया है; preset का बाक़ी हिस्सा नहीं बदलता। --complexity को एक preset का नाम देना एक error है।

एक region पर preset लागू करना

Free पर, एक preset पूरी build को cover करता है: CLI पर --preset, या आपके config में preset। इससे संकरा केवल एक control है, paths.exclude, जो पूरी फ़ाइलों को बाहर छोड़ देता है और उन्हें बिना protection के output में copy कर देता है। बाकी हर फ़ाइल preset की load लागत चुकाती है, इसलिए जब तक आपके अपने माप ज़्यादा की अनुमति न दें, पूरे app bundle को light पर रखें।

Pro पर, एक source directive किसी एक function या फ़ाइल पर भारी preset लगाता है, और बाकी bundle आपके global preset पर रहता है:

/* @afterpack preset=extreme */
function pricingEngine(plan, region) {
  return resolve(plan, region);
}
/* @afterpack end */

किसी फ़ाइल को cover करने के लिए, उसके code को एक directive में लपेटें। Directives केवल block comments होते हैं, जिन्हें एक framework plugin आपके source से पढ़ता है; CLI कोई directive नहीं पढ़ता। Grammar और tier के नियमों के लिए Directives देखें।

आगे