# MiniApp quickstart

Create your own two-page application, run it in WeChat Developer Tools, then
make a small source edit. You do not need to understand Minimoon's renderer or
release process first. [Back to README](../../README.md).

## Prerequisites

- MoonBit: `moon 0.1.20260904` with `moonc v0.10.12` or newer.
  Existing local `moon 0.1.20260907` tools need no downgrade.
- Node `>=24.20.0` and Bun `1.4.2`, available in your terminal.
- Git, a writable development directory with enough free space, and WeChat
  Developer Tools with Skyline support.
- A suitable WeChat MiniApp account/AppID for host preview. Automated CLI
  checks do not establish account or device-preview eligibility.

Check the tools before running the setup:

```bash
moon version --all
node --version
bun --version
git --version
```

CI uses the official installer pinned to prebuilt release
`0.10.12+1634b282e`, not latest; no Rust is required. CI covers Node 24.20.0
and 26.8.1. Keep the dependency versions and PostCSS override generated by
`minimoon init`.

## Create from the current source

Core `0.2.0` and UI `0.1.0` are currently documented as unpublished
candidates. This is the default way to try this checkout without resolving an
unpublished core registry package. Published-version installation is a
[separate alternative](#registry-installation-after-publication), not an
additional step.

Start in your chosen development directory, outside another Moon workspace.
The commands create sibling `minimoon/` and `my-app/` directories:

<!-- minimoon:onboarding:start -->
```bash
git clone https://github.com/lucavance/minimoon.git minimoon
cd minimoon
bun install --frozen-lockfile
moon update
moon install --path src/cmd/minimoon
minimoon --version
minimoon init ../my-app --minimoon-root "$PWD"
cd ../my-app
bun install
minimoon build .
minimoon verify . --candidate
```
<!-- minimoon:onboarding:end -->

If you already cloned this repository, start at `cd minimoon` from its parent.
`my-app/` must be new or empty; choose another name if it already contains work.
If `minimoon` is not found after installation, open a terminal with MoonBit's
bin directory on PATH. `minimoon --version` must print `0.2.0`; remove a
stale CLI from PATH precedence rather than building with a different version.

The generated `moon.work` includes your app and the framework checkout.
Keep both directories while developing in source mode. Do not simply delete
the workspace and expect an unpublished dependency to resolve from the registry.

The starter uses only `lampclaw/minimoon`, with Home and Details pages.
It does not enable application-owned shared state or the optional UI module.
Source configuration is `miniapp.minimoon.json`, using App Contract v11.

## Open in WeChat Developer Tools

From `my-app/`, the candidate verification above creates release-mode files.
Import **`my-app/dist/`** unchanged, not `my-app/` or the framework repository.

Check the Developer Tools settings:

- Skyline renderer.
- ES6-to-ES5 transformation, enhanced compilation and minification enabled:
  `setting.es6=true`, `setting.enhance=true`, `setting.minified=true`.
- Online minimum base library **3.17.0** or newer.

For your AppID, copy `dist/project.private.config.example.json` to
`dist/project.private.config.json` **only if the private file does not already
exist**, then edit that private copy. Never overwrite existing local settings
or commit the AppID/private file. Rebuilds preserve it and exclude it from
artifact fingerprints. Do not change generated public files to store secrets.

On a cold launch, expect:

1. **Hello Minimoon**, counter **0**, a name input and **Open details**.
2. Tap **+1**; the counter becomes **1**.
3. Type a name; the greeting updates. Open Details, then return to Home.

Require a clean console. If the host cannot open the project, first check the
import directory, tool settings and your account/AppID. For parser errors or
blank screens, use the [host troubleshooting guide](../operations/miniapp_javascript_compatibility.md).

## Make your first change

Edit **your app's** `src/pages/home/page.mbt`, not the framework template.
Find this initial model inside `program()`:

<!-- minimoon:first-edit:start -->
```moonbit
{ count: 0, name: "Minimoon", visits: 0, }
```

Change only its initial name:

```moonbit
{ count: 0, name: "My App", visits: 0, }
```
<!-- minimoon:first-edit:end -->

From `my-app/`, rebuild and verify:

```bash
minimoon build .
minimoon verify . --candidate
moon test --target js
```

Cold-restart the MiniApp, rather than retaining the old page instance.
The title should now be **Hello My App**; count and navigation still work.
The existing tests remain valid because they set their own input name.

Maintain `src/`, `miniapp.minimoon.json` and `styles/tailwind.css`.
Treat `dist/`, `generated/` and `styles/app.wxss` as generated output.

## Continue developing

From the app directory, `minimoon dev .` watches source changes and rebuilds;
keep using Developer Tools for the preview. It does not start a browser server.
Stop the watcher before a separate manual build.

```bash
minimoon add page activity_log --after home --title "Activity Log"
minimoon add component status_badge --page home
```

The [authoring guide](miniapp_authoring_example.md) explains ordinary page
builders and typed state. Use [typed HTTP](http.md), [native navigation](native_navigation.md),
[shared state](shared_state.md) and the
[UI guide](https://github.com/lucavance/minimoon/blob/main/ui/README.md) as needed.
No-App factories export `program() -> Page`; opting into `application`
changes them to `program(deps : @application.Deps) -> Page`.

Required route parameters use `page_with_input`. Its builder receives plain
input decoded before graph creation; previews are separate. Add explicit
`smokeInput` to required-input configuration entries, for example
`{ "package": "src/pages/details", "smokeInput": { "from": "smoke" } }`.
This is only synthetic input for automated verification, not a navigation
default. See [input and lifecycle](api_ergonomics.md#page-input-and-first-render).

## Registry installation after publication

Use this alternative **only when the matching version is available**, as
recorded in [project status](https://github.com/lucavance/minimoon/blob/main/docs/project_status.md).
Start in a development directory outside every Moon workspace:

```bash
moon install lampclaw/minimoon/cmd/minimoon@0.2.0
minimoon --version
minimoon init my-app
cd my-app
moon update
bun install
minimoon build .
minimoon verify . --candidate
```

This creates a standalone `moon.mod` dependency on `lampclaw/minimoon@0.2.0`,
with no generated `moon.work`. Do not pass `--minimoon-root` in registry mode.
The Developer Tools and first-edit steps are the same as above. Adding UI is
optional and requires its matching published module or an explicit local
workspace; it is not included by the core-only source setup.

## Automated checks and real-host acceptance

`minimoon verify . --candidate` performs automated checks. It does not operate
Developer Tools, test a physical device, or prove production request-domain
eligibility. Keep actual simulator preview, physical-device preview and device
debugging outcomes separate.

Formal release acceptance follows the [host checklist](../operations/miniapp_devtools_validation.md).
Only after the exact release passes should you use `minimoon devtools record`
and `minimoon verify . --release`. Evidence stays local and Git-ignored; never
copy another application's record. These release steps are not required to
make your first edit.

The framework's [Conformance](https://github.com/lucavance/minimoon/blob/main/examples/miniapp_conformance_app/README.md)
has seven routes and four native Tabs; the independent
[UI Showcase](https://github.com/lucavance/minimoon/blob/main/ui/examples/showcase/README.md)
has six pages. They demonstrate and verify framework capabilities, not the
recommended starting contents for a business application.
