Skip to content

sergey-scherbina/scalascript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5,797 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ScalaScript

A language where Markdown is syntax, not decoration.ssc files are executable documents combining YAML front-matter, Markdown prose, and Scala 3 code blocks.

.ssc files support two code-block languages:

Annotation Language Backends
```scalascript ScalaScript dialect — effects, handlers, content helpers, TCO interpreter · JS transpiler · JVM · Rust (native binary; up to R.5 web toolkit) · WebAssembly
```ssc Alias for scalascript interpreter · JS transpiler · JVM · Rust
```scala Standard Scala 3 — no ScalaScript extensions interpreter · Scala.js (JS) · JVM · Rust (passthrough)
```rust Standard Rust — passthrough verbatim into the emitted Cargo crate Rust
---
name: hello
version: 1.0.0
---

# Hello World

```scalascript
def greet(name: String): String = s"Hello, $name!"
println(greet("World"))
```
Hello, World!

After installing, every .ssc file is a first-class executable:

$ ssc hello.ssc
Hello, World!

# The shebang line (#!/usr/bin/env ssc) lets you run files directly:
$ chmod +x hello.ssc && ./hello.ssc
Hello, World!

# Watch mode — re-runs on every save:
$ ssc watch hello.ssc

Quick Start

Requirements: scala-cli · Node.js (for JS backend) · sbt (optional, for library use)

git clone https://github.com/sergey-scherbina/scalascript
cd scalascript

# Standalone install, once releases are published:
cs install ssc --channel https://releases.scalascript.io/coursier.json

# Contributor checkout only: builds and stages local bin/ launchers.
./install.sh --dev

# Pipe sops-decrypted secrets into a script (${sops:key} references in databases:)
sops -d secrets.enc.yaml | ssc myapp.ssc

# Interpreter (tree-walking, no compilation step)
bin/ssc examples/hello.ssc

# Watch mode — re-run on every file change
bin/ssc watch examples/hello.ssc

# Interactive REPL
bin/ssc repl

# Transpile to JavaScript and run via Node.js
bin/jssc examples/hello.ssc

# Compile to JVM bytecode and run via Scala 3 / scala-cli
bin/sscc examples/hello.ssc

# Compile to a native binary via Rust + Cargo (requires `cargo` on PATH;
# see docs/rust-backend.md for the capability surface).
bin/ssc build-rust examples/hello.ssc && ./hello
bin/ssc run-rust   examples/hello.ssc

# Run on Apache Spark (Spark 4.0.0 / Scala 3.7.1, local[*] by default)
bin/ssc-spark examples/spark-encoder-demo.ssc

# Run all examples
./examples/run-all.sc

# Start HTTP server for the examples browser
bin/http.ssc

Documentation

Full categorized index of all docs: docs/README.md.

Getting started

Project Summary One-page overview — what ScalaScript is, the five backends, and the headline capabilities
User Guide Installation, CLI commands, language basics, HTTP, effects, actors, Apache Spark, WebAssembly, frontend frameworks, cluster, x402 — practical day-to-day reference
Tutorial 1 — Todo API Build a todo API step by step — data model → REST → auth → WebSocket → TLS → MCP
Tutorial 2 — Spark ETL End-to-end Spark pipeline — Dataset[T]@SqlFn UDF → @TempView → Delta Lake
Tutorial 3 — Frontend Toolkit demo Compile + emit + serve a toolkit SPA through React / Vue / Solid / Custom + SSR via ssc serve
Tutorial 4 — Full-stack .ssc SQLite + REST API + reactive runtime/std/ui frontend in one .ssc file — databases:, sql blocks, serve(lower(tree, theme), port)

Language reference

Language Specification Formal grammar, type system, semantics, all language constructs
Direct Syntax Do-notation over any monad — direct[M] { x = expr }, .! postfix bind, effect-row unions
Coroutines & Generators Coroutine primitive underlying one-shot effects and generators
Algebraic Effects spec Typed effect rows — ! operator, multi effect, Rémy-style unification, typed stdlib, Reader[R], NonDet
Error Handling Checked errors via throws[A, E], attemptCatch, HasStackTrace
Metaprogramming / v2 macros inline, derives, compiletime.*; partially implemented restricted quoted macros for ssc link, interpreter ssc run, and the JVM + JS backends, incl. Expr.asValue match compile-time constant folding, with targeted unsupported-body diagnostics; interpreter Mirror.Of[T] and user derived(m: Mirror) typeclasses
Markdown Content Introspection Markdown-to-frontend content layer: Markdown/YAML/GFM tables/fenced language blocks lower to std/ui through contentToolkitNode() or explicit contentToolkitBlock(id) / contentToolkitSection(id) selectors, including declarative yaml @ui=toolkit controls, Markdown-authored tables as TableNode, contentData(id) lookup, explicit contentComponent(...) registries for component=<name> / data=<id> metadata, explicit contentBind(value, bindings) resolution for Markdown ${name} placeholders, and cross-backend std/content lookup helpers contentCurrentSection(), contentSection(id), contentBlock(id), contentMetadata(path), contentPlainText(value), contentToMarkdown(value), plus direct imported module content namespaces via contentModule(namespace) for interpreter, JS, and JVM targets; .scir and .sscc preserve the current-module DocumentContent snapshot when present; low-level contentView(contentDocument()) remains available
Markdown Content Linked Namespaces Focused contract for reusing Markdown-authored sections, blocks, data, and content: metadata from direct .ssc imports through contentModules() and namespace-scoped lookup helpers
Markdown Content Native Client Parity Same Markdown-authored toolkit controls render through Swing, JavaFX, and SwiftUI native frontends by normalizing shared std/ui/lower View.Element output into native text fields, checkboxes/toggles, buttons, and signal state
DSL Authoring Parser combinators, multi-pass pipelines, runtime/std/parsing/*

Platform & runtime

Architecture Compiler pipeline, module structure, backend SPI
Target Backends Interpreter · JS transpiler · JVM · Rust (Cargo crate → native binary) — capabilities and tradeoffs
Rust backend guide ssc emit-rust / build-rust / run-rust — compile .ssc to a native binary via Cargo, with mixed ```rust fence blocks
Actors & Distributed Spawn, supervise, cluster over WebSocket
Distributed Wire Protocol Planned: opt-in JSON/MsgPack/CBOR internal wire layer for actors, Dataset/DStream, typed route clients/RPC, object sync, security, compression, and compatibility
Distributed Runtime Planned: canonical local/remote/distributed runtime model for streams, actors, typed async calls, cluster lifecycle, cluster operations, code deployment, and worker bundles
Dataset / MapReduce Dataset[T] — local, parallel, distributed
Apache Spark backend Spark 4 + Scala 3.7.1: Dataset[T], sql blocks, @SqlFn UDFs, Structured Streaming, Delta Lake, Hive catalog, MLlib — see §13 of the User Guide
Frontend Framework SPI React / Vue / Solid / custom frontend backends; design doc has historical planning context
Frontend Toolkit High-level declarative widgets: Forms, Routing, Widgets v2, Table
Cluster Management Bully election, phi-accrual failure detector, federation, Raft, ZooKeeper client
x402 micropayments HTTP 402 protocol, Ethereum + Cardano flows, MCP × x402 paid tools
Bank Rails v1.54 SEPA CT/DD, ACH, Pix, FedNow — BankRailsProvider SPI, mandate lifecycle, async settlement
International Bank Rails v1.55 SWIFT MT103 + pacs.008, SEPA Instant, UK FPS/BACS/CHAPS, India UPI, Japan Zengin, Singapore PayNow
Browser SQL Cross-backend sql fenced blocks (JS / Node / Wasm / JVM)
Electron SQL Current sqlite: behavior in Electron desktop bundles, including the localStorage-backed renderer fallback
Electron Persistence Bridge Main/preload bridge for durable Electron SQLite under app.getPath("userData")
Secret Resolvers ${env:} · ${file:} · ${sops:} · SecretResolver SPI for Vault / AWS SM / GCP / Doppler / 1Password
MCP Support MCP server tools + resources, MCP client
Rozum / Agent SDK Generic app-owned agent loop over a stateless OpenAI-compatible rozum gateway, with strict tool schemas and in-process tool handlers
Rozum Agent Streaming runAgentStream / collectAgentStream for OpenAI-compatible SSE text/tool-call deltas with ordered AgentEvents
Rozum Agent Endpoint Pool AgentEndpointPool + runAgentPool / streaming pool variants for bounded ordered failover across multiple rozum gateways
Rozum Agent Schema Derivation AgentSchema[A] derives + agentToolFor[A] for typed tool inputs with OpenAI-compatible JSON Schema parameters
Markdown as Syntax How Markdown constructs map to AST nodes
SwiftUI / iOS / macOS Native Swift Package emission; ssc run --target ios / --target macos; ssc package + ssc publish to App Store / TestFlight
GraalVM native binary ssc native binary via GraalVM native-image; no-JVM distribution; ssc-plugin-host.jar bridge
Native plugin guide Compile a plugin to a native binary — fully JVM-free ssc → plugin

Planned / partial

Blockchain SPI Draft / planned, not fully implemented: pluggable chain abstraction below wallet and x402 support
Electron JVM REST Backend Partially implemented: explicit ssc run --frontend electron --backend jvm-rest, ssc run --target desktop-jvm, plain ssc run for frontend: electron full-stack sources, server-only ssc run --mode server --backend jvm, Electron client-only, and web client preview via ssc run --mode client --frontend react --server-url ... with opt-in --open-browser plus --host/--port preview binding; packaging and runtime-level JVM bind-host support remain planned
Full-stack in-process transport Planned, partially implemented: BackendTransport types, `ssc run --transport http
JVM Desktop Frontend Partially implemented: frontend-swing backend, ServiceLoader registration, ssc run-jvm --frontend swing, static Swing toolkit subset emission, local signal action bridge, Swing fetchAction / dataTable / typed route client backend dispatch in the same JVM process, no-socket full-stack examples, and a swing-plugin skeleton for future interpreter intrinsics; JavaFX/Compose adapters remain planned
Typed route clients Planned, partially implemented: apiClients: / api-clients: front-matter endpoint metadata parses into AST and codegen metadata; JVM/Swing generates callable in-process client methods, and JS/browser/Electron bundle codegen emits Promise-returning HTTP clients over fetch using --server-url / __sscBackendBaseUrl; awaitClient(...) gives client-side ScalaScript code a small await bridge; generated clients call a stable typed JSON codec facade sourced from backend/typed-data; JVM/Swing typed clients use JsonCodec[T], and JS/browser/Electron typed clients use generated runtime codec metadata for known case-class/enum shapes
Contract validation Planned, not implemented yet: shared OpenAPI/GraphQL validation model for route/resolver signatures, request/response bodies, typed errors/status codes, profiles, overlays/imports, CLI checks, compatibility diffs, and contract tests
Typer real types roadmap Planned, partially implemented foundation: reduce accidental Any in exported symbols/IR and carry structured type evidence through case classes, enums, generics, routes/remotes, OpenAPI/GraphQL schemas, Dataset/Spark mapping, and plugin metadata
Client/server object store Complete: JS/browser/Electron IndexedDb.store[A] typed local client store, JVM/JDBC ObjectStore, generated JVM REST sync routes, Sync.pull/push/sync[A], durable queued Sync.put/remove[A], explicit Sync.conflicts/resolve[A], generated JVM conflict policies (manual / server-wins / client-wins), and Sync.status / Sync.isOnline / Sync.isSyncing UI helpers
Graph storage Planned, partially implemented: graphs: front matter parses into AST/IR; JVM codegen exposes Graph.* over in-memory, embedded TinkerGraph property, and RDF4J memory RDF stores plus Sparql.select over RDF4J; the interpreter exposes Graph.* over in-memory property/RDF storage. Production adapters such as Neo4j, JanusGraph/TinkerPop providers, and RDF4J-compatible servers remain planned
Typed data mapping Planned, partially implemented: backend/typed-data owns the shared emitted typed JSON facade for generated route clients plus JsonValue / DecodeError / JsonCodec[A], explicit object helpers, JsonFieldSpec rename/default/key/unknown-field helpers, derives JsonCodec for case classes/sealed ADTs, schema annotations for derived JVM/interpreter product codecs, schemas: front-matter metadata for interpreter typed SQL, initial RowValue / RowFieldSpec / RowCodec[A] support for simple case-class rows and explicit JVM column metadata, initial ObjectValue / ObjectFieldSpec[A] / ObjectCodec[A] support for portable IndexedDB/ObjectStore document shapes, VertexValue / EdgeValue / RdfValue plus VertexCodec[A] / EdgeCodec[A] / RdfCodec[A] for graph/RDF mapping, DatasetCodec[A] for local/MapReduce Dataset element serialization and distributed worker partition payloads, DatasetWire JSON/MsgPack/CBOR envelope + chunk helpers for DatasetWirePartition, std/mapreduce runDistributedWire and runDistributedShuffleWire for direct DatasetWirePartition actor/shuffle payloads, DistributedDataset.encode/decode[A] typed boundary helpers, DistributedDataset.run/runShuffle[A, B] actor-effect wrappers, and SparkSchemaCodec[A] for Spark-like schema metadata using the same field annotations; JS/browser/Electron IndexedDb.store[A] typed local object storage, and JVM/JDBC ObjectStore storage through ObjectCodec[A]; SqlRuntime.query/insert/update[A] use RowCodec[A]; interpreter and JVM codegen expose Db.query/insert/update[A] for typed SQL reads and writes; SparkGen typed readers use SparkSchemaCodec[A] metadata when present and alias external column names back to Scala field names before .as[T]; richer cross-store convergence remains planned
Distributed binary wire protocol Planned, partially implemented: opt-in wire: config with JSON fallback plus MsgPack/CBOR profiles for internal ScalaScript distributed actors, Dataset/DStream, typed route clients/RPC, WebSocket subscriptions, object sync, compression, integrity, and future schema evolution. Implemented pieces include shared WireEnvelope, actor binary WS, typed RPC binary HTTP negotiation, and DatasetWire JSON/MsgPack/CBOR partition envelopes with chunking
Distributed runtime Planned, partially implemented: local / remote / distributed placement vocabulary, named operation registry, code identity, stream bridges, typed actor remote spawn, ! Async remote calls, cluster runner UX, token rotation, rolling upgrades, and cluster-aware deployment. Implemented pieces include stream bridge basics, typed actor refs/remote spawn, ClusterCapability, static SeedResolver, interpreter code identity checks, typed cluster: / registry front-matter metadata, interpreter remoteHandlers: lowering with in-process Remote.function plus HTTP JSON fallback routes, explicit Remote.http[A, B](url) calls, path-based Remote.stub(baseUrl) HTTP stubs, and generated RemoteRpc typed HTTP client metadata for path: remote handlers

Dataset/MapReduce binary wire now reaches actor messages directly: wireFormat = "msgpack" | "cbor" sends DatasetWire envelope bytes for partition, shuffle-bucket, and key-result messages, while JSON keeps the object-message fallback.

What Works

All three backends support scalascript blocks. scala blocks (standard Scala 3) are supported by the interpreter and JVM backend; the JS backend compiles them via Scala.js.

Core language

Feature Syntax
Values and variables val x = 42, var n = 0
Functions def f(x: Int): Int = x * 2
Lambdas and closures val double = (x: Int) => x * 2
Higher-order functions xs.map(double), xs.filter(_ > 0)
Default parameters def f(x: Int, step: Int = 1), also on class/enum constructors
Case classes case class Point(x: Double, y: Double)
Enums / sealed traits enum Color { case Red; case Green; case Blue }
Recursive ADTs enum Tree { case Leaf(v: Int); case Branch(l: Tree, r: Tree) }
Pattern matching x match { case Some(n) => n; case None => 0 }
For comprehensions for x <- xs if x > 0 yield x * x
While loops while n > 0 do { ... }
Collections List, Map, Option, Set, Vector, Array, LazyList, Seq, IndexedSeq, Iterable — full method dispatch
Real collection semantics The interpreter models true Scala semantics — Array is mutable with reference identity (a(i) = x), LazyList is lazy (#:: defers; infinite streams work), Vector is a distinct indexed type with O(log₃₂ n) access; constructors Seq/Vector/Array/IndexedSeq/Iterable/LazyList(...) + .toSeq/.toVector/.toArray/.toList/.toLazyList conversions
Tuples val t = (1, "hello"); t._1
Bitwise operators a & b, a | b, a ^ b, a << n, a >> n, a >>> n, ~a on Int
String interpolation s"Hello, $name", md"..." (strips indent)
Math math.sqrt, math.abs, math.pow, math.Pi, …
Extension methods extension (n: Int) def squared: Int = n * n
Typeclasses trait Show[A], given, summon[Show[Int]], context bounds
Higher-kinded types (HKT) trait Functor[F[_]], sealed dispatch, auto-resolution
Standard typeclasses Functor, Applicative, Monad, Foldable, Traversable, Either, Eq, Show, Hash, Order, Semigroup, Monoid, Bifunctor, MonadError, Selective
Recursion factorial, Fibonacci, tree traversal
Tail-call optimisation self-TCO and mutual TCO — no @tailrec required
Case-class .copy p.copy(field = newValue, ...)
List / map literals [1, 2, 3]List(…), ["k" -> v, ...]Map(…), []List() — compact sugar in .ssc code blocks

Optics

Feature Syntax
Lenses Focus[T](_.a.b)Lens with get / set / modify / andThen
Prisms Prism[Sum, Variant]getOption / set / modify / reverseGet
Optionals Focus[T](_.maybe.some.field)Optional for paths through Option fields
Traversals Focus[T](_.items.each.field)Traversal — multi-foci getAll / modify / set

Effects and concurrency

Feature Syntax
Algebraic effects effect E:, handle(body) { case E.op(arg, resume) => ... }, multi-shot
Typed effect rows def foo(): A ! Logger — effect appears in function type; closed row (no !) = total/pure
multi effect Multi-shot effects — continuation can be resumed many times
Reader[R] capability Context-injection effect: Reader.get, runReader(value)(body)
NonDet multi-shot Nondeterministic branching via multi-shot continuations
EffectAnalysis Compile-time error for unhandled effects (not just a warning)
Standard effects — Logger Logger.info(msg), runConsoleLogger, runTestLogger
Standard effects — Random Random.nextInt(n), runSeededRandom(seed)
Standard effects — Clock Clock.now(), Clock.millis(), runSystemClock
Standard effects — State State.get, State.set(v), State.modify(f), runState(init)
Standard effects — Env Env.get(key), runEnv(map)
Standard effects — Http Http.get(url), Http.post(url, body), runHttpClient
Standard effects — Retry Retry.attempt(n)(body), runRetry(policy)
Standard effects — Cache Cache.getOrSet(key)(body), runCache
Standard effects — Tx Tx.begin, Tx.commit, Tx.rollback, runTx
Standard effects — Auth Auth.check(claims), runAuth(verifier)
Direct syntax (do-notation) direct[M] { x = expr; y = expr2 }, .! postfix bind
Effect-row unions direct[Async | Random] { ... }
Built-in Async effect runAsync { Async.delay(ms); Async.parallel(...) }
Real-thread runAsyncParallel genuine JVM concurrency without touching call sites
Built-in Storage effect runStorage { Storage.put(k, v); Storage.get(k) } — JSON file-backed or ephemeral
Coroutines coroutineCreate, coroutineResume, suspend, Step[Y,T] ADT, coroutineCancel
Generators generator[T] { yield(v) }, fromGenerator, streaming interop
Reactive signals Signal(0), s.get / s.set(v), computed { … }, effect { … } with diamond-dedup flush
Free monad Free[F,A], liftF, foldMap, runM — in runtime/std/free.ssc

Actors

Feature Syntax
Local actors spawn, self(), pid ! msg, receive { case ... }, link, exit, supervision
Distributed actors actor cluster over WS, bully leader election, Phi-accrual FD, gossip, membership events
Typed actor refs + named remote spawn ActorRef[M], ref.tell(msg), ref.address, ref.isLocal, registerBehavior, spawnRemote over the current JSON actor WS control channel
Cluster capability + code identity clusterOf, SeedResolver.staticList, codeIdentity, assertCodeIdentity for typed cluster snapshots and deterministic SHA-256 code checks
Remote handler registry remoteHandlers:, @remote(...) def, and simple remote def declarations lower to an interpreter RemoteHandlerRegistry; Remote.function[A, B](name).call(value) uses the in-process path, path: entries expose POST HTTP JSON fallback routes, Remote.http[A, B](url) calls those routes explicitly, remoteStub[Api](baseUrl) / Remote.stub[Api](baseUrl) provide a path-based HTTP JSON fallback stub, and RemoteClientDeriver exposes path: handlers as generated RemoteRpc typed HTTP client metadata for JS/JVM codegen. Generated trait methods, async effect-row lowering, WebSocket/internal-wire transport, and binary WireCodec[A] negotiation are planned

Web and HTTP

Feature Syntax
HTTP server route(method, path)(handler), serve(port), Request/Response
REPL web mode :serve/:stop/:clear/:mount/:load/:reload/:unmount/:routes/:http/:call — mount handlers and test routes interactively; :set errorDetails true|false
HTTP streaming streamResponse, SSE via sse(req)
HTTP middleware CORS, gzip, cache headers, /_health / /_ready, /_openapi.json / /_swagger with typed response schemas for front-matter/generated JVM routes when apiClients: metadata is available; ssc emit-openapi exports the same document as JSON/YAML without starting a server; @openapi(...) adds per-route summary/description/tags/deprecated/security metadata and openApiSecurity(...) declares OpenAPI security schemes
WebSocket server onWebSocket(path), ws.send/recv/close/ping, rate limiting, per-route maxConnections
TLS tls("cert.pem", "key.pem"), serve(443, tls=...), wss://
HTTP client httpGet/httpPost, httpClient { }, httpGetStream for SSE/LLM streaming
WebSocket client wsConnect(url) { ws => }, wss://
REST ergonomics jsonParse/jsonStringify/jsonRead, req.json, JsonValue, validate { }, middleware
Typed handlers CaseClass => CaseClass auto-deser (path/query/body) + auto-ser (JSON 200); Either[Request, Input] for explicit error handling
SQL databases databases: front-matter declares named JDBC connections; ```sql ``` fenced blocks execute DDL/DML; ```transaction ``` fenced blocks run multiple ;-separated statements atomically (JDBC transaction, commit/rollback); Db.query/execute for programmatic access; SQLite, H2, PostgreSQL out of the box
XML markup ```xml ``` fenced blocks parse well-formed XML 1.0 into Value.MarkupV(doc: Markup.Doc); ${expr} interpolation with automatic XML escaping; bound as <section>.xml; zero-dependency PureMarkupCodec parser
XSLT transformation MarkupCodec.default.transform(doc, xslt, params) applies an XSLT 1.0 stylesheet to a Markup.Doc; returns Either[TransformError, Markup.Doc]; parameter substitution via Map[String, String]; JVM / interpreter only (Feature.Xslt); see examples/xslt-transform.ssc
Secret resolution ${env:VAR}, ${file:/run/secrets/pw}, ${sops:key.path} in database URLs/credentials; SecretResolver SPI for Vault, AWS SM, GCP SM, Doppler, 1Password and more
Progressive Web App pwa(name, themeColor, icons, precache) — registers GET /manifest.json + GET /sw.js; cache-first precaching service worker; works in ssc run and ssc run-jvm

Planned, not implemented yet:

Feature Planned shape
Full-stack in-process transport ssc run and ssc run-jvm recognize `--transport http
JVM desktop frontend ssc run-jvm --frontend swing app.ssc launches the JDK-only Swing runtime in the current JVM process; ssc run-jvm --frontend swing --transport in-process is accepted as the monolithic JVM mode foundation; Swing fetchAction can call generated JVM backend routes in-process; ssc run --frontend swing remains the interpreter path and reports that Swing intrinsics are planned; JavaFX/Compose adapters remain planned
Typed route clients apiClients: / api-clients: front matter preserves endpoint method/path/request/response metadata in AST and JVM/JS codegen. JVM/Swing generates callable in-process clients that encode case-class/ADT inputs through JsonCodec[T], dispatch through generated BackendTransport, and decode typed JSON responses through JsonCodec[T]. JS/browser/Electron bundle codegen emits Promise-returning HTTP clients over fetch and passes request/response type names through the shared typed JSON facade; generated JS case-class/enum metadata decodes known response shapes back into generated JS values. Client-side ScalaScript can use awaitClient(Messages.list()), which lowers to JS await and enables the needed async wrapper. emit-spa --server-url, web client mode, and Electron JVM REST dev mode can route those relative calls to a JVM backend. examples/frontend/typed-client-distributed/ demonstrates one source running as backend on one machine and client on another
Client/server object storage JS/browser/Electron code can use IndexedDb.store[A]("store", "dbName", "keyField") for Promise-based typed local object storage, awaited with awaitClient(...); native IndexedDB is used when available, with a lightweight fallback for Node/tests. JVM code can use ObjectStore.put/get/all/delete/changes[A](dbName, store, ...) over the declared JDBC database. JVM codegen emits typed GET /__ssc/sync/{store}/changes and POST /__ssc/sync/{store}/push routes for objectStores: entries with sync: client-server. JS clients call Sync.pull/push[A] or the combined Sync.sync[A]; Sync.put/remove[A] persist local queued mutations for offline-friendly pushes. Conflicts are listed with Sync.conflicts, resolved with Sync.resolve[A], or handled automatically by generated JVM conflict: policies. Sync.status(store, db?) returns { pending, conflicts, lastPulled, lastPushed, isSyncing } for sync-status badges; Sync.isOnline and Sync.isSyncing(store, db?) give per-store and network availability signals
Graph storage backend/graph now provides GraphCapabilities, PropertyGraphBackend, RdfGraphBackend, GraphBackend, GraphRuntime.inMemory(), GraphRuntime.tinkerGraph(), GraphRuntime.rdf4jMemory(), and GraphRuntime.sparqlSelect() for portable JVM property/RDF storage through typed codecs plus RDF4J SPARQL SELECT. graphs: front matter survives AST/IR/.sscc; JVM codegen emits a typed Graph.* facade for declared in-memory, embedded-tinkergraph, and rdf4j-memory graph stores plus Sparql.select for RDF4J-backed stores, and runtime/std/graph-plugin mirrors the portable in-memory facade for ssc run. Production adapters such as Neo4j, JanusGraph/TinkerPop providers, and RDF4J-compatible repositories remain planned
Typed data mapping backend/typed-data now provides the shared emitted typed JSON facade for generated route clients plus explicit JsonValue, DecodeError, JsonCodec[A], JsonFieldSpec, RowValue, RowValueCodec[A], RowFieldSpec[A], RowCodec[A], ObjectValue, ObjectFieldSpec[A], ObjectCodec[A], VertexValue, EdgeValue, RdfValue, VertexCodec[A], EdgeCodec[A], RdfCodec[A], DatasetCodec[A], DatasetWire, and SparkSchemaCodec[A] helpers. derives JsonCodec supports case classes and sealed ADTs; derives RowCodec, derives ObjectCodec, derives VertexCodec, derives EdgeCodec, derives RdfCodec, and derives SparkSchemaCodec support simple case-class rows/documents/graph records/schema records. DatasetCodec[A] derives from JsonCodec[A] and now exposes partition payload helpers for distributed MapReduce worker movement; DatasetWire wraps those payloads in shared JSON/MsgPack/CBOR WireEnvelopes and chunks large partitions. std/mapreduce can move DatasetWirePartition payloads directly through runDistributedWire and runDistributedShuffleWire, with DistributedDataset.encode/decode[A] wrapping the typed boundary and DistributedDataset.run/runShuffle[A, B] wrapping the actor-effect calls for map and shuffle. SparkSchemaCodec[A] uses the same @fieldName, @key, and Option nullability conventions to produce Spark-like schema metadata, and SparkGen typed readers consume that metadata when it is in scope. Graph/RDF codecs add @graphLabel, @graphEdge, @graphFrom, @graphTo, @rdfClass, @rdfId, and @rdf. SqlRuntime.query/insert/update[A] use RowCodec[A], and interpreter/JVM codegen expose Db.query/insert/update[A] for typed SQL reads and writes. Broader cross-store migration helpers remain planned

Dataset/MapReduce typed wire calls can select wireFormat = "msgpack" | "cbor" to send DatasetWire envelope bytes through actor partition, shuffle-bucket, and key-result messages.

Auth and security

Feature Syntax
Sessions + CSRF req.session, withSession(Map(...)), csrfToken() / csrfValid(req)
JWT bearer tokens jwtSign(Map(...)), jwtVerify(token), RS256 and HS256
Password hashing hashPassword/verifyPassword (PBKDF2)
TOTP 2FA totpGenerateSecret, totpVerify(secret, code)
WebAuthn / passkeys webAuthnRegisterChallenge, webAuthnVerify
OAuth2 oauthAuthorizeUrl(...), oauthExchangeCode(...), oauthUserinfo(...), Google + GitHub presets

MCP (Model Context Protocol)

Feature Syntax
MCP server mcpServer { srv => srv.tool(...) }, serveMcp(Transport.stdio/Http/Ws)
MCP client mcpConnect(url) { client => client.callTool(...) }

Data processing

Feature Syntax
Dataset / MapReduce Dataset[T] with map/filter/flatMap/groupBy/reduceByKey/top/countByValue
Execution modes runLocal, runParallel, runDistributed
Apache Spark Same Dataset[T] source → sql fenced blocks · @SqlFn UDFs · Scala 3 native encoder derivation · Structured Streaming · Delta Lake · Hive metastore · MLlib pipelines

DSL authoring and metaprogramming

Feature Syntax
Parser combinators runtime/std/parsing/* — Parser ADT, ~/~>/~<, rep, opt, sep, error recovery, indentation-aware
Multi-pass pipelines runtime/std/dsl/*Pass[A,B], andThen/parallel/recover, Visitor, cata, ana
Metaprogramming inline def/val/if/match, compiletime.constValue/summonInline/error. Restricted quoted macros run on the interpreter, JVM, and JS backends (MacroCodegen.expand pre-codegen pass), including Expr.asValue match compile-time constant folding and cross-module macro expansion, with targeted unsupported-body diagnostics; ssc check warns on interpreter-only macros. Mirror.Of[T] conformance + custom derived(m: Mirror) typeclasses (JVM + JS)
Derives derives Eq/Show/Hash/Order/Foldable/Traversable/Functor; structural stdlib + custom derives cross-backend (JVM + JS)
Checked errors throws[A, E] = Either[E, A], throwsRaw[A, E] = A | E, attemptCatch, HasStackTrace

Module system and tooling

Feature Syntax
Package system package: org.example.ui in frontmatter, namespaced exports, collision-safe imports
Module imports [name](./lib.ssc) Markdown links bring definitions into scope; one pure Markdown paragraph may contain multiple import links
URL imports [X](https://...) URL fetch, cached at ~/.cache/ssc/
Dependency imports [X](dep:org/lib:1.2) legacy source resolver, [X](dep:org:name:version) Coursier resolver, [X](jitpack:com.github.owner:repo:tag), [X](github:owner/repo@tag[#asset]), sha256: pins, ssc.lock
Package registry ssc search / ssc info / ssc add against https://sergey-scherbina.github.io/scalascript/packages.yaml by default, overrideable with --registry or registry.url
Project scaffolding ssc new my-app, `--template lib
Plugin system .sscpkg format, essential bundled plugins auto-loaded from bin/lib/compiler/plugins, advanced bundled plugins available locally under bin/lib/compiler/plugin-available and enabled with --plugin / ssc plugin install, ~/.scalascript/registry.yaml
sbt integration ScalascriptInteropPlugin, sscGenerateFacade, sscCompile, sscLink, sscTest, sscRun, sscRepl, sscWatch, sscBspSetup, sscBackends cross-build (emit JVM/JS/Rust/Wasm artifacts from one source), Phase 5 dependency resolution, src/main/scalascript/ source convention
Config system config: front-matter, ```yaml config "name" fenced blocks, config.files: [...], typed derives Config, JsConfigEmitter, ScalaConfigEmitter — see specs/config-system.md
Separate compilation ssc emit-interface, ssc emit-ir, ssc compile-jvm/compile-js, ssc link, ssc build --incremental, .scim/.scir/.scjvm/.scjs; .scir and .sscc preserve Markdown content snapshots when present

Browser and UI

Feature Syntax
Browser SPA target ssc emit-spa file.ssc — same route() source runs as a single-page app
Web Components ssc emit-wc, customElements.define
SSR + hydration wc(tag, component, args*) declarative shadow DOM
Component library runtime/std/ui/* — Button, Input, Select, Modal, Card, Spinner, Alert, DatePicker, Combobox, and more
Frontend Framework SPI One .ssc source compiled to React, Vue 3, Solid, or a custom runtime via frontend-{react,vue,solid,custom} backends
Reactive primitives Signal[T], ShowSignal (conditional render), ToggleSignal, ForSignal[T] (list render) — uniform semantics across all 4 frontend backends
runtime/std/ui script toolkit Declarative widget DSL from a .ssc file — vstack/hstack, textField, checkbox, signalButton, actionButton, badge, spinner, card, modal, table, router + hashRouter, dataTable, fetchAction, and Markdown-driven contentToolkitNode() / contentToolkitBlock(id) / contentToolkitSection(id) / contentComponent(...) / contentData(id) / contentBind(value, bindings) / contentToolkitOptionsWithBindings(data) / contentSection(id) / contentBlock(id) / contentMetadata(path) / contentPlainText(value) / contentToMarkdown(value) / contentView(contentDocument()) with yaml @ui=toolkit controls (including {type: button, action: <id>} and {type: table, source: <id>} — with an optional inline columns: list of typed column specs (`kind: text
Native Markdown toolkit controls Markdown/YAML @ui=toolkit controls lower through the same std/ui View pipeline for Swing, JavaFX, and SwiftUI native clients; see examples/frontend/markdown-native-controls/
NFC NDEF (std.nfc) nfcCapabilities, nfcPermissionStatus, readNdef, writeNdef, textRecord, uriRecord, mimeRecord; interpreter reports deterministic unsupported status, native Android/iOS/Web adapters are capability-gated by Feature.NfcNdef
Rozum / agent loop (std.agent) runAgent, runAgentPool, runAgentStream, runAgentStreamPool, collectAgentStream, collectAgentStreamPool, AgentEndpoint, AgentEndpointPool, AgentSchema, AgentTool, agentToolFor, RunOptions, ToolResult, AgentEvent — OpenAI-compatible tool-call loop for stateless rozum gateways; apps own prompts, typed or explicit tool schemas, validation, streaming callbacks, failover policy, and side effects
Fetch primitives fetchUrlSignal — live GET binding (v2: real fetch + headers); seedSignal — editable draft seeded from another Signal[String] until user input makes it dirty, supported by the browser runtime and frontend emitters including JVM desktop; fetchAction/fetchActionClear — POST/PUT/DELETE on button click with optional headers: Signal[String] for bearer tokens; dataTableView over any TableDataSourcestaticRowsSource (in-memory rows, no fetch), signalRowsSource (reactive rows signal), or a bare fetch signal (Remote) — on interpreter, JVM, and JS browser backends alike; rowPostAction bodies via fieldPayload / wholeRowPayload / fieldsPayload; incSignal — manual refresh; emptyHeaders sentinel
Themes defaultTheme (light) · darkTheme · custom Theme(ColorPalette, SpacingScale, TypographyScale, RadiusScale)
Frontend Toolkit (v1.18 B+ / B++ / C) High-level declarative UI via Tk facade (sbt API) — vstack/hstack, card, textField, form with validators, router, modal/drawer/tabs, table. Backend-agnostic: lowers to React / Vue / Solid / Custom or to static HTML via Ssr.renderToHtml.
WebAssembly target ssc emit-wasm file.sscscalascript blocks lowered to Wasm; cross-backend sql fenced blocks supported. Algebraic effects compile and run on Wasm (arithmetic, collection HOFs, multi-shot resume, cross-module) via a pure-Scala effect runtime with no preamble bloat. @wasm extern FFI + cross-module inlining + macro expansion are wired
Native Rust SSR server serve(view, port) on the Rust backend (ssc build-rust) emits a self-contained tokio + hyper server with server-side rendering, a reactive signal store, computed-signal live recompute, Server-Sent Events push (/__ssc/events), and a direct WebSocket signal endpoint on port + 1 — no JS framework, no Node runtime. See docs/rust-backend.md
i18n translations: frontmatter, t(key), setLocale(code)
Env access getenv(key) / getenv(key, default)
Content helpers doc(...) / render(...) structured output
HTML / CSS interpolators html"..." (auto-escaping) and css"..." with ${expr}

Blockchain, wallets, and micropayments

Feature Syntax
x402 micropayments HTTP 402 → typed payment challenge / settlement via Payment[T], x402Server { … }, x402Client(...) — Ethereum + Cardano payment families
Blockchain SPI (draft / planned, not fully implemented) BlockchainBackend trait — EVM (mainnet, L2s), Bitcoin, Solana, Cardano via pluggable backends. See specs/blockchain-spi.md
Wallet Connect (WC v2) Relay-transport cryptographic primitives — pairing, session, JSON-RPC, X25519 / HKDF / ChaCha20-Poly1305
Browser MetaMask wallet x402ClientJs helper — Wallets.metaMask(Network.Base) over window.ethereum + EIP-712 signing
Ledger hardware wallets JVM HID and browser WebHID vaults — Ledger HID APDU framing, Ethereum app signing, Cardano CIP-8 helpers
MPC wallet vaults wallet-vault-mpc remote signing core plus wallet-vault-mpc-fireblocks provider adapter — Fireblocks JWT auth, RAW transaction signing, polling
Solana Wallet Standard solana-wallet-std translator — Wallet Standard ↔ unified Wallet SPI
ERC-4337 account abstraction EntryPoint v0.7 PackedUserOperation — bundlerless and bundler-driven flows
Cardano CIP-8 wallet Ed25519 key-derived enterprise bech32 address, CIP-8 message signing, Scalus-source escrow validator with on-chain canonical CIP-8 proof verification, exact receiver-output check, claim/refund validity-window checks, Scalus script-context validator tests, stable EscrowScript.address(network) script address helper, Scalus-mode structured claim-message signing, server-side Scalus proof verification, bloxbean claim Tx draft with script data hash + relayer witness, typed Blockfrost protocol params, protocol min-fee draft balancing, static/bloxbean/Blockfrost/Ogmios Plutus ex-units, and env-gated Preprod integration coverage
Cross-backend crypto JVM: native Ed25519, secp256k1, BLS12-381; JS: @noble/curves Scala.js backend — uniform CryptoBackend SPI
std.crypto hashing sha256 (hex) / sha256Base64 (base64 digest) / sha256OfBase64 (digest over decoded bytes), byteLengthUtf8, hmacSha256, base64Encode/base64Decode — digests + encoding (e.g. KSeF invoiceHash/encryptedInvoiceHash)
std.crypto encryption AES-256-GCM (aesGenKey/aesGcmEncrypt/aesGcmDecrypt + byte variants), AES-256-CBC + PKCS#7 with external IV (aesGenIv/aesCbcEncrypt/aesCbcDecrypt), RSA-OAEP (rsaOaepEncrypt), X.509 SPKI extraction (x509PublicKey) — hybrid encryption for KSeF 2.0 etc. (JVM only)
std.crypto signature verify verifyEd25519/verifyEd25519Url, verifyRsaSha256 (PKCS1/PSS) — total verifiers (malformed → false, never throw) for trustless federation (JVM only)
std.crypto signing ed25519Sign/ed25519SignUrl, rsaSignSha256 (PKCS1/PSS) — private-key signers that round-trip with the verifiers; for chain-checkpoint evidence a third party can verify without a shared secret (JVM only)
std.pdf generation htmlToPdfBase64(html) — render a confined HTML/CSS subset (table layout, A4, typography/borders/bg) to base64 PDF bytes via OpenHTMLtoPDF; drop-in for an HTML→PDF relay (JVM only)
std.pdf extraction pdfToMarkdown(pdfBase64) / pdfPageCount(pdfBase64) — read a PDF's text layer (Apache PDFBox), pages split by ---; honest plain-text (no layout inference), non-PDF throws (JVM only)
std.mime assembly buildMimeMessage(from,to,subject,htmlBody,attachments) — hand-rolled RFC 5322 multipart/mixed (base64 HTML body + base64 attachments, RFC 2047 subject), ready for SMTP DATA (JVM only)
MCP × x402 mcpServer { srv => srv.tool(...).requirePayment(...) } — paid LLM tools

Cluster, leader election, federation

Feature Syntax
Bully leader election cluster.leader() returns the current bully-elected leader; reactive on membership change
Phi-accrual failure detector Heartbeat-driven liveness; tunable phi threshold per cluster
Self-health cluster.self.health — driver-side health metric stream
Federation Multi-cluster gossip + cross-cluster routing — see specs/cluster-federation.md
Raft consensus Strongly-consistent state machine — see specs/cluster-raft.md
ZooKeeper client zkClient { … } for legacy coordinator integration — see specs/client-zookeeper.md
Operational HTTP routes /_ssc-cluster/status, /_ssc-cluster/members, /_ssc-cluster/leader — built-in across all 4 frontend / Node backends

Examples

File Description
hello.ssc Minimal "Hello, World!"
fs-roundtrip.ssc std.fs write / read / append / list / delete round-trip
os-env.ssc std.os env vars, path helpers, platform detection
nfc-ndef.ssc std.nfc capability check plus text/URI/MIME NDEF record constructors
rozum-agent.ssc Self-contained fake rozum gateway plus std.agent tool-call loop over an accounting-style tool
rozum-agent-schema-derived.ssc Self-contained fake rozum gateway with derived AgentSchema and explicit tool schemas side by side
rozum-agent-pool.ssc Self-contained fake primary/secondary rozum gateways plus AgentEndpointPool failover
rozum-agent-streaming.ssc Self-contained fake rozum SSE gateway plus runAgentStream callbacks for text/tool-call events
yaml-parse.ssc std.yaml parse YAML + accessors + fenced block wiring
ui-typed-json.ssc std.json navigable JsonValue (total accessors, exact asDecimal) + structured builders
ui-fetch-json.ssc fetchJsonValue (GET → navigable JsonValue) + fetchJsonAction (POST structured body)
frontend/std-ui/styled-primitives.ssc std.ui status primitives (badge/tag/pill/kpiCard/tabBar), token-aware styled(), box sizing; re-themes under dark
datatable-static-spa.ssc Browser SPA backed by a static in-memory DataTable (staticDataTable / fieldsBody); renders client-side with no fetch, identical on interpreter / JVM / JS
index.ssc Landing page for the serve examples browser
script.ssc Functions, loops, Fibonacci
data-types.ssc Case classes, sealed traits, enums, pattern matching
functional.ssc Lambdas, closures, HOF, composition, pipelines
enums.ssc Simple and parameterised enums, recursive ADTs
extensions.ssc Extension methods, for comprehensions, while, recursion
imports.ssc Math, geometry, statistics
multi-link-imports.ssc Two std modules imported from one pure Markdown paragraph
typeclass.ssc Show, Eq, Ord, Monoid, Functor via given/summon
quoted-macro-interpreter.ssc Restricted quoted macros on the interpreter run path with Expr.asValue / Expr.asTerm
quoted-macro-constfold.ssc Compile-time constant folding via Expr.asValue match (literal → Some, else None); interpreter run + ssc link fold
custom-derives-mirror.ssc User-defined typeclass derives through runtime Mirror metadata
typed-data.ssc Data pipelines, Option, enums
graph-storage.ssc JVM graphs: front matter plus generated Graph.* facade over embedded TinkerGraph property graph storage
graph-rdf4j-storage.ssc JVM graphs: front matter plus generated Graph.* and Sparql.select facades over RDF4J memory RDF storage
graph-storage-interpreter.ssc Interpreter Graph.* facade over in-memory property graph storage
content.ssc md interpolator, auto-output, doc/render
content-introspection.ssc Markdown-to-frontend authoring: Markdown body content, YAML data, section ids, and multiple real std/ui controls declared directly in yaml @id=... @ui=toolkit blocks and selected by id; runs as a live serve(page, 8099) phone preview
markdown-toolkit-links.ssc Live serve(page, 8099) example where textField, checkbox, button, signalText, and badge controls are declared as ordinary Markdown toolkit: links instead of YAML, including a visible Apply-status update
content-to-markdown.ssc Reverse-render selected DocumentContent regions back to semantic Markdown with contentToMarkdown(value)
content-linked-namespaces.ssc Read section content from a directly imported module namespace with contentModuleSection(namespace, id)
content-tables.ssc Use a Markdown GFM pipe table as ContentBlock.Table, show raw ${name} placeholders, bind YAML data with contentBind(...), and lower the bound table through contentToolkitBlock(id) to a toolkit TableNode
content-toolkit-transitive/app.ssc Entry module renders a @ui=toolkit control block through contentToolkitBlock(id) called from a transitively-imported child — the JS backend emits the content-toolkit runtime for imports anywhere in the graph
content-live-rows.ssc Bind a live fetch Signal as the rows of a Markdown-authored table: a toolkit:table?rows=<id> link resolves a contentRows(id, signal, columns) registration to a live DataTable (content-toolkit 3b)
content-toolkit-yaml-controls.ssc Declarative @ui=toolkit YAML control tree whose {type: button, action: <id>}, {type: table, source: <id>}, and {type: signalText, signal: <id>} reference a registered action / data source / computed signal by id, and the table declares typed columns: (text/date/money/status/link) inline (declarative-ui Scope B.1 + B.5 + B.2)
content-data-source.ssc @ui=toolkit tables bound to named data sourcescontentDataSource(id, source, columns) registers a fetchSource(...) (managed GET, re-fetch on tick, with an optional dotted rowsPath envelope path) or a staticSource(...) (in-memory rows) under an id that source: resolves (declarative-ui Scope B.3)
content-action-onsuccess.ssc A @ui=toolkit button bound to an action whose structured onSuccess runs after a 2xx — fetchActionWith(method, url, body, [onBumpTick(t), onSetSignal(s, v), onNavigate(path)]) refreshes a table, flashes a status signal, and routes, in order; a failed POST runs none (declarative-ui Scope B.4)
content-form-submit.ssc A @ui=toolkit form whose submit action assembles its POST body from the named field signalsfetchActionWith("POST", url, formBody([("customerName", "customer"), "amount"]), …) serialises {customerName, amount} from the live signals at click (a (jsonKey, signalId) entry remaps a signal to a different wire key), no hand-maintained body signal (declarative-ui Scope B.4+)
content-slot.ssc A @ui=toolkit panel with a {type: slot, id: <id>} escape hatch filled by a code-built TkNode registered with contentSlot(id, node) — when the declarative vocabulary can't express a widget, the author drops a ScalaScript-authored one into the panel by id (declarative-ui Scope B.6)
markdown-native-controls.ssc Same Markdown/YAML-declared controls rendered through native clients: `ssc run-jvm --frontend swing
recursion.ssc Self-TCO, mutual TCO, Collatz — deep recursion without overflow
effects.ssc Algebraic effects — Console routing, nondeterminism, early return
std-effects-demo.ssc Logger, Random, Clock, State, Env standard effects
direct-demo.ssc direct[M] do-notation, .! postfix bind, effect-row unions
async-demo.ssc Built-in Async effect — runAsync, async, await, parallel, delay
coroutine-demo.ssc coroutineCreate, coroutineResume, suspend, generators
signals-demo.ssc Reactive signals — Signal, computed, effect, diamond dedup
storage-demo.ssc Built-in Storage effect — JSON-backed and ephemeral handlers
actors-demo.ssc Actors — spawn, send, receive, supervision, cluster
actors-typed-remote-spawn.ssc Typed ActorRef[M] helpers plus named registerBehavior / spawnRemote
cluster-capability.ssc ClusterCapability, static seed discovery, and code identity checks
remote-registry-rpc.ssc remoteHandlers: / @remote / remote def registry declarations, Remote.function, typed remoteTryCall, HTTP JSON fallback path metadata, and generated RemoteRpc typed client metadata for path: handlers
openapi-annotation.ssc @openapi(...) route metadata and openApiSecurity(...) security schemes surfaced in /_openapi.json and Swagger UI
ws-recv-demo.ssc Sync-style ws.recv() loop alternative to onMessage callbacks
mcp-demo.ssc MCP server with tools and resources; MCP client usage
dataset-stats.ssc Dataset MapReduce — runLocal, runParallel, aggregations
dsl-demo.ssc Parser combinators, error recovery, multi-pass compilation pipeline
lenses.ssc .copy(field = v), Focus[T](_.a.b), get / set / modify / andThen
default-params.ssc Default parameter values on defs, classes, and enum cases
lang-split.ssc scala vs scalascript block annotations side by side
scala-js-demo.ssc Pure scala 3 document — runs on all three backends with byte-identical output
rest-api.ssc Tiny in-memory REST API — route(), html"...", serve()
mount-demo/ mount() intrinsic — file-based handlers, typed (CaseClass => CaseClass auto-deser/ser), 1-arg, 2-arg with ctx, static response
sql-sqlite-file.ssc SQLite file database — databases: front-matter, sql DDL/DML blocks, Db.query/execute
typed-sql-crud.ssc Typed SQL CRUD — derives RowCodec, Db.insert/update/query[A] on interpreter and JVM codegen paths
typed-object-codec.ssc Typed object/document codec — derives ObjectCodec, portable object fields, aliases/defaults, and key extraction
graph-codecs.ssc Typed graph/RDF codecs — derives VertexCodec, EdgeCodec, and RdfCodec
dataset-typed-mapping.ssc Typed Dataset element mapping — DatasetCodec[A] over JsonCodec[A] in a JVM Dataset pipeline
distributed-dataset-codec.ssc Distributed Dataset partition payloads — DatasetCodec.encodePartitions/decodePartitions[A]
distributed-dataset-wire-protocol.ssc Distributed Dataset wire protocol — DatasetWirePartition payloads through local MapReduce actor workers
distributed-dataset-wire-shuffle.ssc Distributed Dataset wire shuffle — DatasetWirePartition reduceByKey through local MapReduce actor workers
distributed-dataset-typed-helpers.ssc Distributed Dataset typed helpers — DistributedDataset.run/runShuffle[A, B] around actor map + shuffle wire execution
spark-schema-mapping.ssc Spark-like schema metadata — derives SparkSchemaCodec using shared field annotations
spark-shared-schema-reader.ssc Spark typed CSV reader — Dataset.fromCsvAs[A] using SparkSchemaCodec[A] external column names
indexeddb-drafts.ssc Typed client IndexedDB store — IndexedDb.store[A], local put/get/all/keys, awaitClient(...)
indexeddb-sync-client.ssc Typed client sync helper — Sync.push[A] / Sync.pull[A] over local IndexedDB and REST sync endpoints
sync-todo.ssc Full sync UI helper API — Sync.put, Sync.sync, Sync.status, Sync.isOnline, Sync.isSyncing, Sync.pending
object-store-jdbc.ssc Typed server ObjectStore — JDBC JSON table, ObjectStore.put/get/all/delete/changes[A], derives ObjectCodec
object-store-sync-routes.ssc Typed ObjectStore sync routes — objectStores: front matter generates JVM REST pull/push endpoints
sql-transaction.ssc Atomic multi-statement transaction block — debit + credit in one JDBC transaction
spa-demo.ssc Same route() / serve() source, browser SPA via ssc emit-spa
pwa-demo.ssc Progressive Web App — pwa(name, icons, precache), GET /manifest.json + GET /sw.js
swing-hello.ssc Minimal JDK-only Swing desktop window
swing-fullstack/ No-socket JVM desktop full-stack example: Swing fetchActionClear posts to generated JVM backend routes and dataTable reads/deletes rows in the same process
swing-typed-client/ No-socket JVM desktop full-stack example using generated apiClients: methods over backend routes
typed-client-distributed/ Same-source distributed typed route client: JVM server on one machine, browser/Electron client on another via --server-url
auth-demo.ssc Login / logout with signed cookie sessions + CSRF tokens
fetch-auth.ssc Bearer-token authed fetch: fetchActionClear with headers Signal (v1) + fetchUrlSignal GET with headers (v2)
seed-signal.ssc Editable draft signal seeded from fetchUrlSignal; reloads update the draft only while it is pristine
oauth-demo.ssc Full OAuth2 sign-in (GitHub or Google) — state, exchange, userinfo
tls-demo.ssc HTTPS + WSS server with tls(cert, key)
wc-demo.ssc Web Components via ssc emit-wc, SSR + hydration
wasm-fibonacci.ssc scalascript → WebAssembly module via ssc emit-wasm
wasm-sorting.ssc · wasm-matrix.ssc · wasm-primes.ssc · wasm-collections.ssc Wasm benchmark suite
wasm-scalascript.ssc scalascript blocks → WebAssembly — Point geometry with //> using dep
wasm-http.ssc HTTP Fetch via scalajs-dom in Wasm — //> using dep hoisted directive
algebraic-effects.ssc Typed effects end-to-end — discharge signatures, Reader[R], NonDet, multi effect
examples/frontend/counter/ · show-hide/ · todo/ · toolkit-demo One source compiled to React / Vue / Solid / Custom — first three via Frontend Framework SPI, toolkit-demo via high-level Toolkit (Tk facade) and covered by an Electron Add-flow smoke test
x402-server.ssc · x402-client.ssc HTTP 402 micropayment server + client (Ethereum settlement)
x402-metamask.ssc Browser x402 wallet helper — connect MetaMask and sign EIP-712 via window.ethereum
x402-cardano.ssc x402 on Cardano — CIP-8 wallet, Scalus escrow validator, end-to-end client + server
wallet-ledger-js.ssc Browser Ledger/WebHID vault sketch — connect lifecycle, Ethereum signer, Cardano CIP-8 helper
wallet-mpc-fireblocks.ssc JVM Fireblocks MPC vault sketch — remote secp256k1 signing through Fireblocks RAW transactions
spark-sql-demo.ssc Spark SQL via sql fenced blocks + ${expr} bind parameters + section aliases
spark-encoder-demo.ssc Scala 3 native Encoder[T] derivation — Dataset[CaseClass] end-to-end on Spark 4
spark-streaming-rate-console.ssc Structured Streaming — rate source → console sink with auto-awaitTermination
spark-delta-demo.ssc Delta Lake — auto-emit delta-spark dep + extension/catalog configs
spark-hive-demo.ssc Hive metastore via spark-hive-metastore: + @TempView("...") + Dataset.fromTable[T]
spark-mllib-pipeline.ssc MLlib — Tokenizer + HashingTF + LogisticRegression pipeline end-to-end
xslt-transform.ssc XSLT 1.0 transformation — identity, element rename, parameter substitution, HTML generation (MarkupCodec.transform)

Run them all at once:

./examples/run-all.sc

Frontend Toolkit demo

A reference SPA built entirely through the high-level Tk facade (layout + form-like fields + display widgets + theming). Compiles to all four frontend backends + static HTML via SSR.

# 1. Compile + test (frontend-toolkit 217 tests, frontend-examples 41)
sbt frontendToolkit/test frontendExamples/test

# 2. Generate 16 (4 demos x 4 backends) HTML+JS bundles
sbt "frontendExamples/runMain scalascript.frontend.examples.EmitAll"
#   → target/frontend-examples/toolkit-demo/{custom,react,solid,vue}/

# 3. Serve via the bundled ssc static-file server (no Python/Node)
ssc serve 8000 target/frontend-examples/toolkit-demo/react
# open http://localhost:8000/

Details: examples/frontend/README.md and docs/user-guide.md#16-frontend-toolkit. For SSR (Ssr.renderToHtml) and the full widget catalog see specs/frontend-toolkit-spec.md.

Benchmarks

Cold start (interpreter)

The interpreter uses lazy plugin loading (v1.33): the ServiceLoader scan for HTTP/SQL/OAuth/etc. plugins is deferred until the first plugin name is actually accessed. Scripts that never call a plugin skip the scan entirely.

Script Steady-state cold start
hello.ssc (no plugins) ~0.31 s
Script with HTTP/SQL/auth ~0.35 s (scan runs on first access)

Application Class-Data Sharing (AppCDS) is enabled in bin/ssc and the install.sh launcher (-XX:+AutoCreateSharedArchive, JDK 19+; the archive is auto-created on first run and auto-recreated on classpath change — no build step). It cuts a fresh ssc run hello.ssc from ~378 ms → ~182 ms (−51%) and peak RSS from 167 → 114 MB (−32%). Old JDKs ignore the flags; opt out with SSC_NO_CDS=1. Three real-workload-perf harnesses live under tests/perf/: coldstart/ (fresh-run wall-clock + RSS), serverrss/ (steady-state server RSS

  • leak detection — the interpreter server settles at ~195 MB with no climb), and GC-under-load.

Microbenchmarks (scripts/bench)

Everything benchmark-related goes through one wrapper:

scripts/bench interp                  # all interpreter microbenchmarks
scripts/bench interp recursionFib     # filter to one bench
scripts/bench cross                   # interp vs JS vs JVM (RuntimeBench)
scripts/bench off recursionFib        # prove the off-mode fall-back works
scripts/bench profile recursionFib    # JFR alloc + GC profile
scripts/bench wall                    # cross-language wall-clock (ssc/scala/node)
scripts/bench help                    # full command list

The canonical reference — what each bench measures, when to use it, how to add a new one — is docs/benchmarks.md.

Quick non-blocking smoke checks for perf-sensitive changes:

ssc bench --smoke               # corpus-driven CLI smoke
scripts/bench smoke             # one-iter JMH smoke (writes bench/jmh-smoke.json)

The checked-in workflow and baseline policy live in bench/perf-manifest.yaml and bench/README.md. Raw JMH/runtime outputs are ignored; only curated summaries should be promoted into tracked baseline files.

Watch reload benchmark

ssc watch-bench measures the same parse-cache, incremental typer, and interpreter reload path that ssc watch uses, but runs against a temporary copy so the source file is not modified:

ssc watch-bench --cycles 10 --target-ms 100 examples/rest-api.ssc
ssc watch-bench --cycles 10 --target-ms 100 --require-target examples/rest-api.ssc

The command reports warm-up, p50, and max cycle times. --require-target turns the target into a non-zero exit condition for local performance gates.

End-to-end smoke

e2e/rest-smoke.sc boots examples/rest-api.ssc through each of the three backends in turn and diffs their HTTP responses — guards against drift between the interpreter / JVM / JS serve runtimes.

scala-cli e2e/rest-smoke.sc

Conformance Suite

Cross-backend tests that verify JVM interpreter and JS transpiler produce identical output. Run with:

scala-cli conformance/run.sc
Test What it covers
arithmetic Integer and floating-point ops, math.*
strings String methods and interpolation
collections List — map, filter, fold, take, drop, …
option Optionmap, getOrElse, filter, …
pattern-matching Literals, guards, Option, tuple patterns
case-classes Case class construction, field access, pattern matching
for-comprehensions yield, guards, nested generators, do
higher-order-functions Lambdas, compose, flatMap, eta-expansion
recursion Factorial and Fibonacci
tail-recursion Self-TCO at depth 100 000 — sum, countdown
mutual-recursion Mutual TCO — isEven/isOdd at depth 100 000
sealed-traits ADT hierarchy with sealed trait + case class
variables var mutation and while loops
tuples Tuple construction, _1/_2/_3, destructuring
maps Mapsize, getOrElse, contains, keys, values
list-companion List.fill, List.tabulate, List.range
modules [name](./path.ssc) imports — bind definitions from another file
effects Algebraic effects: Console routing, Choose nondeterminism, Fail early-return
std-effects Logger, Random, Clock, State, Env standard effects with default + test handlers
async Built-in Async effect — runAsync drives async / await / parallel / delay
async-parallel runAsyncParallel — real-thread Async on JVM
storage Built-in Storage effect — get / put / remove / has / keys via ephemeral or file-backed handler
direct Direct-syntax do-notation: direct[M], .! bind, pure lift, control flow
coroutines coroutineCreate, coroutineResume, suspend, Step[Y,T], coroutineCancel
generators generator[T] { yield(v) }, pipeline composition, lazy streams
streams Source[A] / Sink[A] / Flow[A, B], stream { emit(x) }, bounded buffers, overflow strategies, wall-clock throttle/debounce, live Source.signal, and sig.bind(source)
signals Reactive Signal / computed / effect with diamond-dedup flush
lenses .copy(field = v) and Focus[T](_.a.b) — get / set / modify / andThen
prisms Prism[Sum, Variant] — getOption / set / modify on enum / sealed-trait cases
optional Focus[T](_.maybe.some.field) — Optional optic with getOption / set / modify / andThen
traversal Focus[T](_.items.each.field) — Traversal with getAll / modify / set / andThen
actors spawn / send / receive / supervision / link / exit
actors-dist Distributed actor cluster, WS transport, gossip, leader election
mcp MCP server tools + resources; MCP client callTool
dataset Dataset[T] local sequential, parallel, distributed MapReduce
dsl Parser combinators, error recovery, indentation-aware, multi-pass pipeline
metaprogramming inline, derives, compiletime.*, restricted quoted macro link/interpreter expansion (partial), interpreter Mirror.Of[T] custom derives
checked-errors throws[A, E], attemptCatch, HasStackTrace
websocket onWebSocket, ws.send/recv, rate limiting, wss://
tls tls(cert, key), HTTPS, WSS

Backends

ScalaScript supports the following bundled backends, all loaded through the Backend SPI plugin architecture (specs/backend-spi.md):

Command Backend id How it works
bin/ssc file.ssc int Tree-walking interpreter — instant startup, no compilation
ssc run --target jvm file.ssc jvm Compile via JvmGen → temp .scscala-cli run. True JVM semantics, no artifacts left on disk. Requires scala-cli.
ssc run-jvm file.ssc jvm Alias for ssc run --target jvm (kept for backward compatibility)
ssc run-js file.ssc js Compile via JsGen → temp .jsnode. True Node.js semantics, no artifacts left on disk. Requires node.
bin/jssc file.ssc js Alias for ssc run-js via bin/ wrapper
bin/sscc file.ssc jvm Alias for ssc run-jvm via bin/ wrapper
ssc emit-openapi file.ssc openapi Headless interpreter dry-run that exports registered routes as OpenAPI 3.1 JSON or YAML. Flags: --format json|yaml, -o, --title, --version, repeatable --server.
ssc emit-spa file.ssc scalajs-spa Self-contained SPA HTML + JS bundle
bin/ssc-spark file.ssc spark Apache Spark 4 — generates a Scala 3.7.1 .sc script with //> using dep directives, runs via scala-cli. Auto-detects sql blocks, @SqlFn UDFs, readStream/writeStream, .format("delta"), @TempView, MLlib imports. See §13 of the User Guide.
ssc emit-wasm file.ssc / examples/run-wasm.sh wasm WebAssembly module — scalascript/ssc blocks lowered to Wasm IR. Cross-backend sql fenced blocks supported (v1.27 Phase 5).
ssc-native (GraalVM) native No-JVM ssc binary; plugins via ssc-plugin-host.jar subprocess bridge
(sub-backend) node Node.js runtime variant of js — emits server-side JS with fs/path shims and a cross-backend SQL runtime (v1.27 Phase 4).
(sub-backends) frontend-{react,vue,solid,custom} Frontend Framework SPI (v1.18 Phase A): same .ssc UI source compiled to React (useState/useEffect), Vue 3 (ref/render), Solid (createSignal/createEffect), or a minimal custom runtime — ShowSignal/ToggleSignal/ForSignal reactive primitives shared across all four. See specs/frontend-framework-spi-plan.md.
JVM desktop sub-backend frontend-swing Partially implemented JDK-only JVM desktop frontend. It provides SPI discovery, ssc run-jvm --frontend swing, Swing source emission for text/buttons/fields/toggles/stacks/spacers/dividers/scroll views, basic style hints, local signal actions, Swing fetchAction / dataTable / typed route client dispatch through generated JVM BackendTransport, no-socket full-stack examples, and a swing-plugin skeleton for future interpreter intrinsics; JavaFX/Compose adapters remain planned. See specs/jvm-desktop-frontend.md.

The Backend trait + ServiceLoader discovery let third parties add their own backend without touching core — drop a JAR and attach it via ssc --plugin path/to/your-backend.jar. See docs/writing-a-backend.md and the worked samples under examples/plugins/.

Useful flags:

ssc --list-backends                 # list every visible backend
ssc --list-source-languages         # list registered SourceLanguage plugins
ssc --describe-backend jvm          # capabilities + intrinsics + sources
ssc --backend js run file.ssc       # override the per-command default

Built-in fenced languages are SourceLanguage plugins too: scala, html, css, javascript/js, xml, bind-aware sql, and bind-aware transaction are visible through --list-source-languages. Third-party DSLs follow the same path.

The JavaScript backend handles two block types differently:

  • scalascript blocks — transpiled by our custom JS transpiler (JsGen), which supports ScalaScript-specific features (effects, content helpers, TCO, imports).
  • scala blocks — compiled by Scala.js via scala-cli --js, giving full Scala 3 fidelity (standard library, type system, no custom runtime limitations).

When a .ssc file contains both, the Scala.js-compiled section runs first, followed by the ScalaScript transpiled section.

Compiler Plugins with Intrinsics

A compiler plugin lets you extend ScalaScript with new native capabilities — cryptographic primitives, ML inference, GPU kernels, hardware I/O — by mapping extern def declarations in a .ssc source to platform-specific implementations.

// crypto.ssc  (shipped inside the .sscpkg)
extern def sha256(input: String): String
extern def hmacSha256(key: String, data: String): String

Call it from any .ssc file just like a normal function:

import [Crypto](crypto)

val digest = sha256("hello, world")
println(hmacSha256("secret", digest))

Each extern def maps to an IntrinsicImpl:

Variant When to use
NativeImpl(fn) Interpreter — call the JVM lambda directly
RuntimeCall(sym) JVM / JS codegen — emit sym(args…) and ship sym as a runtime helper
InlineCode(emit) Emit arbitrary target code at each call site
HostCallback(name) Out-of-process backends — route through the host wire protocol

Plugins are packaged as .sscpkg (a ZIP containing manifest.yaml, sources/*.ssc, runtime/jvm.scala + runtime/js.js, and an intrinsics/*.jar that registers a Backend via ServiceLoader):

ssc plugin pack  _pkg/   -o org.example.crypto-1.0.0.sscpkg
ssc plugin install      ./org.example.crypto-1.0.0.sscpkg   # permanent
ssc --plugin ./org.example.crypto-1.0.0.sscpkg run use-crypto.ssc  # ad-hoc

Installed distributions also include first-party advanced plugins locally under bin/lib/compiler/plugin-available; use --plugin with one of those .sscpkg files when you want opt-in capabilities without a registry domain.

See examples/plugins/crypto-plugin/ for a complete worked example and docs/user-guide.md §21 for the full API reference.

CLI Commands

ssc run file.ssc              # interpret (tree-walking, instant startup)
ssc run --target jvm file.ssc # compile via JvmGen + run with scala-cli (no artifacts)
ssc run-jvm file.ssc          # same as above (backward-compat alias)
ssc run-js file.ssc           # compile via JsGen + run with node (no artifacts)
ssc watch file.ssc            # watch mode (re-run on change)
ssc watch-bench file.ssc      # benchmark watch reload cycles on a temp copy
ssc bench --smoke             # quick interpreter-only benchmark wiring smoke
ssc check file.ssc            # type-check only (parse + typer, no codegen); exit 0=clean 1=type-err 2=parse-err 3=notfound
                              #   also warns on @ui=toolkit controls that reference an unregistered action/data-source id (declarative-ui B.7)
ssc check --json file.ssc     # structured JSON diagnostics
ssc check --quiet file.ssc    # no output, exit code only (for pre-commit hooks)
ssc check --watch file.ssc    # re-check on file change, Ctrl-C to stop
ssc check src/                # recursively check all *.ssc files in a directory
ssc repl                      # interactive REPL
ssc build myapp.ssc           # build project file → dist/ (--target ssc|jvm|js|web)
ssc build                     # auto-discover <dirname>.ssc or single .ssc in cwd
ssc build src/                # dir-walk mode (backward compat)
ssc package myapp.ssc         # build all targets: listed in frontmatter
ssc install [--prefix <dir>]  # install ssc to ~/.local (or custom prefix)
ssc compile-jvm file.ssc      # compile to .scjvm artifact
ssc compile-js file.ssc       # compile to .scjs artifact
ssc emit-interface file.ssc   # emit .scim interface
ssc emit-ir file.ssc          # emit .scir normalized IR
ssc link --backend jvm dir/   # link artifacts
ssc build --incremental dir/  # incremental build
ssc emit-js file.ssc          # transpile to JS
ssc emit-lib --host js|jvm|rust|java --feature optics -o dir/  # standalone host library (npm/jar/crate/maven)
ssc emit-spa file.ssc         # SPA HTML bundle
ssc emit-wc file.ssc          # Web Components bundle
ssc test file.ssc             # run tests
ssc preview file.ssc          # preview component variants
ssc deps file.ssc             # show import closure
ssc search json [--refresh|--offline]
ssc info io.scalascript/json [--registry <url>]
ssc add io.scalascript/json [<version>] [--file <manifest>]
ssc info artifact.scjvm       # inspect artifact
ssc plugin install/list/uninstall/check/pack/registry
ssc --list-backends / --describe-backend <id>
jssc file.ssc                 # JS transpiler runner
sscc file.ssc                 # JVM runner
ssc-spark file.ssc            # Apache Spark runner (Spark 4 + Scala 3.7.1)
ssc submit file.ssc           # spark-submit fat JAR (cluster deploy)
ssc --spark-master <url>      # override Spark master (local[*] / spark:// / yarn / k8s://)
ssc --spark-version <v>       # override Spark version (default 4.0.0)

Project Layout

bin/
  ssc          # interpreter launcher (tree-walking, no compilation step)
  jssc         # JS runner: transpiles .ssc → JS and runs via Node.js
  sscc         # JVM runner: compiles .ssc → Scala 3 → JVM via scala-cli
  ssc-js       # JS transpiler: emit JS to stdout, or --run to execute
  http.ssc     # HTTP server for examples browser

runtime/backend/spi/        # SPI traits (Backend, SourceLanguage, PluginRegistry, Capabilities, …)
runtime/scalascript-plugin-api/ # Stable plugin author API (PluginValue, PluginNative, capability traits)
ir/                         # IR types + JSON/MsgPack codecs
core/
  src/main/scala/scalascript/
    parser/    # Markdown + YAML + Scala parser
    typer/     # Type checker
    ast/       # AST types
    imports/   # Cross-file import resolver
    interpreter/Value.scala  # Computation Free monad (used by interpreter+codegens)
    transform/ # Normalize, DirectDesugar, EffectAnalysis
    plugin/    # PluginRegistry facade, BackendRegistry, SubprocessBackend, WireProtocol
runtime/backend/jvm/      # JvmGen — emits Scala 3 source
runtime/backend/js/       # JsGen — transpiles to JavaScript
runtime/backend/scalajs/  # ScalaJsBackend — emits SPA via Scala.js
runtime/backend/interpreter/
  src/main/scala/scalascript/
    interpreter/    # Tree-walking interpreter
    server/         # Built-in HTTP / WebSocket / Actor / MCP runtime
    bench/          # WsStress benchmark
runtime/runtime-server/common/      # Shared HTTP/WS server primitives (all backends)
mcp/common/                 # Shared MCP protocol types + codec
cli/                        # Main entry point (ssc command)

conformance/     # Cross-backend conformance test suite
  expected/      # Canonical expected outputs

examples/        # Runnable .ssc files
  run-all.sc     # Runs all examples in order
  plugins/       # Worked backend plugin examples

build.sbt        # sbt build — multi-module per spec §4.1
project/
  build.properties
  plugins.sbt    # sbt-assembly for fat-jar packaging

docs/            # Architecture, spec, design docs
  architecture.md        # Compiler pipeline and module structure
  backend-spi.md         # Backend SPI design (source of truth)
  direct-syntax.md       # Direct do-notation (v1.8+)
  coroutines.md          # Coroutine primitive (v1.9+)
  dsl.md                 # DSL authoring and parser combinators (v1.20)
  mapreduce.md           # Dataset / MapReduce API (v1.21–1.22)
  mcp.md                 # MCP server + client (v1.17)
  actors-dist.md         # Distributed actors design
  metaprogramming.md     # inline/derives (v1.14)
  error-handling.md      # Checked errors / throws (v1.15)
  modularity.md          # Package system and separate compilation
  markdown-as-syntax.md  # Markdown as Syntax design
  targets.md             # Target Backends
  user-guide.md          # Practical user reference
  tutorial.md            # Step-by-step todo-list application tutorial
tools/scripts/         # launchers/ and validate-frontmatter.scala

Installing as a Binary

# Install scala-cli first (if needed)
./setup.sh

# Build ssc into bin/
./install.sh --dev

After installation:

ssc examples/hello.ssc
jssc examples/hello.ssc
sscc examples/hello.ssc

Library Usage (sbt)

ScalaScript can be used as a Scala 3 library via sbt:

sbt compile      # compile all modules
sbt test         # run unit tests
sbt cli/assembly # produce a self-contained ssc.jar
sbt cli/installBin # stage bin/lib so bin/ssc works from the checkout

The public API surface:

import scalascript.parser.Parser
import scalascript.interpreter.Interpreter
import scalascript.codegen.{JsGen, JvmGen}

val module = Parser.parse(source)            // parse a .ssc file
Interpreter.run(module)                      // interpret
val js    = JsGen.generate(module)           // emit JavaScript
val scala = JvmGen.generate(module)          // emit Scala 3 script

ScalaScript libraries can also be packaged as .ssclib archives:

ssc package --lib --precompile --manifest ssclib-manifest.yaml -o dist/my-lib.ssclib
ssc check-compat dist/my-lib-1.0.ssclib dist/my-lib-1.1.ssclib

--precompile embeds .scim public interface artifacts under ir/. check-compat reports removed or changed public symbols between library versions and falls back to deriving interfaces from packaged sources when a library has no precompiled interface artifacts.

Design Principles

  1. Reuse, don't invent. Markdown, YAML, Scala 3 — use what works.
  2. One source, many targets. Source semantics are target-independent.
  3. Human and machine readable. Pleasant for humans, trivially parseable for machines.
  4. No AI at runtime or compile time. The language stands on its own.

License

Apache License 2.0

Author

Sergiy (Victorovych) Shcherbyna sergey.scherbina@gmail.com

About

Literate Scala 3 in Markdown. One .ssc source runs on a tree-walking interpreter, transpiles to JavaScript, compiles to the JVM, emits a native Rust binary, or targets WebAssembly. Algebraic effects, typeclasses, reactive UI, and a native reactive web server — pick the backend at build time.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors