คอมไพเลอร์ TypeScript เนทีฟ ที่ สร้างด้วย Rust

Perry คอมไพล์ TypeScript ที่คุณเขียนอยู่แล้วให้เป็นโค้ดเครื่อง — แบบเดียวกับที่ toolchain ของ Rust หรือ Go คอมไพล์ภาษาของมัน ไม่มี JavaScript ที่ทรานสไพล์มา ไม่มี virtual machine ไม่มีรันไทม์บน ระบบปลายทาง

ไม่ใช่ทรานสไพเลอร์ ไม่ใช่รันไทม์

เครื่องมือ TypeScript ส่วนใหญ่แบ่งเป็นสองตระกูล ทรานสไพเลอร์ — tsc, SWC, esbuild — ตรวจสอบและตัด type ออก แล้วสร้าง JavaScript ให้ engine รันในภายหลัง รันไทม์ — Node.js, Bun, Deno — คือ engine เหล่านั้น: มันจะ parse, interpret และคอมไพล์ JavaScript แบบ JIT ทุกครั้งที่โปรแกรมของคุณ เริ่มทำงาน

คอมไพเลอร์เนทีฟคือตระกูลที่สาม และสำหรับ TypeScript มันแทบจะว่างเปล่า มาตลอด Perry ปฏิบัติต่อ type annotation ไม่ใช่ในฐานะเอกสารที่ต้อง ถูกตัดทิ้ง แต่เป็นอินพุตที่ขับเคลื่อนการสร้างโค้ด ผลลัพธ์ของ perry compile main.ts คือ ไฟล์ปฏิบัติการแบบ standalone ที่มีโค้ดเครื่องอยู่ในนั้น — โดยทั่วไป มีขนาด 2–5 MB เริ่มทำงานในเวลาประมาณหนึ่งมิลลิวินาที.

มันทำงานอย่างไร

จากซอร์สโค้ด TypeScript เป็นไฟล์ปฏิบัติการเนทีฟในไม่กี่วินาที

TypeScriptไฟล์ .ts
SWC
Parserแยกวิเคราะห์เร็ว
HIR
แปลงMonomorphization
LLVM
สร้างโค้ดโค้ดเครื่อง
ไฟล์ปฏิบัติการไบนารี 2-5 MB

อยากรู้ว่าคอมไพเลอร์ทำงานภายในอย่างไร? โครงสร้างภายในคอมไพเลอร์

เจาะลึก: TypeScript บน LLVM — monomorphization, NaN-boxing และเหตุผลที่ Perry ทิ้ง Cranelift

ไปป์ไลน์ ทีละขั้นตอน

  1. Parse (SWC) ไฟล์ ซอร์สถูก parse ด้วย SWC ตัว parser TypeScript แบบเนทีฟที่เขียนด้วย Rust ทำให้แม้แต่โปรเจกต์ขนาดใหญ่ก็ parse เสร็จในหลักมิลลิวินาที การสร้างโค้ดโมดูล, transform pass และการสแกนสัญลักษณ์รันแบบขนาน ข้ามทุกแกน CPU
  2. การ resolve type คอมไพเลอร์ resolve type ที่ประกาศไว้และอนุมานส่วนที่เหลือ ทำให้ ทุก expression มี concrete type ก่อนที่การสร้างโค้ดจะเริ่มต้น
  3. Typed HIR และ monomorphization AST ถูก lower ลงสู่ typed high-level IR ฟังก์ชันและคลาส generic ถูกทำ monomorphization — แต่ละ instantiation อย่าง Stack<number> ถูก คอมไพล์แยกกันด้วย concrete type ของมัน ทำให้ generic ไม่มีต้นทุน ตอนรันไทม์เลย เมื่อรู้ type แล้ว การเรียก method จะกลายเป็น static dispatch และ field ของ object จะกลายเป็นการโหลดแบบ fixed-offset โดยตรง
  4. Codegen (LLVM) HIR ถูก lower ลงสู่ LLVM IR และรันผ่าน pipeline การปรับแต่งของ LLVM — inlining, การปรับแต่ง loop, vectorization — แล้วจึง emit เป็น โค้ดเครื่องสำหรับเป้าหมายนั้น
  5. Link เอาต์พุตคือ ไฟล์ปฏิบัติการแพลตฟอร์มปกติ: Mach-O บน macOS, ELF บน Linux, PE บน Windows — รวมถึงเป้าหมายมือถือ, watch, TV และ WebAssembly

ฝั่ง LLVM ของเรื่องนี้ — เหตุผลที่เลือก LLVM แทน Cranelift, วิธีที่ NaN-boxing แทนค่า dynamic, สิ่งที่ optimizer ทำกับ typed IR — มีการ เจาะลึกของตัวเอง: TypeScript บน LLVM. รายละเอียดการ implement อย่าง NaN-boxing, static dispatch และ zero-cost abstraction ถูกอธิบายไว้ใน โครงสร้างภายในคอมไพเลอร์.

แล้วโค้ดแบบ dynamic กับ npm ล่ะ?

TypeScript ก็ยังคงเป็น JavaScript อยู่ข้างใต้ และคอมไพเลอร์ TypeScript เนทีฟก็ต้องซื่อสัตย์กับเรื่องนั้น ความสอดคล้องของ Perry กับชุดทดสอบ test262 อย่างเป็นทางการถูกวัดผลและเผยแพร่ — ณ v0.5.1146 semantics ของ String อยู่ที่ 79% และ Array อยู่ที่ 72% ซึ่งทั้งคู่ เพิ่มขึ้นทุก release แพ็กเกจ npm ที่เป็น TypeScript/JavaScript ล้วน คอมไพล์แบบเนทีฟได้ผ่าน perry.compilePackages: axios, zod v4, express, fastify และ hono คอมไพล์และรันได้แล้วใน วันนี้ โค้ดที่ต้องการ semantics ของ engine เต็มรูปแบบสามารถเลือก ใช้ V8 fallback แบบฝังตัวด้วย --enable-js-runtime

เรื่องราวแบบเต็มอยู่ใน npm package จริงคอมไพล์ได้แล้ว: axios, zod, express — กับการกวาด conformance.

Perry เกี่ยวข้องกับความพยายาม “native TypeScript” อื่น ๆ อย่างไร

Perry ไม่ใช่โปรเจกต์เดียวที่มองเห็นโอกาสในการคอมไพล์จาก type annotation ของ TypeScript — แต่แนวทางนั้นแตกต่างกันอย่างชัดเจน AssemblyScript คอมไพล์ภาษาที่เข้มงวดคล้าย TypeScript ไปเป็น WebAssembly เท่านั้น: มันจงใจไม่เข้ากันได้กับ JavaScript และไม่ ผลิตไฟล์ปฏิบัติการของ OS หรือ UI เนทีฟ Static Hermes ของ Meta คอมไพล์ JavaScript subset ที่มี type แบบ ahead-of-time ภายใน Hermes engine โดยมุ่งเป้าหลักไปที่ React Native — ณ กลางปี 2026 มันยังคงเป็นโครงการวิจัยที่ต้อง build จาก source เอง และ Hermes V1 engine ที่ส่งมอบจริงใน React Native ก็ไม่มีฟีเจอร์แบบ static รวมอยู่ด้วย (เปรียบเทียบแบบเต็ม)

การเดิมพันของ Perry แตกต่างกันในทั้งสองแกน: TypeScript มาตรฐานเป็น ภาษาอินพุต และไฟล์ปฏิบัติการแพลตฟอร์มธรรมดา — CLI, server และ GUI — เป็นเอาต์พุต ที่ติดตั้งได้วันนี้ผ่าน Homebrew, APT, winget หรือ npm

คอมไพเลอร์เดียว สิบเป้าหมาย

เพราะการสร้างโค้ดผ่าน LLVM โค้ดเบสเดียวจึงคอมไพล์เป็น macOS, iOS, iPadOS, Android, Linux, Windows, watchOS, tvOS, WebAssembly และ Web/JS ธรรมดา — รวมถึงการครอสคอมไพล์ไบนารี Windows, macOS และ iOS จากเครื่อง Linux แอป GUI ใช้ perry/ui ซึ่งเป็น API แบบ declarative เหนือวิดเจ็ตแพลตฟอร์มจริง (AppKit, UIKit, GTK4, Win32, Android ผ่าน JNI) — ไม่มี webview เข้ามาเกี่ยวข้องเลย

เทียบกับแนวทางอื่นแล้วเป็นอย่างไร: Perry เทียบกับ Bun, Deno, Electron, Tauri, React Native และ Static Hermes.

ลองใช้คอมไพเลอร์

ติดตั้ง Perry แล้วคอมไพล์ไบนารีเนทีฟตัวแรกของคุณได้ในเวลาไม่ถึง นาที