sky-lang.org · Docs · Examples
Status: v0.17.x release candidate. Public APIs are stable for the v1.0 line; minor versions ship features additively. Internals can still change between minor versions. v0.17.0 closes the typed-emit soundness floor under the reframed "rock solid + ~100% sound with documented surface for remaining rt.Coerce" goal — see docs/v0.17/release-plan.md.
Sky is a fullstack functional language that compiles to typed Go.
You write Elm-style syntax — explicit types, exhaustive pattern matching,
no runtime exceptions — and ship a single static binary with a
batteries-included stdlib, observability built in, and any Go package
just an import away.
module Main exposing (main)
import Std.Log exposing (println)
main =
println "Hello from Sky!"
sky init hello && cd hello && sky run src/Main.sky
Task Error a; every fallible value returns Result Error a;
sky check invokes go build on the emitted Go so any shape
mismatch surfaces at type-check time. There is no runtime null,
no uncaught exception, no silent numeric coercion.init / update / view /
subscriptions source compiles to a server-rendered web app
(Sky.Live), a terminal UI (Sky.Tui), or a native desktop window
(Sky.Webview).Std.Db,
Std.Auth, Std.Ui, Std.Cache, Std.Email, …) and
documented with sky doc --serve.sky add github.com/some/package —
the compiler introspects the Go package and generates strict,
typed Sky bindings. No hand-written FFI glue. Stripe SDK
(~76k FFI symbols) compiles and tree-shakes to a 4k-line
main.go.CLAUDE.md and sky init's starter CLAUDE.md give any
AI assistant the load-bearing context to scaffold production
apps directly.scp, with Docker, or as a CLI
you brew install.A counter web app — type-checked, server-driven, no JavaScript.
module Main exposing (main)
import Std.Cmd as Cmd
import Std.Live exposing (app, route)
import Std.Sub as Sub
import Std.Ui as Ui
import Std.Ui.Font as Font
type Msg
= Increment
| Decrement
type alias Model = { count : Int }
init : a -> ( Model, Cmd Msg )
init _ = ( { count = 0 }, Cmd.none )
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Increment -> ( { model | count = model.count + 1 }, Cmd.none )
Decrement -> ( { model | count = model.count - 1 }, Cmd.none )
view : Model -> Ui.Element Msg
view model =
Ui.layout []
(Ui.row [ Ui.spacing 16, Ui.padding 24 ]
[ Ui.button [] { onPress = Just Decrement, label = Ui.text "−" }
, Ui.el [ Font.size 24 ] (Ui.text (String.fromInt model.count))
, Ui.button [] { onPress = Just Increment, label = Ui.text "+" }
])
main =
app
{ init = init
, update = update
, view = view
, subscriptions = \_ -> Sub.none
, routes = [ route "/" () ]
, notFound = ()
}
sky run src/Main.sky # http://localhost:8000
Add Std.Tui.app cfg to ship the same view to a terminal
canvas, or Std.Webview.app cfg for a native desktop window.
# macOS / Linux — single-binary install
curl -fsSL https://sky-lang.org/install | bash
# or build from source (Haskell GHC 9.4+ required to build the compiler)
git clone https://github.com/anzellai/sky
cd sky && cabal install --installdir=$HOME/.local/bin exe:sky
The sky binary embeds the runtime, stdlib, and Sky Console.
End users only need sky on PATH and Go 1.21+ available for
codegen.
Match the application to the right surface — every shape uses the
same TEA-style init / update / view / subscriptions.
| What you're building | Surface | Entry point | Default deployment |
|---|---|---|---|
| Web app (server-driven, real-time) | Sky.Live | Std.Live.app cfg |
Cloud Run / VM |
| HTTP / JSON API (no UI) | Sky.Http.Server | Server.listen 8000 [...] |
Cloud Run / VM |
| Terminal UI (TUI) | Sky.Tui | Std.Tui.app cfg |
brew install / CLI |
| CLI tool (no UI loop) | Sky.Cli | main = Task.run ... |
brew install |
| Native desktop app | Sky.Webview | Std.Webview.app cfg |
.app / .exe |
Every backend shares Std.Ui for layout, Std.Auth for sessions,
Std.Db for persistence, Std.Log / Std.Trace for
observability, and Sky.Core.* for pure primitives.
A short tour. Full reference at sky doc --serve or
docs/stdlib.md.
| Module | What it gives you |
|---|---|
Std.Ui |
Typed no-CSS layout DSL (row/column/el/button/input + Background/Border/Font/Region subs). Renders to inline-styled HTML, ANSI cells, or native Webview from the same source. |
Std.Live |
Sky.Live runtime — TEA app + SSE patches + session stores (memory / sqlite / redis / postgres / firestore) + routing + cookies + auth gates. |
Sky.Http.Server |
HTTP server with typed routes, middleware (CORS / logging / rate-limit / basic-auth), streaming responses, WebSocket upgrade. |
Std.Auth |
bcrypt password hashing, HS256 / RS256 JWT, register / login / roles. Typed secrets — never fmt.Sprintf("%v", token). |
Std.Db |
SQLite + PostgreSQL via one interface. Connection pool, prepared statements, versioned migrations, Db.RowDecoder, withTransaction. |
Std.Money + Std.Decimal |
Arbitrary-precision Decimal + currency-typed Money (50+ ISO 4217 codes + crypto) with allocate for fair splits and conversion rates. |
Std.Cache |
LRU + TTL in-memory cache, parametric on key + value, monotone stats. |
Std.Email |
Resend / SES / SendGrid / SMTP under one typed EmailProvider. SKY_EMAIL_DRY_RUN=1 for tests. |
Std.Compression / Std.Csv / Std.Config |
gzip / zstd; RFC 4180 CSV; TOML / YAML / JSON decoders that mirror Sky.Core.Json.Decode. |
Sky.Core.WebSocket |
Client + server bidirectional sockets. |
Sky.Core.Crypto |
SHA-256 / 512, HMAC, RSA sign/verify, AES-GCM, ChaCha20, scrypt password derivation, AEAD constants. |
Std.Webview |
Native desktop window (macOS in v0.1; Linux / Windows in v0.2). |
Every Sky.Live and Sky.Http.Server app auto-mounts:
/_sky/console — Std.Ui dashboard with overview, logs,
metrics, traces, errors (production-gated via
SKY_CONSOLE_AUTH)./_sky/metrics — Prometheus scrape endpoint
(sky_live_requests_total{route,status}, latency histograms,
drop counters)./_sky/healthz / /_sky/readyz — liveness + readiness probes./_sky/buildinfo — commit, build timestamp, Sky version.Run sky console serve to stand up a central hub that
multiple Sky apps push telemetry to via the HubExporter
(OTLP/HTTP). See docs/v0.16.x-console/HUB.md
for the multi-service dashboard, tenant isolation, and the
3-layer auth defense-in-depth model.
OTEL_EXPORTER_OTLP_ENDPOINT is honoured for the standard
OpenTelemetry collector — point at Honeycomb, Grafana Tempo,
Datadog, etc.
# sky.toml
name = "myapp"
version = "1.0.0"
entry = "src/Main.sky"
[live]
port = 8000
store = "sqlite" # memory / sqlite / redis / postgres / firestore
storePath = "sessions.db"
ttl = "30m"
[database]
driver = "sqlite" # sqlite / postgres
url = "DATABASE_URL"
[auth]
cookie = "sky_sid"
ttl = "24h"
# tokenSecret read from SKY_AUTH_TOKEN_SECRET (never put secrets in sky.toml)
[log]
format = "json" # plain / json
level = "info"
ENV=production \
SKY_AUTH_TOKEN_SECRET="$(openssl rand -base64 48)" \
SKY_CONSOLE_AUTH=app SKY_CONSOLE_TOKEN="$(openssl rand -base64 48)" \
sky build src/Main.sky && ./sky-out/app
The production gate is ENV (then SKY_ENV fallback). Unset
or dev / development / local → dev mode. Anything else
locks down the dev console, banner, and metrics endpoint.
Deploy with scp + your favourite supervisor, drop the binary
into a Docker FROM scratch image, or run it directly on any
platform with a Go 1.22+ runtime.
Std.Ui.sky.toml — every config key.39 examples ship in examples/. Each builds clean
from a wiped slate (rm -rf sky-out .skycache .skydeps && sky build).
| Range | Category |
|---|---|
| 01-08 | Hello / CLI / Go-FFI / file / system |
| 09-12 | Sky.Cli / Sky.Tui counters & TODOs |
| 13 | Stripe-SDK-scale FFI benchmark (76k symbols) |
| 14-25 | Sky.Live + Sky.Http.Server apps |
| 26 | examples/26-ui-showcase — every Std.Ui primitive |
| 29-31 | Sky.Webview + WebGL spike |
| 32-33 | SSE relay + WebSocket echo |
| 34-38 | Multi-tier + composite-test apps |
| 39 | Two Sky.Live apps → one hub (v0.16.6) |
Issues and PRs welcome at
github.com/anzellai/sky. The
compiler architecture write-up
and pipeline doc are the right
starting points for compiler work. Run cabal test (cap with
timeout 3600) before any PR; scripts/example-sweep.sh
validates every example builds.
Apache 2.0 — © 2025–2026 Anzel Lai. Includes patent grant + trademark clause. Prior-art attribution for derivative files (parts of the type-inference core adapted from elm/compiler under BSD-3-Clause) lives in NOTICE.md. Contributions accepted under the same Apache 2.0 terms — see CONTRIBUTING.md.
Sky was previously distributed under the MIT licence (releases up to and including v0.10.0). Those releases remain available under their original MIT terms; v0.10.1 onwards ships under Apache 2.0.