GoodScript compiler - TypeScript to native code
npm install goodscriptComplete TypeScript-to-C++/TypeScript compiler with binary compilation support, comprehensive runtime library, and TypeScript type definitions.
``bashInstall globally
npm install -g goodscript
Requirements:
- Node.js v18+ (for all features)
- Zig (optional, only needed for
--gsCompile to create native binaries)$3
GoodScript takes a modular approach similar to Rust's architecture:
- Core compiler (Node.js only): Validates GoodScript restrictions and generates C++ code
- Binary compilation (requires Zig): Compiles generated C++ to native executables
This design offers several advantages:
- ā” Lightweight installation: Package stays small (<5MB) without bundling Zig (~50-80MB)
- šÆ Progressive enhancement: Start with validation/C++ generation, add Zig when you need binaries
- š§ Flexibility: Use your preferred Zig version or system package manager
- š¦ Separation of concerns: Compiler and build toolchain are independent
Without Zig installed:
`bash
gsc --gsValidateOnly src/main-gs.ts # ā
Works - validates GoodScript restrictions
gsc --gsTarget cpp src/main-gs.ts # ā
Works - generates C++ code
`With Zig installed:
`bash
gsc --gsTarget cpp --gsCompile -o myapp src/main-gs.ts # ā
Compiles to native binary
`Installing Zig (when you need binary compilation):
`bash
macOS
brew install zigLinux
Download from https://ziglang.org/download/
Windows
Download from https://ziglang.org/download/
Or use: winget install -e --id Zig.Zig
`For complete CLI documentation, see CLI.md.
Architecture
`
TypeScript Source
ā
[Phase 1: Frontend]
- Parser (TypeScript AST)
- Validator (Good Parts restrictions)
ā
[Phase 2: Analysis]
- Ownership Analyzer (DAG for share)
- Null Checker (use lifetime safety)
- Type Signatures (structural typing)
ā
[Phase 3: IR Lowering]
- TypeScript AST ā GoodScript IR
- SSA-based, typed, ownership-aware
ā
[Phase 4: Optimizer]
- Constant folding
- Dead code elimination
- Multi-pass optimization
ā
[Phase 5: Code Generation]
- C++ Codegen (ownership/gc mode)
ā
[Phase 6: Binary Compilation]
- Zig compiler integration
- Cross-platform native binaries
ā
Native Binary / TypeScript
`Key Improvements over v0.11
1. Proper IR: SSA-based, explicitly typed intermediate representation
2. Single source of truth: All type and ownership info in IR
3. Clean separation: Frontend, IR, optimizer, backend are independent
4. Multiple backends: C++ (ownership/GC modes), TypeScript
5. Better optimizations: IR enables dataflow analysis
6. Binary compilation: End-to-end native binary generation via Zig
Directory Structure
`
src/
āāā ir/ # IR types, builder, visitor, signatures
āāā frontend/ # TS parsing, validation, lowering
āāā analysis/ # Ownership & null checking
āāā backend/ # Code generation (C++, TS)
ā āāā cpp/ # C++ codegen + Zig compiler
āāā optimizer/ # IR optimization passes
āāā compiler.ts # Main entry point
āāā types.ts # Shared types
`Development
`bash
Install dependencies
pnpm installBuild
pnpm buildTest (394 tests passing)
pnpm testWatch mode
pnpm dev
`Status
ā
Phases 1-8 Complete (394 tests passing, 19 skipped)
- ā
Phase 1: Frontend (validator, parser)
- ā
Phase 2: Analysis (ownership, null checking, type signatures)
- ā
Phase 3: IR Lowering (AST ā IR, statement types, async context)
- ā
Phase 4: Optimizer (constant folding, DCE)
- ā
Phase 5: Code Generation (C++, string concat, async/await)
- ā
Phase 6: Binary Compilation (Zig + cppcoro integration)
- ā
Phase 7: Runtime Library (FileSystem, async/await, Math, JSON, String, Array, Map)
- ā
Phase 8: Union Types (T | null, T | undefined)
- ā
CLI Tool (
gsc command - drop-in replacement for tsc)Working Features:
- Core Language: Functions, lambdas, classes, arrays, maps, strings
- Async/await: Full Promise support with cppcoro
- Exception handling: try-catch-finally
- File I/O: FileSystem sync/async API
- HTTP/HTTPS: HTTP client with automatic OpenSSL detection and BearSSL fallback
- Math operations: All Math.* methods
- String operations: Concatenation, slice, includes, split, trim, etc.
- Type safety: Compile-time constant detection, union types
- Automatic conversions: Number-to-string in concatenation
- Built-in globals: console, Math, JSON, Promise, FileSystem, HTTP, HTTPAsync, String, Array, Map
HTTPS Support:
- macOS/Linux: Uses system OpenSSL (zero overhead, automatic)
- Windows/minimal systems: Falls back to vendored BearSSL (~300KB)
- Auto-detection: Compiler detects OpenSSL at build time
- 100% coverage: HTTPS works on all platforms
Working Examples (11 out of 12):
- ā
03-functions: Lambda captures, higher-order functions
- ā
04-arrays: Array operations, methods, iteration
- ā
05-maps: Map construction, get/set/delete, forEach
- ā
06-strings: String methods and operations
- ā
07-math: All Math methods + string concatenation
- ā
08-exceptions: try-catch-finally error handling
- ā
09-async-await: async/await with Promise handling
- ā
10-file-io: FileSystem sync/async file operations
- ā
11-http-client: HTTP/HTTPS GET requests with async support
In Progress:
- ā³ Object literals/structs (for classes example)
- Watch mode for
gsc
- IDE integration (LSP server)File Extensions
GoodScript uses
-gs.ts and -gs.tsx suffixes (not .gs):
- math-gs.ts - GoodScript TypeScript file
- component-gs.tsx - GoodScript TSX/React fileWhy this convention?
- ā
All TypeScript tooling works out of the box (VSCode, tsc, ESLint, Prettier)
- ā
No special IDE plugins needed
- ā
Files are valid TypeScript - just import type aliases
- ā
Clear intent:
-gs signals "follows GoodScript restrictions"
- ā
Gradual adoption: mix .ts and -gs.ts files in same projectExample:
`typescript
// math-gs.ts
import type { own, share, use, integer, integer53 } from 'goodscript';export function fibonacci(n: integer): integer {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
export class Buffer {
data: own;
constructor(size: integer) {
this.data = new ArrayBuffer(size);
}
}
`Then compile to native binary:
`bash
gsc --target cpp -o myapp src/math-gs.ts
./myapp
`$3
GoodScript provides TypeScript type definitions for ownership types and integers.
Option 1: Explicit imports (recommended)
`typescript
import type { own, share, use, integer, integer53 } from 'goodscript';
`Option 2: Global types (include in tsconfig.json)
`json
{
"include": [
"src/*/",
"node_modules/goodscript/types/globals.d.ts"
]
}
`types/README.md for complete type documentation.TypeScript/JavaScript Output
Note: For TypeScript/JavaScript output, just use
tsc directly on your -gs.ts or -gs.tsx files.
GoodScript files are valid TypeScript - the ownership and integer types are simple aliases:
`typescript
// In JS/TS mode (semantics only enforced in C++ mode)
type own = T;
type share = T;
type use = T;
type integer = number; // int32_t in C++, number in JS
type integer53 = number; // int64_t in C++, safe integer in JS
`Integer semantics are only guaranteed in C++ compilation mode.
tsconfig.json Integration
The compiler reads
tsconfig.json to auto-configure C++ compilation:Debug Mode (
"sourceMap": true):
`json
{
"compilerOptions": {
"sourceMap": true // Enables -g flag, -O0 (no optimization), #line directives
}
}
`
- Generates debug symbols in C++ binary (-g)
- Disables optimizations for easier debugging (-O0)
- Embeds #line directives mapping C++ lines ā -gs.ts source lines
- Stack traces show original TypeScript file and line numbersProduction Mode (no
sourceMap or false):
`json
{
"compilerOptions": {
"sourceMap": false // Enables -O3 (full optimization), no #line directives
}
}
`
- Maximum optimizations (-O3)
- Smaller binary size
- Faster execution
- No source location trackingOverride with CLI flags:
`bash
gsc --debug src/main-gs.ts # Force debug mode with source maps
gsc --optimize 3 src/main-gs.ts # Force optimization level
`How Source Maps Work:
When
sourceMap: true, the compiler embeds C preprocessor #line directives:`cpp
// Generated C++ code
#line 1 "/path/to/math-gs.ts"
double add(double a, double b) {
#line 2 "/path/to/math-gs.ts"
auto result = (a + b);
return result;
}
`This makes debuggers (gdb, lldb) and crash reports show:
`
math-gs.ts:2 instead of math.cpp:47
``Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.