- scriptc सामान्य TypeScript को छोटे नेटिव binaries में compile करता है जो Node, V8 या JavaScript engine के बिना चलते हैं, और वास्तविक TypeScript compiler की type checking तथा Node behavior compatibility बनाए रखता है
- code structure के आधार पर तय करता है कि static compilation संभव है या नहीं; default रूप से native code बनाता है, और
--dynamicचुने जाने पर ही quickjs-ng के जरिए npm packages के JavaScript औरanytype code को चलाता है - classes, generics,
async/await, exceptions, regular expressions से लेकर Node server API,fetchऔर npm dependencies तक support करता है; unsupported syntax को error code, code frame और fix hints के साथ reject करता है - 800 से ज्यादा programs को Node और native binaries में चलाकर output और exit codes की तुलना करता है, और AddressSanitizer तथा reference count audits से memory errors जांचता है
- Apple M series measurements में startup time लगभग 2.4ms, static binary 170–200KB, typical RSS 1–4MB है; dynamic mode और embedded dependencies शामिल करने पर binary लगभग 3MB हो जाती है
Static compilation model
- अलग dialect या annotations के बिना मौजूदा TypeScript का उपयोग करता है, और
tsconfig.jsonकी checking strictness तथा TypeScript की वास्तविकes2025library लागू करता है- अगर project में
@types/nodeहै तो उसके साथ type checking करता है - बिना lowering वाला reachable code सटीक diagnostics देता है और compilation रोक देता है
- अगर project में
scriptc coverageanalysed statements की संख्या, statically compile होने वाला ratio, blocking factors और error codes दिखाता है- example में 4,481 statements में से 4,451, यानी 99%, statically compile होते हैं
- execution method को साफ तौर पर तीन stages में बांटा गया है
- Static compilation: default mode, जिसमें JavaScript engine के बिना native code में बदलता है
- Dynamic execution:
--dynamicदेने पर करीब 620KB का quickjs-ng शामिल करता है और npm packages के JavaScript तथाanytype code को चलाता है- static code में आने वाली सभी values को runtime पर validate करता है
- declared type और value अलग होने पर memory corrupt किए बिना पकड़े जा सकने वाला
TypeErrorthrow करता है
- Rejection: जो code handle नहीं किया जा सकता, उसके लिए error code, code frame और अक्सर fix hint देता है; चुपचाप गलत compile नहीं करता
Supported TypeScript and standard library
- language features में single-inheritance classes और dynamic dispatch, closures, generic monomorphization, discriminated unions, destructuring, spread, template literals, getters/setters और iterators support हैं
- safety साबित होने पर dynamic dispatch को devirtualize करता है
- discriminated unions को TypeScript narrowing का उपयोग करने वाले tag values से handle करता है
async/awaitको stackful fibers और JavaScript के अनुरूप scheduling से implement करता है- exceptions और
finally, optional, default और rest parameters support करता है
- regular expressions के लिए वही ECMAScript-compatible bytecode interpreter उपयोग करता है जो QuickJS इस्तेमाल करता है, और इसे केवल उन binaries में link करता है जो regular expressions का उपयोग करती हैं
- standard library में UTF-16 semantics का पालन करने वाली strings, और JavaScript जैसे order व identity rules वाले Array, Map, Set शामिल हैं
JSONकी type conversion runtime validation से गुजरती हैMath, typed arrays,Buffer, और typedcatchsupport करने वालीErrorhierarchy भी देता है
Node और Web API
- Node API में
fs,path,process,child_process,os,crypto,url/URL,zlib, timers और signal handlers support हैंfssynchronous और Promise APIs देता हैchild_processpipe streams support करता है- event loop में external dependency नहीं है
- server stack में
net,http,https,tls,dgram,dns,fs.watch,readlineशामिल हैं और real proxy server compile कर सकता है- TLS के लिए शामिल mbedTLS का उपयोग करता है
fetchऔर streams,Headers,AbortSignalजैसे WHATWG Web APIs के कुछ हिस्सों को उसी native network और TLS stack पर implement करता है- redirects, gzip,
AbortSignal.timeout, Node-style error causes support करता है - libcurl या system HTTP dependencies का उपयोग नहीं करता
- redirects, gzip,
npm dependencies और dynamic execution
--dynamicमें Node की module resolution method का उपयोग करता है और package द्वारा दी गई.d.tsके आधार पर type checking करता है- npm package का JavaScript build time पर binary में शामिल हो जाता है, इसलिए execution के दौरान
node_modulesनहीं पढ़ता scriptc coverage --dynamicदिखाता है कि हर statement static या dynamic region में कहां execute होता है और कौन से blockers बाकी हैं- JavaScript engine केवल explicit dynamic mode चुनने पर ही शामिल होता है, इसलिए binary size चुपचाप नहीं बढ़ती
Correctness और memory safety
- Differential testing में 800 से ज्यादा programs को Node और native binary में अलग-अलग चलाकर stdout, stderr और exit code की byte-by-byte तुलना की जाती है
- numeric output shortest round-trip representation का पालन करता है, और 10 लाख
doubleको Node से compare करके fuzzing validation करता है - servers को test करने के लिए दोनों implementations में real client drivers connect किए जाते हैं
- numeric output shortest round-trip representation का पालन करता है, और 10 लाख
- पूरा test set AddressSanitizer और reference count audit के तहत फिर चलाया जाता है; leak या use-after-free होने पर build fail हो जाता है
- Node से जानबूझकर अलग behavior कुछ दर्जन मामलों में है और मुख्य रूप से timing internals तथा error object properties से जुड़ा है
- हर difference documented और numbered है, hidden differences allow नहीं हैं
Performance characteristics
- Apple M series पर Node, Go, Rust, Zig के साथ identical tasks और byte-for-byte same output के आधार पर measure किया गया
- startup time लगभग 2.4ms है, जो Node के लगभग 47ms से कम, Zig जैसा, और Go/Rust से आगे है
- static binary size 170–200KB है, और
--dynamicव embedded dependencies शामिल करने पर लगभग 3MB है- comparison के लिए दिया गया Go binary लगभग 2MB, Node SEA 60–100MB है
- typical memory usage RSS 1–4MB है, जबकि Node 67–116MB है
- runtime JavaScript के अनुरूप
f64semantics बनाए रखते हुए ज्यादातर tasks में system languages से compete करता है- integer inference और ownership analysis roadmap में शामिल हैं
Explicit escape hatches
comptime(() => ...)compiler के अंदर isolated VM में TypeScript को build time पर चलाता है और result को literal के रूप में binary में डालता है--ffiकेवल signatures वाली TypeScript declarations को सीधे C ABI calls से जोड़ता है, और manifest में declared archives, objects और system libraries को link करता है- boundary explicit है और इसमें length information शामिल होती है
- details Native FFI guide में देखे जा सकते हैं
JSON.parse(...) as Configजैसे checked type assertions runtime validation code insert करते हैं- validation fail होने पर
expected number at $.port, got stringजैसी exception throw होती है जिसमें गलत path और expected/actual types शामिल होते हैं
- validation fail होने पर
Compiler architecture
- process क्रम है:
TypeScript → tsc parsing/type checking → lowering → typed IR → C → clang → native executable packages/compilerमें tsc API-based frontend, IR verification/serialization, LLVM और C backends शामिल हैं- frontend और backend के बीच interface के रूप में केवल IR का उपयोग करता है
- LLVM default code generator है और supported scope से बाहर programs के लिए transparent fallback path का उपयोग करता है
- C को permanent reference backend के रूप में रखा जाता है, और
--backend csource line information के साथ readable output बनाता है
packages/runtimereference-counted values और cycle collector, stackful fibers,kqueueevent loop, server stack, JavaScript-compatible numeric output implement करता है- feature-wise linking method से केवल वास्तव में उपयोग होने वाली features binary में शामिल होती हैं
packages/cliscriptc build,scriptc run,scriptc coveragecommands देता है
Installation और development
npm install -g scriptcसे install किया जाता है और clang जरूरी है- मुख्य platform macOS arm64 है, और Linux तथा Windows binaries cross-compile होते हैं
- हर platform को अलग differential test path से validate किया जाता है
- development
pnpm install && pnpm buildसे शुरू होता हैpnpm testdifferential test set और diagnostic snapshots चलाता हैSCRIPTC_SAN=1 pnpm testवही tests ASan और reference count audit के तहत चलाता हैpnpm scriptc build x.ts --emit-irgenerated C औरx.ir.jsonको preserve करता है
- सभी features differential tests के साथ जोड़ी जाती हैं, और merge होने से पहले normal tests व memory safety tests दोनों pass होने चाहिए
1 टिप्पणियां
Hacker News टिप्पणियाँ
लगता है Vercel लगभग हर महीने एक चर्चित प्रोजेक्ट निकालता है ताकि अपनी विश्वसनीयता और मौजूदगी बनाए रख सके। किसी गंभीर कंपनी या प्रोजेक्ट के scriptc इस्तेमाल करने की संभावना कम लगती है
योगदानकर्ताओं का सम्मान है, लेकिन कोड में Claude से जनरेट होने की झलक बहुत साफ दिखती है, और Claude को contributor के रूप में न दिखाया जाना इसे और संदिग्ध बनाता है
project / संबंधित HN पोस्ट
Porffor कुछ समय से यही लक्ष्य हासिल करने की कोशिश कर रहा है। इसके डेवलपर CanadaHonk बेहद प्रतिभाशाली हैं, लेकिन प्रोजेक्ट अभी भी Test262 का केवल लगभग 68% ही पास करता है
अगर मैंने प्रोजेक्ट का दायरा गलत नहीं समझा है, तो Vercel ने इतनी तेजी से जो प्रगति दिखाई है, वह काफी संदिग्ध लगती है
यह एकदम Vercel-स्टाइल प्रोजेक्ट है। रिलीज़ हुए 5 दिन, पूरा vibe coded, बिना किसी खास वजह के 1,500 stars, लेकिन किसी की समस्या हल नहीं करता, और ज़्यादा से ज़्यादा कुछ महीनों में maintenance बंद हो जाएगी
सिर्फ आलोचना करने के बजाय मैंने इसे लोकल के कई प्रोजेक्ट्स पर सीधे आज़माया, लेकिन सभी में code scope analysis के दौरान सैकड़ों errors आए, इसलिए यह व्यवहारिक रूप से उपयोग लायक नहीं था
अगर बाहरी libraries के बिना शून्य से लिखा जाए तो शायद इसे binary में compile किया जा सकता है, लेकिन फिर Rust, Go, Zig, D, C, V, Ada, C++, Nim, Swift, Kotlin Native, Haskell जैसी उन भाषाओं का उपयोग न करने का क्या कारण होगा जिन्हें शुरू से ही सही compilation के लिए डिज़ाइन किया गया है
TypeScript की ताकत सिर्फ उसकी expressiveness नहीं, बल्कि विशाल npm ecosystem के साथ compatibility भी है। ज़्यादातर packages type declarations से केवल interface परिभाषित करते हैं और असली कोड JavaScript में ship करते हैं, इसलिए package इस्तेमाल करने के लिए व्यवहारिक रूप से JavaScript engine चाहिए
अगर आप बिल्कुल शुरुआत से शुरू कर रहे हैं और npm packages बिल्कुल नहीं इस्तेमाल करने वाले हैं, तो AssemblyScript बेहतर विकल्प है। Node स्पष्ट रूप से सलाह देता है कि packages को TypeScript में publish न करें, क्योंकि TypeScript minor versions के बीच भी backward compatible नहीं है, और compiler settings भी packages के बीच portable नहीं होतीं
ऐसा एक प्रोजेक्ट HN जैसी सेवाओं के पहले पेज पर लगातार जगह दिला सकता है। tokens खर्च करके ऐसा दिखने में प्रभावशाली प्रोजेक्ट बनाना जिसे कोई चाहता नहीं, उसे publish करके reach बढ़ाना, और फिर इसे दोहराना — यही growth strategy है
12 महीने बाद संभव है कि open source projects का 90% ऐसे vibe-coded नतीजे हों जो सिर्फ दिलचस्प दिखते हों, असली users न हों। अब पूरे compiler भी आसानी से जनरेट किए जा सकते हैं, लेकिन असली बात long-term maintenance और community है; सिर्फ आकर्षक title से users नहीं टिकते
अगर Vercel गंभीर है, तो उसे वास्तविक लागत और जोखिम उठाकर इसे अपने experimental runtime के रूप में अपनाना चाहिए
यह एक बेहद शानदार problem space है। मैंने AI से runtime code optimize करने वाला ऐसा ही काम Zod पर लागू किया था: zod-compiler
यह build time पर Zod schema को साधारण boolean operations की chain में compile कर देता है, बिना code बदले 2–74x तेज़ बनाता है, और plugin Zod calls को compiled parsing से replace कर देता है। ज़्यादातर optimization Claude ने 100 से अधिक iterations में लिखे थे
scriptc की तरह यहाँ भी correctness को लेकर व्यक्तिपरक निर्णय लेने की ज़रूरत नहीं, क्योंकि नतीजों की तुलना वास्तविक Zod से की जा सकती है। इसे reference implementation और benchmarks वाले compilers, serialization tools, formatters, query planners आदि पर भी लागू किया जा सकता है
Claude से scriptc और Node benchmark चलाया। सबसे अनुकूल byte array परिणाम में भी scriptc, विशेष optimization के बाद Node 24 से लगभग 7.5x धीमा था
लेकिन executable startup 12x तेज़ था (1.5ms बनाम 18.6ms), memory 72x कम इस्तेमाल हुई (2.5MiB बनाम 181MiB), और यह runtime dependency के बिना एक single 370KB executable बनाता है
यह अच्छी बात है कि इन्होंने छोटे और तेज़ native executables की ज़रूरत को माना, लेकिन Java ने दशकों में जो रास्ता तय किया है उसे देखते हुए इसकी व्यवहारिकता पर संदेह है। 1990s का GCJ तकनीकी रूप से ठीक था, लेकिन ecosystem support नहीं था
बाद में GraalVM Native ने समस्या को अधिक समग्र रूप से संभाला और प्रमुख libraries व frameworks ने compatibility सुनिश्चित करने की कोशिश की, फिर भी आज भी साधारण मौजूदा applications को पूरी तरह native चलाना बहुत कठिन है। scriptc जैसी कोशिशें स्वागतयोग्य हैं, लेकिन व्यवहारिक उपयोग तक पहुँचने का रास्ता लंबा और कठिन लगता है
Excelsior के गायब होने का एक कारण शायद यह है कि GraalVM और OpenJ9 मुफ़्त में उपलब्ध हैं। PTC और Aicas अभी भी कम ध्यान पाने वाले embedded और real-time customers की वजह से ठीक चल रहे हैं
अगर विकास जारी रहा, तो इसमें .NET AOT स्तर की बड़ी उपलब्धि बनने की क्षमता है। अभी इसे public हुए बस कुछ दिन हुए हैं, इसलिए फ़िलहाल हल्के परीक्षण जैसी स्थिति है, लेकिन अगर इसे छोड़ा नहीं गया और विकास जारी रहा, तो ecosystem के लिए यह काफी मददगार हो सकता है
AI से बना कोड भी इंसानों के लिखे कोड की तरह गुणवत्ता के बहुत अलग-अलग स्तरों पर हो सकता है। अगर software महत्वपूर्ण है, तो उसे हाथ से लिखे कोड जैसी ही कसौटी पर generate करना और पूरे code का review करना चाहिए; अगर ऐसा किया जाए तो यह बेहतरीन तरीका है। जिन projects में review कमज़ोर हो, उनमें quality और developer accountability भी कम होने की आशंका रहती है, इसलिए उन्हें अपनाना और कठिन हो जाता है
ऑनलाइन चर्चा अक्सर “सब कुछ AI से generated” और “AI का बिल्कुल इस्तेमाल नहीं” जैसे दो ध्रुवों में चली जाती है, लेकिन व्यवहार में सोच-समझकर निर्णय को तेज़ करने वाला मध्य मार्ग ही उचित है। वरना कम गुणवत्ता या छोड़ दिए जाने के जोखिम के कारण ऐसे software को इस्तेमाल करने में हिचक होगी