Compose web apps in Swift — rendered to vanilla HTML, CSS, and JavaScript.
struct ArticleCard: View {
let post: ContentPost
@State var saved: Bool = false
@Action func toggleSaved() { saved.toggle() }
var body: some View {
VStack {
Heading(3) {
post.frontmatter.title
}
Text {
post.frontmatter.excerpt ?? ""
}
.font(color: .muted)
Button(.ghost, action: toggleSaved) {
saved ? "Saved" : "Save"
}
}
.padding(6)
.border(radius: .lg)
.on(.hover) { $0.shadow(.md).translate(y: .px(-2)) }
.animate(.all, duration: 150.ms)
}
}# Build the CLI from source
git clone https://github.com/mac95sb/score
cd score
swift build -c release
cp .build/release/score ~/.local/bin/score
# Create and run a project
score new my-site
cd my-site && score devOpen http://localhost:8080. Edit any file in Sources/ or Content/ and the
browser reloads automatically.
For guides, tutorials, and the full API reference, see the documentation.
Templates/kitchen-sink references the local checkout and runs without
installing Score:
make ks-dev # score dev with hot-reload (builds Score debug first)It is the canonical live showcase: every element, modifier, theme preset, state pattern, animation, and routing API has a working example there. It doubles as a regression test — if a change breaks the kitchen-sink visually, it broke something real.
Templates/default and Templates/static are scaffold templates used by
score new; browse them as examples of the expected project structure.
| Command | Description |
|---|---|
score dev |
Start the development server with hot-reload (SSE-based). |
score build |
Static export to .score/build/ for hosting. |
score test |
Run the test suite, optionally filtered (--filter). |
score db migrate |
Run pending SchemaMigration migrations. |
score db seed |
Execute seed scripts for populating test data. |
score package macos |
Generate a macOS .app wrapper (WKWebView / SwiftUI). |
score package windows |
Generate a Windows WebView2 shell (C# / .NET 8). |
score package linux |
Generate a Linux WebKitGTK shell (C / make). |
score package android |
Generate an Android WebView shell (Kotlin / Gradle). |
score package swiftui |
Export Records + API client as a Swift package. |
score lint |
Lint Swift sources and Score-specific rules. |
score package wraps your Score app in a native WebView shell for desktop and
mobile platforms. Generated projects are complete, buildable projects for each
platform's standard toolchain — Score does not cross-compile the native shell
itself.
# macOS: Swift Package Manager executable with WKWebView + SwiftUI
score package macos
# Windows: C# WinForms + WebView2 (cross-compile via container)
score package windows
# Linux: C + GTK 4 + WebKitGTK 6.0 (cross-compile via container)
score package linux
# Android: Kotlin + Gradle with WebView
score package android
# Remote mode: point the WebView at a deployed URL instead of bundling
score package macos --url https://myapp.comAll packagers support --url for remote mode (nothing bundled) and --source
for specifying the static export directory. See the generated project's
README.md for build instructions.
Score uses SQLite via the built-in ORM. Migrations are Swift structs conforming
to SchemaMigration:
score db migrate # Run pending migrations
score db seed # Run seed scripts
score db status # Show migration statusscore test runs the test suite. App developers can also use ScoreTestCase,
a protocol with HTML assertion helpers (assertContains,
assertNotContains) for testing view rendering.
When adding a new element, modifier, or feature:
- Add DocC comments to every public API (with a usage code block).
- Update the relevant
Documentation.docc/Articles/article, or add one. - Add a live demo section to
Templates/kitchen-sink/Sources/Application.swift. - Add tests in
Tests/ScoreCoreTests/.
See AGENTS.md for the full contributor checklist and architecture notes.
Apache 2.0