If it compiles, it works.

Sky Lang is a typed functional language designed for AI-era development. HM types, no nulls, no exceptions — compiled to a single Go binary. One codebase targets web, terminal, CLI, and desktop.

curl -fsSL https://raw.githubusercontent.com/anzellai/sky/main/install.sh | sh
Main.sky
module Main exposing (main)

import Std.App as App
import Std.Ui as Ui exposing (Element)
import Std.Ui.Font as Font

type alias Model = { count : Int }
type Msg = Increment | Decrement | Reset

init _ = ({ count = 0 }, Cmd.none)

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

view : Model -> Element Msg
view model =
    Ui.column [ Ui.spacing 16, Ui.padding 24 ]
        [ Ui.el [ Font.size 48, Font.bold ]
            (Ui.text (String.fromInt model.count))
        , Ui.row [ Ui.spacing 8 ]
            [ Ui.button [] { onPress = Just Decrement, label = Ui.text "-" }
            , Ui.button [] { onPress = Just Reset,     label = Ui.text "reset" }
            , Ui.button [] { onPress = Just Increment, label = Ui.text "+" }
            ]
        ]

app =
    App.app
        { init = init, update = update
        , view = view, subscriptions = \_ -> Sub.none
        }
        |> App.withNotFound ()

-- web is the default target; sky build --target terminal:tui,
-- terminal:cli, desktop or web:app retargets this same app.
main = App.run app

One model. Five runtimes.

One App.app — the same init / update / view — runs on five runtimes. Pick with a build-time --target, no view-code changes:

Sky.Live — server-driven web UI with DOM diffing over SSE, persistent sessions, async Cmd.perform

Sky.Spa — the same loop compiled to wasm on the client — web, desktop, iOS, Android from one source (experimental)

Sky.Tui — same Element tree rendered to ANSI cells in a terminal (logical-pixel canvas, mouse + scroll)

Sky.Cli — line-oriented stdin event loop for non-interactive shells

Sky.Webview — native desktop window on the system webview, sharing Sky.Live's renderer (macOS today)

Same view, five runtimes

Std.Ui is a typed, no-CSS layout DSL. Pass one build-time --target to retarget — web, terminal, CLI, desktop — with zero changes to view, update, or model. And with Sky.Spa (--target web:app) the same loop compiles to wasm on the client, shipping to web, desktop, iOS and Android from one source.

Sky.Live
web
import Std.App as App

app =
    App.app
        { init = init, update = update
        , view = view, subscriptions = subs
        }
        |> App.withNotFound ()

main = App.run app

$ sky build            -- web (default)

HTTP + SSE wire. Persistent sessions across deploys (memory / SQLite / Redis / Postgres / Firestore). Async Cmd.perform goroutines. Input-authority protocol preserves typed input across re-renders.

Sky.Spa
wasm
-- the very same `app` — no new entry point,
-- no Std.Spa import. Just retarget:

main = App.run app

$ sky build --target web:app
--   desktop:mac | mobile:ios | mobile:android

The same TEA loop compiled to GOOS=js GOARCH=wasm — runs on the client. `sky run` auto-splits one project into a wasm frontend + a stateless backend + a shared codec (no hand-written boundary). Ships to web, desktop, iOS and Android; Std.Native exposes device APIs (clipboard, camera, geolocation) and Native.bridge extends them. Experimental.

Sky.Tui
terminal
-- the very same `app`, retargeted —
-- the Element tree renders to ANSI cells:

main = App.run app

$ sky build --target terminal:tui

Render Element trees to ANSI cells. Logical-pixel canvas (1280×720 default), mouse left-press + scroll wheel, wide chars + emoji via grapheme-cluster width. Diff renderer; no flicker.

Sky.Cli
stdin
-- the very same `app`, retargeted —
-- a line-oriented loop for non-TTY shells:

main = App.run app

$ sky build --target terminal:cli

Line-oriented event loop for non-TTY shells. Same TEA shape; view returns a string each turn. Echo-suppressed password reads via Cli.readPassword for auth flows.

Sky.Webview
desktop
-- the very same `app`, retargeted —
-- Sky.Live's renderer in a native window:

main = App.run app

$ sky build --target desktop

Native desktop window on the system webview, reusing Sky.Live's renderer and VNode diff so the same Std.Ui tree renders identically. macOS is smoke-validated today; Windows and Linux build but are untested. Requires cgo.

Sky.Spa — one source, every platform

The 64-spa-native example — clipboard, files, camera and geolocation via Std.Native, plus Native.bridge to add your own — built once and running on web, iOS and Android. Experimental.

Sky.Spa on Web + Desktop
Web + Desktop
Sky.Spa on iOS
iOS
Sky.Spa on Android
Android
Why Sky Lang
If it compiles, it works

Hindley-Milner type inference, exhaustive pattern matching, no null, no exceptions. Undefined names caught at compile time with line:col positions.

Single binary

Compiles to a native Go binary. Your fullstack app — API, database, server-rendered UI — ships as one file. The compiler itself is also a single binary (Rust).

Multi-backend UI

Std.Ui is a typed no-CSS layout DSL. The same view renders to a server-driven web app (Sky.Live), a client-side wasm app (Sky.Spa), a terminal UI (Sky.Tui), a stdin loop (Sky.Cli), or a desktop window (Sky.Webview). One model, five runtimes.

Go ecosystem

Import any Go package with auto-generated type-safe bindings. Stripe, Firebase, SQLite, PostgreSQL — all with panic recovery and nil safety.

Type-directed lowering

The compiler propagates HM types into lambda bodies, record fields, list elements, and call args — so callback fields keep their typed callee param (no func(any) any fallback). Parametric records compile to Go generics.

Batteries included

Built-in database (Std.Db), authentication (Std.Auth), JSON encode/decode with pipeline, HTTP server, formatter, LSP with hover + diagnostics.

See it in action
STD.UI FORMS
-- Typed onSubmit decodes formData
-- straight into the Msg's record arg
Ui.form [ Ui.onSubmit DoSignIn ]
    [ Ui.input [ Ui.name "username" ]
    , Ui.input [ Ui.name "password"
        , Ui.htmlAttribute "type" "password" ]
    , Ui.input [ Ui.htmlAttribute "type" "submit" ]
    ]
PATTERN MATCHING
describe shape =
    case shape of
        Circle r ->
            "circle r=" ++ String.fromFloat r
        Rectangle w h ->
            "rect" 
DATABASE
import Std.Db as Db

-- reads sky.toml [database]
todos =
    Db.connect ()
        |> Task.andThen (\db ->
            Db.queryDecode db
                "SELECT * FROM todos" [] todoDecoder)
ASYNC COMMANDS
-- Run tasks in background goroutines
update msg model =
    case msg of
        FetchData ->
            ( model, Cmd.perform
                (Http.get "/api") GotData )
CONCURRENCY
-- Parallel HTTP requests (goroutines)
fetch =
    Task.parallel
        [ Http.get url1
        , Http.get url2
        ]
        |> Task.andThen handleAll
GO INTEROP
import Github.Com.Stripe.StripeGo.V84 as Stripe

-- whole-program DCE keeps only the
-- symbols you call (76k available)
customer email =
    Stripe.newCustomerParams ()
        |> Result.andThen
            (\p -> Stripe.customerParamsSetEmail email p)
55+
Examples
1400+
Automated tests
5
UI backends
Rust
Compiler (single binary)
Built with Sky Lang

Standalone tools, libraries, and full applications.

SkyShop
Sky.Live

E-commerce app with Stripe payments, Firebase auth, Firestore, i18n, Tailwind CSS. Full Sky.Live TEA architecture with async commands.

examples/13-skyshop ->
SkyChess
Sky.Live

Chess game with negamax AI, SQLite persistence, and SSE real-time updates. Full move validation, castling, en passant, promotion.

examples/16-skychess ->
sky-env
CLI

Encrypted environment variable manager. AES-256-CBC SQLite, portable across machines, six commands. Single 8MB binary.

github.com/anzellai/sky-env ->
sky-tailwind
Library

Tailwind CSS utility classes for Sky.Live apps. Type-safe, composable, zero-runtime — class names checked at compile time.

github.com/anzellai/sky-tailwind ->
SkyVote
Sky.Live

Roadmap voting app — Sky.Live, Std.Auth (bcrypt + sessions), Std.Db (SQLite), email verification, key rotation.

examples/12-skyvote ->
SkyMon
Sky.Live

Service monitoring dashboard with metrics, alerts, and incident timeline. Real-time updates via SSE subscriptions.

examples/17-skymon ->
SkyForum
Std.Ui

Reddit/HN-style forum on the typed no-CSS layout DSL. Per-user vote tracking, threaded comments, password-manager-friendly forms.

examples/19-skyforum ->
Get Started in 30 Seconds

Install Sky. Bootstrap your first project. Ship a single binary.

curl -fsSL https://raw.githubusercontent.com/anzellai/sky/main/install.sh | sh
sky init my-app
cd my-app
sky run
SKY
LANG
Apache 2.0 License