Skip to content
Agentmart
Submit a tool

app-startup-and-bootstrap

Orders an Expo app's cold start - polyfills, error net, splash hold, storage open, providers, splash release, background flush.

Skill by zakariaf

IndexedMIT★ 11
Write a review

Chalk Labs

Need help deploying app-startup-and-bootstrap?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/zakariaf-app-startup-and-bootstrap

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Orders an Expo app's cold start - polyfills, error net, splash hold, storage open, providers, splash release, background flush. Use when editing the root _layout.tsx or the app root, or the splash hangs or flashes. Not for routes (navigation-and-routing).

Use cases: writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/app-startup-and-bootstrap

What's inside

Skill name
app-startup-and-bootstrap
Description
Orders an Expo app's cold start - polyfills, error net, splash hold, storage open, providers, splash release, background flush. Use when editing the root _layout.tsx or the app root, or the splash hangs or flashes. Not for routes (navigation-and-routing).
License
MIT
Instructions
231 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Agent Skills spec issues

  • files: referenced but missing: scripts/metro/metro-kits.ts

Files (45)

  • SKILL.md
  • shared.json · assets/
  • app-root-with-session.tsx · examples/
  • task-draft-buffer.ts · examples/
  • checker-rules.md · references/
  • lifecycle-flush.md · references/
  • splash-screen.md · references/
  • startup-gate-and-deferred-work.md · references/
  • startup-order.md · references/
  • check-lib.mjs · scripts/
  • check-startup.mjs · scripts/
  • source-scan.mjs · scripts/lib/
  • startup-scan.mjs · scripts/lib/
  • selftest.mjs · scripts/
  • startup.json · templates/contracts/
  • startup.schema.json · templates/contracts/
  • _layout.tsx · templates/src/app/
  • app-root.tsx · templates/src/features/root-navigator/
  • app-stack.tsx · templates/src/features/root-navigator/
  • background-flush.test.ts · templates/src/features/root-navigator/
  • background-flush.ts · templates/src/features/root-navigator/
  • hold-splash.test.ts · templates/src/features/root-navigator/
  • hold-splash.ts · templates/src/features/root-navigator/
  • root-kits.test.tsx · templates/src/features/root-navigator/
  • root-kits.tsx · templates/src/features/root-navigator/
  • root-motion.test.tsx · templates/src/features/root-navigator/
  • root-motion.tsx · templates/src/features/root-navigator/
  • root-stack.tsx · templates/src/features/root-navigator/
  • startup-gate.test.ts · templates/src/features/root-navigator/
  • startup-gate.ts · templates/src/features/root-navigator/
  • use-flush-on-background.test.ts · templates/src/features/root-navigator/
  • use-flush-on-background.ts · templates/src/features/root-navigator/
  • use-startup-ready.test.ts · templates/src/features/root-navigator/
  • use-startup-ready.ts · templates/src/features/root-navigator/
  • create-root-kits.ts · templates/src/services/
  • root-kit.test.ts · templates/src/services/root-kits/
  • root-kit.ts · templates/src/services/root-kits/
  • index.ts · tests/bases/app/
  • package.json · tests/bases/app/
  • app-error-net.ts · tests/bases/app/src/services/error-net/
  • install-error-net.ts · tests/bases/app/src/services/error-net/
  • tsconfig.json · tests/bases/app/
  • CASES.json · tests/fixtures/check-startup/
  • SUITE.json · tests/fixtures/check-startup/
  • EXPECT.txt · tests/fixtures/check-startup/good/

SKILL.md (first lines)

# App startup and bootstrap

The app starts in one fixed order: the entry loads the polyfills and then the router; the root layout
installs the error net, holds the native splash and decides the direction before anything opens; the
app root opens storage once, connects the error log and hydrates the stores synchronously, mounts the
providers in dependency order and releases the splash once the first screen is real. Buffered writes
flush from one root hook when the app leaves the foreground. Optional kits (crash reporting,
analytics, notifications, ...) plug into typed slots from one registry, so the root files stay
canonical when a kit is added. One zero-dependency checker proves it.

## Rules that must hold

1. **The entry imports the polyfills first and `expo-router/entry` last.** Nothing follows the router
   import. Why: ES imports evaluate in order; a module after the router entry loads after the root
   component was registered. (`entry-router-last`)
2. **The root layout's first imports are side effects: the error net installer, then the splash
   hold.** Every import with bindings comes after them. Why: a module that throws while loading must
   find the net, and the hold must run before any other app module. (`root-import-order`)
3. **The native splash is held once, at module scope, in `hold-splash.ts`.** Why: Expo Router hides
   an unheld splash at "navigation ready", over a direction restart's empty screen or a blocking wait;
   called in a component or effect, the hold comes after native content appeared, when iOS and Android
   may already have hidden it. (`splash-hold`)
4. **The splash is released once, in an effect, below the direction gate, when the startup gate is
   ready** (`useStartupReady(gate, hideSplash)` in the app root). A startup component renders `null`
   only while the splash is held. Why: a hold with no release keeps a release build on the splash
   forever; a release in render or above the gate uncovers a frame that is not the first screen.
   (`splash-release`, `blank-frame`)
5. **The root layout's first render creates adapters, reads config and resolves the language, and
   opens nothing; `DirectionGate` is its outermost element (directly inside web-support's
   `WebStorageGate` when the app ships the web); everything with effects lives in its child
   `AppRoot`.** Why: a direction restart re-runs every module and initializer, so work done
   before the decision happens twice (rtl-and-direction's `direction-before-render` enforces the gate).
6. **The data layer opens once, synchronously, in the app root's startup initializer, then the error
   net's sink connects, then the query client, settings and stores hydrate, then the optional kits are
   created, in that order** (`startApp`, run as `useState(() => startApp(services, language))`). Why: the first frame has the real rows
   with no loading state, the buffered errors of the first moments reach the log before any provider
   renders, and a second open runs migrations again. (`storage-open-once`, `sink-before-providers`)
7. **The startup path awaits nothing.** The root layout and the app root contain no `await`,
   `.then`, `.catch` or `.finally`; async work the first screen truly needs is a non-interactive
   blocking task of `createStartupGate` with a literal `deadlineMs` at or under 3000. A session
   restore follows auth-and-secure-storage: its read is async and non-interactive, so it is a blocking
   task under the deadline, and a miss starts the session as unknown or unavailable; a biometric
   unlock is never a gate task but a lock screen after the splash. Why: a promise that never settles
   keeps a held splash up forever, and a prompt that waits for the person outlasts any deadline; the
   gate always opens by its deadline and reports what it missed. (`startup-await`, `startup-deadline`)
8. **Fonts are embedded with the expo-font config plugin, never loaded at runtime.** Why: `useFonts`
   either holds the first frame or swaps the font after it. (`runtime-font-load`)
9. **Providers nest in one dependency order and each is mounted once on the root path:** services (or
   `AppProviders`), data, query, settings store, stores, preferences (i18n, theme, text locale), root
   stack (gesture root, keyboard, `RootMotion` (the one MotionConfig), navigation theme, session,
   feedback, ads, games, then `AppStack`, whose `RootKits` slot wraps the `Stack` in the kits'
   providers). Why: each provider reads only those
   outside it, a misplaced one throws only when its path renders on a device, and a second copy
   silently overrides the first. (`provider-order`, `provider-once`)
10. **Deferred work starts after the splash release, in the component or service that owns it; never
    through `InteractionManager`.** Why: consent, entitlements, OTA checks and prefetches must not delay
    the first frame, and `InteractionManager` is a deprecated stub in React Native 0.86 that runs on the
    next tick. (`interaction-manager`)
11. **Buffered writes flush from one root hook when the app leaves the foreground:**
    `useFlushOnBackground(flushers, errorLog)` once, in the app root, before
    `useCheckpointOnBackground`; features hand it a `Flusher` and never write from their own `AppState`
    listener. Why: an iOS swipe-kill from the app switcher sends `inactive` and no `background`, and
    listeners run in subscription order, so the drafts must land before the WAL is folded.
    (`flush-root`, `lifecycle-write`)
12. **Optional kits join through the slots, never through the root files.** A kit returns a `RootKit`
    (`forward`, `blocking`, `flushers`, `motion`, `opensDebugRoutes`, `provide`, `effects`; every part
    optional) from the app's one registry, `src/services/create-root-kits.ts`; `startApp` first calls
    the registry's `prepareRootKits` (the ports every reader uses: a test build's simulated clock and
    network), then `createRootKits` once, after the stores, attaches the kits to the error sink
    (which replays the reports it kept) and hands their tasks to the gate and their flushers to the
    flush; `RootMotion` renders the first kit's motion slot in `MotionConfig`'s place; `AppStack`
    opens its `(debug)` group only while a kit says so and renders `<RootKits kits>` around the
    `Stack`; a kit that needs Metro lists a `MetroKit` in `scripts/metro/metro-kits.ts`, which the
    canonical `metro.config.js` composes. A slot no kit fills does nothing, and a test build's kits
    are reached only through the test-only gate. Why: the root skeleton stays the canonical file
    every skill cites, a kit is added or removed in one line, and every kit's work still runs at its
    place in the startup order (E1, E2, E6, E7, F5, F6, I1). (`root-kits`)
13. **Prove the launch on a release build, on both platforms.** Expo Go shows the app icon instead of
    the splash, and a development build does not apply every splash config property (Expo's SDK 57
    splash-screen docs); only a release build shows the hold, the release and a direction restart as
    people see them.

## Workflow

1. **Read the order**: [references/startup-order.md](references/startup-order.md) (section 1 is the
   table of every step, its file and its owner skill). Find where the change belongs before writing it.
2. **New app or no root yet**: copy the templates (line 1 names each repo path):
   `templates/src/app/_layout.tsx`, `templates/src/features/root-navigator/` (`app-root.tsx`,
   `root-stack.tsx`, `app-stack.tsx`, `hold-splash.ts`, `startup-gate.ts`, `use-startup-ready.ts`,
   `background-flush.ts`, `use-flush-on-background.ts`, `root-kits.tsx`, the helpers each with its
   test), `templates/src/services/root-kits/root-kit.ts` (+ test, the slot types and helpers),
   `templates/src/services/create-root-kits.ts` (the app's registry, empty) and
   `templates/contracts/startup.json`. These files are the canonical root skeleton that other skills
   cite; each of them owns one piece inside it. They expect the composition root
   (architecture-and-boundaries), the error net (error-handling-typed-results), `DirectionGate`
   (rtl-and-direction), the data layer (persistence-and-migrations), `watchSystemA11y` and
   `MotionConfig` (accessibility-as-code), `useScreenAnimation` (motion-and-animation) and the
   navigation theme (design-system-structure); set up a missing one with its skill first. Route groups
   and `Stack.Protected` inside `AppStack` are navigation-and-routing's.
3. **Adding a piece of startup.** An optional kit from another skill (crash reporting, analytics,
   push or local notifications): one entry in `src/services/create-root-kits.ts`, as that skill's
   example shows; the root files stay unchanged (read [references/startup-order.md](references/startup-order.md)
   section 15, the slot contract). An app piece (a store, a client, the session): its creation in
   `startApp` at its row of the order table, its provider at its place in the tree, and its name in
   `appRootOrder` in `contracts/startup.json` if it is new; pass what a kit reads (the settings, the
   session) on to `createRootKits`. Imitate [examples/app-root-with-session.tsx](examples/app-root-with-session.tsx).
4. **Work that is async**: decide with [references/startup-gate-and-deferred-work.md](references/startup-gate-and-deferred-work.md)
   (section 1) whether it blocks the first screen. Deferred is the default; a blocking task returns a
   Result, goes into `createStartupGate({ blocking })` and gets a test that drives it resolving, failing
   and hanging.
5. **Splash problems** (hangs, flashes, empty frame): [references/splash-screen.md](references/splash-screen.md)
   (sections 3-4 and the pitfalls table). The splash art itself is icons-app-icon-and-splash's.
6. **A buffered writer** (debounced draft, batch queue): read [references/lifecycle-flush.md](references/lifecycle-flush.md),
   imitate [examples/task-draft-buffer.ts](examples/task-draft-buffer.ts), return its flusher from
   `startApp`.
7. **Test**: `npx jest src/features/root-navigator --ci --maxWorkers=2`, then `npm run typecheck` and
   `npx eslint . --max-warnings 0`.
8. **Run the checker** from the repo root: `node ${CLAUDE_SKILL_DIR}/scripts/check-startup.mjs .`;
   look up a FAIL line's rule in [references/checker-rules.md](references/checker-rules.md); fix and

From zakariaf/ReactNative-Skills, MIT.

More from zakariaf/ReactNative-Skills

Signals

Stars
11
Forks
2
Open issues
0
Last commit (this folder)
Oct 17, 2026 (13 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from zakariaf

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get app-startup-and-bootstrap running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying app-startup-and-bootstrap?

CallGet help
Cite this page

app-startup-and-bootstrap skill. Agent Mart. https://agentmart.dev/skills/zakariaf-app-startup-and-bootstrap (last updated 2026-10-24)