Skip to content

anzellai/sky

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

745 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sky

sky-lang.org · Examples · Docs

Experimental · v0.10 — Sky is under active development. APIs and internals may change between minor versions.

Sky is an experimental fullstack programming language that combines Go's pragmatism with Elm's elegance. You write functional, strongly-typed code with a batteries-included stdlib — Sky.Live for server-driven UI, Std.Db for SQL persistence, Std.Auth for sessions, Sky.Core.Error for unified error handling — import any Go package with auto-generated FFI bindings (no hand-written glue), and ship a single portable binary. Sky's explicit types, exhaustive pattern matching, and strict Task effect boundary make it AI-friendly by design: both humans and LLMs tend to write code that compiles the first time.

module Main exposing (main)

import Std.Log exposing (println)

main =
    println "Hello from Sky!"

What Sky brings together

  • Go — fast compilation, single static binary, access to the full Go ecosystem (databases, HTTP servers, cloud SDKs).
  • Elm — Hindley-Milner type inference, algebraic data types, exhaustive pattern matching, pure functions, The Elm Architecture.
  • Phoenix LiveView — server-driven UI with DOM diffing, SSE subscriptions, session management. No client-side framework required.

Sky compiles to Go. One binary runs your API, DB access, and server-rendered interactive UI — one codebase, one language, one deployment artifact.

Why Sky exists

I've worked professionally with Go, Elm, TypeScript, Python, Dart, Java, and others for years. Each has strengths, but none gave me everything I wanted: simplicity, strong guarantees, functional programming, fullstack capability, and portability — all in one language.

The pain point that kept coming back: startups and scale-ups building React/TypeScript frontends talking to a separate backend, creating friction at every boundary — different type systems, duplicated models, complex build pipelines, and the constant uncertainty of "does this actually work?" that comes with the JS ecosystem. Maintenance becomes the real cost, not the initial build.

I always wanted to combine Go's tooling (fast builds, single binary, real concurrency, massive ecosystem) with Elm's developer experience (if it compiles, it works; refactoring is fearless; the architecture scales). Then, inspired by Phoenix LiveView, I saw how a server-driven UI could eliminate the frontend/backend split entirely — one language, one model, one deployment.

The first attempt compiled Sky to JavaScript with the React ecosystem as the runtime. It worked, but Sky would have inherited all the problems I was trying to escape — npm dependency chaos, bundle configuration, and the fundamental uncertainty of a dynamically-typed runtime. So I started over with Go as the compilation target: Elm's syntax and type system on the frontend, Go's ecosystem and binary output on the backend, with auto-generated FFI bindings that let you import any Go package and use it with full type safety.

Building a programming language is typically a years-long effort. What made Sky possible in weeks was AI-assisted development — first with Gemini CLI, then settling on Claude Code, which fits my workflow and let me iterate on the compiler architecture rapidly. I designed the language semantics, the pipeline, the FFI strategy, and the Live architecture; AI tooling helped me execute at a pace that would have been impossible alone.

Sky is named for having no limits. It's experimental, opinionated, and built for one developer's ideal workflow — but if it resonates with yours, I'd love to hear about it.

Current implementation

The compiler is written in Haskell (GHC 9.4+). It handles parsing, Hindley-Milner type inference, canonicalisation, formatting, LSP, and Go codegen. Previous implementations (TypeScript bootstrap, Go, self-hosted Sky) are preserved under legacy-ts-compiler/ and legacy-sky-compiler/ for historical reference.

See docs/compiler/journey.md for the full compiler history.

What's in the box

Sky is batteries-included. Three killer modules cover the common needs of any modern web app — no plugins, no separate services, no npm install:

Sky.Live — server-driven UI

The Elm Architecture, but the server is authoritative. No client framework, no JSON API contracts, no bundler. Browser runs ~2 KB of JS for DOM diffing + SSE — that's it.

type Msg = Increment | Decrement

update msg model =
    case msg of
        Increment -> ( { model | count = model.count + 1 }, Cmd.none )
        Decrement -> ( { model | count = model.count - 1 }, Cmd.none )

view model =
    div []
        [ button [ onClick Increment ] [ text "+" ]
        , span [] [ text (String.fromInt model.count) ]
        , button [ onClick Decrement ] [ text "-" ]
        ]

Full TEA loop with init / update / view / subscriptions, async work via Cmd.perform, persistent sessions across deploys (memory / SQLite / Redis / Postgres / Firestore). See Sky.Live overview.

Std.Auth — authentication, in the box

bcrypt password hashing, HMAC-SHA256 JWTs, plus optional DB-backed register / login that creates the users table for you. No passport, no bcryptjs, no auth microservice.

Auth.register db "alice@example.com" password
    |> Task.andThenResult
        (\uid ->
            Auth.signToken secret (Dict.fromList [ ( "sub", String.fromInt uid ) ]) 86400
        )

Production-grade defaults: minimum-32-byte secret enforcement, constant-time password compare, configurable bcrypt cost, rate-limit-friendly. See Sky.Auth overview.

Std.Db — one API for SQLite + Postgres

Parameter-safe queries, transactions, conventional CRUD helpers (insertRow / getById / updateById / deleteById), row decoders. Switch driver in sky.toml; never touch it again in your code.

Db.withTransaction db (\tx ->
    Db.exec tx "UPDATE accounts SET balance = balance - ? WHERE id = ?" [ amount, fromId ]
        |> Task.andThen (\_ ->
            Db.exec tx "UPDATE accounts SET balance = balance + ? WHERE id = ?" [ amount, toId ]
        )
)

See Std.Db overview.

Plus the rest of the stdlib

Crypto, JSON, HTTP client/server, file I/O, time, regex, encoding (base64 / hex / URL), structured logging, UUIDs, async tasks, parallel execution. See Standard library reference for the full surface.

Quick start

# macOS / Linux — single-binary install
curl -fsSL https://raw.githubusercontent.com/anzellai/sky/main/install.sh | sh

# custom installation path
curl -fsSL https://raw.githubusercontent.com/anzellai/sky/main/install.sh | sh -s -- --dir ~/.local/bin

# Or with Docker
docker run --rm -v $(pwd):/app -w /app anzel/sky sky --help

Prerequisite: Go 1.21+ installed — Sky compiles to Go and uses Go's toolchain to produce your binary.

Create and run a project:

sky init hello
cd hello
sky run src/Main.sky

Sky ships as a single sky executable. The FFI-introspection helper (sky-ffi-inspect) is embedded and self-provisions into $XDG_CACHE_HOME/sky/tools/ on first sky add — no second binary to install or keep on $PATH.

See docs/getting-started.md for a walkthrough.

Building from source

Contributors: see docs/development.md for the full build + test story, including the pinned GHC/Go toolchain, the ./scripts/build.sh entrypoint, and reproducible builds via Nix:

# quickest path on any system with nix
nix develop            # GHC 9.4.8 + Go + every system dep, sandboxed
./scripts/build.sh --clean

Documentation

Area Link
Getting started docs/getting-started.md
Language syntax docs/language/syntax.md
Types docs/language/types.md
Pattern matching docs/language/pattern-matching.md
Modules docs/language/modules.md
Go FFI interop docs/ffi/go-interop.md
FFI design docs/ffi/ffi-design.md
Error system docs/errors/error-system.md
Standard library reference docs/stdlib.md
Sky.Auth overview docs/skyauth/overview.md
Std.Db overview docs/skydb/overview.md
Sky.Live overview docs/skylive/overview.md
Sky.Live architecture docs/skylive/architecture.md
Compiler architecture docs/compiler/architecture.md
Compiler pipeline docs/compiler/pipeline.md
Compiler journey (TS→Go→Sky→Haskell) docs/compiler/journey.md
Version history docs/compiler/versions.md
CLI reference docs/tooling/cli.md
Testing (sky test) docs/tooling/testing.md
LSP docs/tooling/lsp.md
Development & contributing docs/development.md

Status

  • v0.10 — stdlib consolidation + soundness gaps closed (2026-04-25, BREAKING). Single canonical module per concern (drop Args / Env / Sha256 / Hex / Slog; rename OsSystem; shrink Process to run); type errors in dep modules and FFI / kernel return shapes now abort the build instead of silently degrading to any-typing. See docs/V0.10.0_PR_SUMMARY.md for the full migration guide.
  • v0.9 — adversarial audit remediation complete (2026-04-16). All 23 P0–P3 items across soundness, security, cleanup, and tooling landed with regression tests. See docs/AUDIT_REMEDIATION.md for the per-item tracker and docs/compiler/v1-soundness-audit.md for the soundness audit findings.
  • Core principle — "if it compiles, it works" — aspirational. Now holds for every path in cabal test, the example sweep, and the runtime Go test matrix. v1.0 requires production usage and bug-fixes to earn the label. Residual future-work (fully-typed emitted Go, Sky-test harness) tracked in docs/PRODUCTION_READINESS.md as P4.
  • 18 example projects under examples/ covering CLI, HTTP servers, full-stack Sky.Live apps, databases (SQLite, PostgreSQL, Firestore), payments (Stripe), auth, and GUI (Fyne).
  • sky verify is the canonical runtime check: builds and runs every example, hits HTTP endpoints, honours per-example verify.json scenarios (status code + body substring assertions). CI runs sky verify across the full example set.
  • Test matrix: 47-example hspec suite + ~20 runtime Go tests + 67-file test-files/*.sky self-test loop + format idempotency across every example source file.
  • FFI generation: Stripe SDK (8,896 types), Firestore, Fyne, and others auto-bind.

Contributing

Issues and PRs welcome. See the docs tree for architecture context before opening a structural PR.

Licence

MIT.