1 पॉइंट द्वारा GN⁺ 2 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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 और any type 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 की वास्तविक es2025 library लागू करता है
    • अगर project में @types/node है तो उसके साथ type checking करता है
    • बिना lowering वाला reachable code सटीक diagnostics देता है और compilation रोक देता है
  • scriptc coverage analysed statements की संख्या, statically compile होने वाला ratio, blocking factors और error codes दिखाता है
    • example में 4,481 statements में से 4,451, यानी 99%, statically compile होते हैं
  • execution method को साफ तौर पर तीन stages में बांटा गया है
    1. Static compilation: default mode, जिसमें JavaScript engine के बिना native code में बदलता है
    2. Dynamic execution: --dynamic देने पर करीब 620KB का quickjs-ng शामिल करता है और npm packages के JavaScript तथा any type code को चलाता है
      • static code में आने वाली सभी values को runtime पर validate करता है
      • declared type और value अलग होने पर memory corrupt किए बिना पकड़े जा सकने वाला TypeError throw करता है
    3. 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, और typed catch support करने वाली Error hierarchy भी देता है

Node और Web API

  • Node API में fs, path, process, child_process, os, crypto, url/URL, zlib, timers और signal handlers support हैं
    • fs synchronous और Promise APIs देता है
    • child_process pipe 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 का उपयोग नहीं करता

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 किए जाते हैं
  • पूरा 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 के अनुरूप f64 semantics बनाए रखते हुए ज्यादातर 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 शामिल होते हैं

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 c source line information के साथ readable output बनाता है
  • packages/runtime reference-counted values और cycle collector, stackful fibers, kqueue event loop, server stack, JavaScript-compatible numeric output implement करता है
    • feature-wise linking method से केवल वास्तव में उपयोग होने वाली features binary में शामिल होती हैं
  • packages/cli scriptc build, scriptc run, scriptc coverage commands देता है

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 test differential test set और diagnostic snapshots चलाता है
    • SCRIPTC_SAN=1 pnpm test वही tests ASan और reference count audit के तहत चलाता है
    • pnpm scriptc build x.ts --emit-ir generated C और x.ir.json को preserve करता है
  • सभी features differential tests के साथ जोड़ी जाती हैं, और merge होने से पहले normal tests व memory safety tests दोनों pass होने चाहिए

1 टिप्पणियां

 
GN⁺ 2 시간 전
Hacker News टिप्पणियाँ
  • लगता है Vercel लगभग हर महीने एक चर्चित प्रोजेक्ट निकालता है ताकि अपनी विश्वसनीयता और मौजूदगी बनाए रख सके। किसी गंभीर कंपनी या प्रोजेक्ट के scriptc इस्तेमाल करने की संभावना कम लगती है
    योगदानकर्ताओं का सम्मान है, लेकिन कोड में Claude से जनरेट होने की झलक बहुत साफ दिखती है, और Claude को contributor के रूप में न दिखाया जाना इसे और संदिग्ध बनाता है

    • वाकई बहुत विशाल स्तर का योगदान ;-) commit
    • इसी तरह के vibe coding नेता ने Vercel की मई में बड़े स्तर पर घोषित “agents के लिए programming language” zerolang को भी लीड किया था। 1,200 commits के बाद जून के मध्य के आसपास विकास रुक गया
      project / संबंधित HN पोस्ट
    • Simon Willison ने शायद सिर्फ README में बदलाव किए, और प्रोजेक्ट में उनका वास्तविक योगदान नहीं दिखता
    • योगदान इतिहास देखें तो लगता है लगभग 99% vibe coding एक ही व्यक्ति ने की है, और compiler से जुड़ी पृष्ठभूमि भी नहीं दिखती
    • कई SaaS प्रोडक्ट Vercel के साथ काम करते हैं, और dev tools में Next.js और React को शीर्ष SDK की तरह माना जाता है
  • 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 नहीं होतीं

    • लगता है scriptc इसे इस तरह संभालता है कि ज़रूरत पड़ने पर ऐसी dependencies चलाने के लिए वैकल्पिक रूप से 620KB quickjs-ng engine को bundle में शामिल करता है
    • dependency-heavy कोड की बजाय, मैं इसे ऐसे स्पष्ट उपयोग वाले command-line tools में इस्तेमाल करना चाहूँगा जिन्हें बड़े TypeScript प्रोजेक्ट्स के साथ code share करना हो
    • यह untyped libraries distribute करने के पक्ष में एक तर्क हो सकता है, लेकिन यह समझना कठिन है कि वह कारण types की उपयोगिता से अधिक महत्वपूर्ण कैसे हो जाता है
  • ऐसा एक प्रोजेक्ट 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 जैसी कोशिशें स्वागतयोग्य हैं, लेकिन व्यवहारिक उपयोग तक पहुँचने का रास्ता लंबा और कठिन लगता है

    • मुझे पता है Graal टीम ने भी ऐसा ही meta-interpreter approach आज़माया था। native execution जिन चीज़ों को संभाल नहीं पाती, जैसे dynamic bytecode loading या reflection, उन्हें Espresso Java implementation से interpret करने की कोशिश की गई थी
    • GCJ हमेशा prototype के क़रीब ही रहा। गंभीर users शायद Excelsior JET, BEA JRockit जैसे AOT tools वाले commercial JDK खरीदते
      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 को इस्तेमाल करने में हिचक होगी