Run Musubi locally
This is the shortest reliable path from a fresh clone to a working development environment. It deliberately separates the backend, docs, and native client so you can run only the layer you are changing.
Prerequisites
Section titled “Prerequisites”| Tool | Version / notes |
|---|---|
| Node.js | 22.12 or newer. Astro 7 requires it. |
| pnpm | Use Corepack; the root manifest activates exactly [email protected]. |
| PostgreSQL | 15+ locally, or Docker. The bundled Compose stack uses PostgreSQL 17. |
| Git | Any recent version. |
| Native client | Android Studio for Android; Xcode on macOS for iOS; or an EAS development build. |
First boot
Section titled “First boot”-
Clone and install the pinned workspace.
Terminal window git clone https://github.com/frgtn-dot-dev/musubi.gitcd musubicorepack enablepnpm install --frozen-lockfilepackage.jsonat the repository root is the only package-manager version source. Do not install a separate global pnpm or add package-localpackageManagerfields. -
Create the local environment file.
Terminal window cp .env.example .envFor a minimal local stack, set:
POSTGRES_USER=musubiPOSTGRES_DB=musubiPOSTGRES_PASSWORD=local-development-onlyDATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}API_SERVER_PORT=7531ENVIRONMENT=devBETTER_AUTH_URL=http://localhost:7531BETTER_AUTH_SECRET=replace-with-a-long-random-valueGenerate secrets instead of inventing production values:
Terminal window openssl rand -base64 32 # BETTER_AUTH_SECRETopenssl rand -hex 32 # CALDAV_ENC_KEY, when testing CalDAV/federationSee Environment variables for every setting, feature gate, and rotation consequence.
-
Start PostgreSQL.
Terminal window docker compose up -d dbdocker compose psCreate the database named in
DATABASE_URLand make sure it is reachable:Terminal window pg_isready -h localhost -p 5432 -U musubi -d musubi -
Apply every server migration.
Terminal window pnpm db:migrateMigrations live in
packages/db/drizzle/and are applied in journal order. -
Start the API and verify it.
Terminal window pnpm --filter @musubi/api devIn a second terminal:
Terminal window curl http://localhost:7531/api/v1/server/ok# {"ok":true} -
Start the documentation site.
Terminal window pnpm docs:devOpen
http://localhost:4321/docs/. -
Build and start the native client.
Connect a device with USB debugging or start an emulator, then run:
Terminal window pnpm --filter @musubi/client androidThe first run generates the ignored native project and installs a development build. Later JavaScript-only sessions can use:
Terminal window pnpm --filter @musubi/client startTerminal window pnpm --filter @musubi/client iosA paid Apple account is needed for some device capabilities. See Authentication before testing Google/Apple sign-in or universal links.
Terminal window cd apps/clienteas build --profile development --platform android# or: --platform iospnpm startInstall the resulting development build once; Metro then hot-reloads JavaScript changes.
Emulator vs physical device
Section titled “Emulator vs physical device”localhost means different things depending on where the client runs:
| Client | API URL to enter on the welcome screen |
|---|---|
| iOS simulator | http://localhost:7531 |
| Android emulator | http://10.0.2.2:7531 |
| Physical phone | http://<your-computer-LAN-IP>:7531 |
For a physical phone, the computer and phone must be on the same network. Set
BETTER_AUTH_URL to that same LAN origin before starting the API, for example
http://192.168.1.42:7531. Run the client with pnpm --filter @musubi/client start; the workspace-wide pnpm dev uses the client’s
localhost-only Metro mode and is best suited to simulators.
Run the whole workspace
Section titled “Run the whole workspace”Once each layer works independently:
pnpm devTurborepo starts every workspace that declares dev and displays the API,
client, and docs in a terminal UI. Use stream output when logs need to be
copyable:
pnpm exec turbo run dev --ui=streamVerify the setup
Section titled “Verify the setup”Before editing code, establish the same baseline contributors use:
pnpm checkThis first validates release/toolchain metadata and peer dependencies, then runs client + API typechecks, the twelve existing assertion-based self-checks, client lint, and the docs build. Lint has zero errors and a locked budget for 108 known React Compiler/hook warnings; a net increase fails the command. The remaining migration is recorded in the codebase audit.
What to do in the app
Section titled “What to do in the app”Use this five-minute smoke flow before beginning onboarding:
- Enter the local server URL and create an email/password account.
- Finish onboarding and rename the auto-created personal calendar.
- Create a second calendar and an event.
- Edit the event, enable attendees, and move it in day view.
- Restart the app and confirm cached calendars/events render before refresh.
Continue with Codebase Onboarding and trace those actions through the client, API, database, provider boundary, and SSE echo.