<!-- Skal docs — markdown mirror of https://skal.run/docs/ -->

# Getting Started

From zero to a native app running your Solid code in about three minutes (plus one coffee while the toolchain warms).

## Prerequisites

-   [bun](https://bun.sh) 1.2+ — runs the CLI, the bundler, and your tests
-   [Flutter](https://flutter.dev) 3.41+ — the rendering host (`flutter doctor` should be green for your targets)
-   Xcode for iOS/macOS, or an Android SDK + emulator for Android

## Create an app

```jsx
$ npm create skal my-app
$ cd my-app
```

The scaffold is a complete, runnable project:

```jsx
my-app/
├── src/
│   ├── App.jsx          # your Solid app — edit this
│   └── index.jsx        # entry: mounts <App/> on the bridge renderer
├── flutter-host/        # platform shells (android/ios/macos) + libskal
├── .maestro/smoke.yaml  # E2E smoke test, ready to run
└── package.json         # dev / build / test scripts
```

## Run it

```jsx
$ npm i -g @skal/cli   # once — or use `bun run dev:<target>` directly

$ skal dev macos       # fastest loop for UI work
$ skal dev android     # boots an emulator automatically if none is attached
$ skal dev ios         # iOS Simulator
$ skal dev web         # Solid → DOM at localhost:5173
```

`skal dev` builds the JS bundle and launches the platform host. Add `--hot` and the hot-reload server pushes every save under `src/` straight into the running app — [navigation and hot state survive](tooling.html).

🍻 **First run is slower.** The platform host compiles once per target (normal Flutter behavior). Every run after that is seconds.

## Make it yours

Open `src/App.jsx`. It's plain SolidJS — signals, memos, effects, `<For>`, `<Show>` — with Skal's widget set instead of DOM tags:

```jsx
import { createSignal } from 'solid-js';
import { Column, Text, Button } from 'skal';

export default function App() {
  const [name, setName] = createSignal('Skal');
  return (
    <Column padding={24} gap={16}>
      <Text label={`Hello, ${name()}`} fontSize={28} fontWeight={800} />
      <Button label="Skål 🍻" onClick={() => setName('World')} />
    </Column>
  );
}
```

When a signal changes, Solid updates exactly the widgets that read it — no virtual DOM, no reconciliation pass. The change crosses to Flutter as a handful of binary ops in shared memory. See [Components](components.html) for the full widget set.

## Ship it

```jsx
$ skal build android   # release APK, JSC bytecode cache baked in
$ skal build ios       # release build for TestFlight
$ skal build macos
$ skal build web       # static site bundle
```

Release builds compile your bundle to JavaScriptCore bytecode, so production cold starts skip the JS parser entirely — that's the [36 ms first-eval](../#performance).

## Where next

-   [Architecture](architecture.html) — what actually happens between a signal and a pixel
-   [State & the Store](state.html) — persistent state with the native store engine
-   [Wrapping pub.dev packages](native.html) — camera, geolocation, anything native
-   [Hot reload & dev loop](tooling.html) — sub-second reload, what state survives
-   [Testing](testing.html) — unit tests, the headless harness, Maestro E2E

[NextArchitecture →](architecture.html)
