create-disposabl-app 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -22
- package/dist/templates/default/apps/desktop/.oxfmtrc.json +5 -0
- package/dist/templates/default/apps/desktop/.oxlintrc.json +6 -0
- package/dist/templates/default/apps/desktop/README.md +58 -0
- package/dist/templates/default/apps/desktop/forge.config.mts +90 -0
- package/dist/templates/default/apps/desktop/index.html +12 -0
- package/dist/templates/default/apps/desktop/package.json +55 -1
- package/dist/templates/default/apps/desktop/src/declarations.d.ts +2 -0
- package/dist/templates/default/apps/desktop/src/index.css +8 -0
- package/dist/templates/default/apps/desktop/src/main.ts +58 -0
- package/dist/templates/default/apps/desktop/src/preload.ts +3 -0
- package/dist/templates/default/apps/desktop/src/renderer.ts +19 -0
- package/dist/templates/default/apps/desktop/tsconfig.json +14 -0
- package/dist/templates/default/apps/desktop/vite.main.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.preload.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.renderer.config.mts +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/agent-device/SKILL.md +22 -0
- package/dist/templates/default/apps/mobile/.agents/skills/android-emulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/dogfood/SKILL.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/SKILL.md +176 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/app-store-metadata.md +497 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/ios-app-store.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/play-store.md +244 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/testflight.md +62 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/workflows.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/SKILL.md +431 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/SKILL.md +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/metrics.md +98 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/queries.md +444 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/setup.md +529 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/third-party.md +136 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/SKILL.md +237 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/controllers.md +139 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/logs-and-crashes.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/run-your-app.md +256 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/troubleshooting.md +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/SKILL.md +146 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/SKILL.md +99 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/fetch.js +109 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/package.json +6 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/LICENSE +21 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/RECIPES.md +385 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/SKILL.md +274 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/SKILL.md +290 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/references/native-module.md +96 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/SKILL.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-integrated.md +551 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-isolated.md +449 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/comparison.md +63 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/SKILL.md +478 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/SKILL.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/audit.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/SKILL.md +184 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/SKILL.md +425 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/SKILL.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/references/catalog.md +105 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/SKILL.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/compatibility.md +130 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/example.md +212 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/migration-map.md +457 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/SKILL.md +151 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/config-plugin.md +90 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/create-expo-module.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/lifecycle.md +127 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/module-config.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-module.md +286 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-view.md +171 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/SKILL.md +201 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/controls.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/gradients.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/icons.md +232 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/media.md +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/storage.md +121 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/visual-effects.md +198 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/webgpu-three.md +605 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/SKILL.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/references/launch-without-dev-menu.md +24 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/SKILL.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/SKILL.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/form-sheet.md +253 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/route-structure.md +229 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/search.md +248 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/tabs.md +433 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/toolbar-and-headers.md +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/zoom-transitions.md +158 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/SKILL.md +314 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/agents/visual-grader.md +52 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/design-rubric.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/runtime-matrix.md +34 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/check-static.sh +64 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/SKILL.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/drop-in-replacements.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/jetpack-compose.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/swift-ui.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/universal.md +104 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/scripts/list-components.js +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/SKILL.md +150 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-video.md +160 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/native-tabs.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/new-architecture.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-19.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-compiler.md +59 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/SKILL.md +91 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/false-friends.md +119 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/native-patterns.md +39 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/run-as-goal.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/verify-on-device.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/ios-simulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/POWER.md +172 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-app.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-js.md +264 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-barrel-exports.md +250 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-code-splitting.md +255 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-hermes-mmap.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-library-size.md +164 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-native-assets.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-r8-android.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-tree-shaking.md +215 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/devtools-flamegraph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/emerge-xray-ios.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/expo-atlas-treemap.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/fps-drop-graph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/memory-heap-snapshot.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-instruments-templates.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-thread-view.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-animations-reanimated.md +273 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-atomic-state.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-bottomsheet.md +339 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-concurrent-react.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md +223 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-measure-fps.md +178 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-memory-leaks.md +168 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-profile-react.md +138 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-react-compiler.md +261 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-uncontrolled-components.md +219 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-android-16kb-alignment.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-measure-tti.md +221 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-leaks.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-patterns.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-platform-setup.md +112 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-profiling.md +140 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-sdks-over-polyfills.md +192 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-threading-model.md +230 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-turbo-modules.md +210 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-view-flattening.md +180 -0
- package/dist/templates/default/apps/mobile/AGENTS.md +41 -0
- package/dist/templates/default/apps/mobile/app.json +38 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/grid.png +0 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/icon.json +40 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-background.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-foreground.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-monochrome.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/icon.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/splash-icon.png +0 -0
- package/dist/templates/default/apps/mobile/eslint.config.js +10 -0
- package/dist/templates/default/apps/mobile/package.json +43 -1
- package/dist/templates/default/apps/mobile/skills-lock.json +185 -0
- package/dist/templates/default/apps/mobile/src/app/_layout.tsx +5 -0
- package/dist/templates/default/apps/mobile/src/app/index.tsx +17 -0
- package/dist/templates/default/apps/mobile/tsconfig.json +20 -0
- package/dist/templates/default/apps/web/.agents/skills/frontend-design/SKILL.md +71 -0
- package/dist/templates/default/apps/web/.agents/skills/web-design-guidelines/SKILL.md +39 -0
- package/dist/templates/default/apps/web/.env.example +3 -0
- package/dist/templates/default/apps/web/components.json +23 -0
- package/dist/templates/default/apps/web/eslint.config.ts +21 -0
- package/dist/templates/default/apps/web/package.json +39 -1
- package/dist/templates/default/apps/web/public/disposabl-logo.svg +8 -0
- package/dist/templates/default/apps/web/public/favicon.ico +0 -0
- package/dist/templates/default/apps/web/public/manifest.json +25 -0
- package/dist/templates/default/apps/web/skills-lock.json +17 -0
- package/dist/templates/default/apps/web/src/index.css +92 -0
- package/dist/templates/default/apps/web/src/routeTree.gen.ts +282 -0
- package/dist/templates/default/apps/web/src/router/__root.tsx +63 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/dashboard.tsx +9 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/$id.tsx +27 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/index.tsx +33 -0
- package/dist/templates/default/apps/web/src/router/index.tsx +15 -0
- package/dist/templates/default/apps/web/src/router.tsx +20 -0
- package/dist/templates/default/apps/web/tsconfig.json +33 -0
- package/dist/templates/default/apps/web/tsr.config.json +6 -0
- package/dist/templates/default/apps/web/vite.config.ts +65 -0
- package/dist/templates/default/bun.lock +3932 -0
- package/dist/templates/default/bunfig.toml +5 -0
- package/dist/templates/default/disposabl.json +9 -0
- package/dist/templates/default/gitignore +9 -1
- package/dist/templates/default/package.json +29 -4
- package/dist/templates/default/packages/backend/.agents/skills/convex/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-add/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-advisor/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-agent/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-auth/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-authz/SKILL.md +36 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-backup/SKILL.md +33 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-billing/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-cost/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/SKILL.md +325 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/assets/icon.svg +3 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/advanced-patterns.md +146 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/hybrid-components.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/local-components.md +39 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/packaged-components.md +54 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-crons/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-deploy-guard/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-design/SKILL.md +30 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-docs/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-domains/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-env/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-expert/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-explain-app/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-improve-convex-plugin/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-insights/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-launch-readiness/SKILL.md +35 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate-rehearse/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-monitor/SKILL.md +22 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-optimize/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/assets/icon.svg +4 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-reviewer/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-seed/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-self-heal/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-sentinel/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-suggest/SKILL.md +27 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-test/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-verify/SKILL.md +34 -0
- package/dist/templates/default/packages/backend/.prettierignore +4 -0
- package/dist/templates/default/packages/backend/AGENTS.md +18 -0
- package/dist/templates/default/packages/backend/CLAUDE.md +13 -0
- package/dist/templates/default/packages/backend/README.md +33 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/ai-files.state.json +6 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/guidelines.md +286 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.d.ts +66 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.js +23 -0
- package/dist/templates/default/packages/backend/convex/_generated/dataModel.d.ts +60 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.d.ts +164 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.js +101 -0
- package/dist/templates/default/packages/backend/convex/auth.config.ts +14 -0
- package/dist/templates/default/packages/backend/convex/auth.ts +15 -0
- package/dist/templates/default/packages/backend/convex/convex.config.ts +30 -0
- package/dist/templates/default/packages/backend/convex/http.ts +5 -0
- package/dist/templates/default/packages/backend/convex/mcp.ts +8 -0
- package/dist/templates/default/packages/backend/convex/schema.ts +10 -0
- package/dist/templates/default/packages/backend/convex/todos/index.ts +26 -0
- package/dist/templates/default/packages/backend/convex/todos/internal.ts +43 -0
- package/dist/templates/default/packages/backend/convex/tsconfig.json +27 -0
- package/dist/templates/default/packages/backend/convex/users.ts +20 -0
- package/dist/templates/default/packages/backend/eslint.config.mjs +62 -0
- package/dist/templates/default/packages/backend/package.json +36 -0
- package/dist/templates/default/packages/backend/skills-lock.json +203 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/accordion.tsx +77 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert-dialog.tsx +185 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert.tsx +75 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/aspect-ratio.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/attachment.tsx +207 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/avatar.tsx +106 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/badge.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/breadcrumb.tsx +121 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/bubble.tsx +127 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button.tsx +57 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/calendar.tsx +241 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/card.tsx +102 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/carousel.tsx +239 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/chart.tsx +368 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/checkbox.tsx +27 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/code-block.tsx +243 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/collapsible.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/combobox.tsx +300 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/command.tsx +194 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/context-menu.tsx +271 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dialog.tsx +156 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/direction.tsx +4 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/drawer.tsx +224 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dropdown-menu.tsx +269 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/empty.tsx +103 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/field.tsx +236 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/hover-card.tsx +50 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-group.tsx +158 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-otp.tsx +83 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/item.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/kbd.tsx +26 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/label.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/marker.tsx +70 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/menubar.tsx +284 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message-scroller.tsx +128 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message.tsx +91 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/native-select.tsx +64 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/navigation-menu.tsx +170 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/pagination.tsx +133 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/popover.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/progress.tsx +82 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/questionnaire.tsx +330 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/radio-group.tsx +35 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/resizable.tsx +49 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/scroll-area.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/select.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/separator.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sheet.tsx +132 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sidebar.tsx +723 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/skeleton.tsx +13 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/slider.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/spinner.tsx +16 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/switch.tsx +31 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/table.tsx +113 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tabs.tsx +81 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/textarea.tsx +17 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toast.tsx +229 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle.tsx +42 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tooltip.tsx +65 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/trace.tsx +161 -0
- package/dist/templates/default/packages/disposabl-kit/client/hooks/use-mobile.ts +21 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/prerender.ts +89 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/return-to.ts +12 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/utils.ts +1 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/login.tsx +114 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/signUp.tsx +120 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_authenticated/route.tsx +38 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/consent.tsx +137 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/route.tsx +30 -0
- package/dist/templates/default/packages/disposabl-kit/client/styles/globals.css +60 -0
- package/dist/templates/default/packages/disposabl-kit/client/vite.config.ts +32 -0
- package/dist/templates/default/packages/disposabl-kit/components.json +23 -0
- package/dist/templates/default/packages/disposabl-kit/eslint.config.js +21 -0
- package/dist/templates/default/packages/disposabl-kit/package.json +59 -0
- package/dist/templates/default/packages/disposabl-kit/server/http.ts +42 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/functions.ts +46 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/mcp-tools.ts +47 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/platforms.ts +20 -0
- package/dist/templates/default/packages/disposabl-kit/tsconfig.json +17 -0
- package/dist/templates/default/patches/@convex-dev%2Fauth@2.0.0-beta.0.patch +310 -0
- package/dist/templates/default/patches/@convex-dev%2Fstatic-hosting@0.2.1.patch +187 -0
- package/dist/templates/default/tsconfig.json +9 -0
- package/dist/templates/default/turbo.json +51 -0
- package/package.json +1 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Measure TTI (Time to Interactive)
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: tti, startup, performance, markers
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Measure TTI (Time to Interactive)
|
|
8
|
+
|
|
9
|
+
Set up performance markers to measure app startup time and track TTI improvements.
|
|
10
|
+
|
|
11
|
+
## Quick Command
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install react-native-performance
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// Mark when screen is interactive
|
|
19
|
+
import performance from 'react-native-performance';
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
performance.mark('screenInteractive');
|
|
23
|
+
}, []);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
- App startup feels slow
|
|
29
|
+
- Need baseline metrics for optimization
|
|
30
|
+
- Setting up performance monitoring
|
|
31
|
+
- Comparing TTI across releases
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
- `react-native-performance` library (recommended)
|
|
36
|
+
|
|
37
|
+
> **Note**: This skill involves visual timeline diagrams and profiler output. Use `agent-device` for cold-start evidence; install it through the environment's approved/trusted path or ask the user if verification needs it and it is missing. Timeline interpretation may still require exported metrics or human review. Record concrete marker names, durations, device tier, and startup type in text when asking an agent to reason about them.
|
|
38
|
+
|
|
39
|
+
## Understanding TTI
|
|
40
|
+
|
|
41
|
+
**Time to Interactive**: Time from app icon tap to displaying usable content.
|
|
42
|
+
|
|
43
|
+
### Startup Types
|
|
44
|
+
|
|
45
|
+
| Type | Description | Measure? |
|
|
46
|
+
|------|-------------|----------|
|
|
47
|
+
| Cold | App not in memory, full init | ✅ Yes |
|
|
48
|
+
| Warm | Process exists, activity recreated | ❌ Skip |
|
|
49
|
+
| Hot | App in background, resumed | ❌ Skip |
|
|
50
|
+
| Prewarmed (iOS) | iOS pre-initialized app | ❌ Filter out |
|
|
51
|
+
|
|
52
|
+
**Only measure cold starts** for consistent metrics.
|
|
53
|
+
|
|
54
|
+
## React Native Startup Pipeline
|
|
55
|
+
|
|
56
|
+
**Pipeline markers:**
|
|
57
|
+
```
|
|
58
|
+
1. Native Process Init (nativeLaunchStart → nativeLaunchEnd)
|
|
59
|
+
2. Native App Init (appCreationStart → appCreationEnd)
|
|
60
|
+
3. JS Bundle Load (runJSBundleStart → runJSBundleEnd)
|
|
61
|
+
4. RN Root View Render (contentAppeared)
|
|
62
|
+
5. React App Interactive (screenInteractive) ← This is TTI
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Step-by-Step Implementation
|
|
66
|
+
|
|
67
|
+
### 1. Detect Cold Start
|
|
68
|
+
|
|
69
|
+
**iOS (Swift):**
|
|
70
|
+
|
|
71
|
+
```swift
|
|
72
|
+
let isColdStart = ProcessInfo.processInfo.environment["ActivePrewarm"] != "1"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Android (Kotlin):**
|
|
76
|
+
|
|
77
|
+
```kotlin
|
|
78
|
+
class MainApplication : Application() {
|
|
79
|
+
var isColdStart = false
|
|
80
|
+
|
|
81
|
+
override fun onCreate() {
|
|
82
|
+
super.onCreate()
|
|
83
|
+
|
|
84
|
+
var firstPostEnqueued = true
|
|
85
|
+
Handler().post { firstPostEnqueued = false }
|
|
86
|
+
|
|
87
|
+
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
|
88
|
+
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
|
89
|
+
unregisterActivityLifecycleCallbacks(this)
|
|
90
|
+
if (firstPostEnqueued && savedInstanceState == null) {
|
|
91
|
+
isColdStart = true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ... other callbacks
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 2. Check Foreground State
|
|
101
|
+
|
|
102
|
+
Only measure when app starts in foreground.
|
|
103
|
+
|
|
104
|
+
**iOS:**
|
|
105
|
+
|
|
106
|
+
```swift
|
|
107
|
+
var isForegroundProcess = false
|
|
108
|
+
|
|
109
|
+
override func application(_ application: UIApplication,
|
|
110
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
111
|
+
if application.applicationState == .active {
|
|
112
|
+
isForegroundProcess = true
|
|
113
|
+
}
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Android:**
|
|
119
|
+
|
|
120
|
+
```kotlin
|
|
121
|
+
private fun isForegroundProcess(): Boolean {
|
|
122
|
+
val processInfo = ActivityManager.RunningAppProcessInfo()
|
|
123
|
+
ActivityManager.getMyMemoryState(processInfo)
|
|
124
|
+
return processInfo.importance == IMPORTANCE_FOREGROUND
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 3. Set Up Performance Markers
|
|
129
|
+
|
|
130
|
+
Using `react-native-performance`:
|
|
131
|
+
|
|
132
|
+
**Native (iOS):**
|
|
133
|
+
|
|
134
|
+
```swift
|
|
135
|
+
import ReactNativePerformance
|
|
136
|
+
|
|
137
|
+
RNPerformance.sharedInstance().mark("appCreationStart")
|
|
138
|
+
// ... app init ...
|
|
139
|
+
RNPerformance.sharedInstance().mark("appCreationEnd")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Native (Android):**
|
|
143
|
+
|
|
144
|
+
```kotlin
|
|
145
|
+
import com.oblador.performance.RNPerformance
|
|
146
|
+
|
|
147
|
+
RNPerformance.getInstance().mark("appCreationStart")
|
|
148
|
+
// ... app init ...
|
|
149
|
+
RNPerformance.getInstance().mark("appCreationEnd")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 4. Mark Screen Interactive (JavaScript)
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import performance from 'react-native-performance';
|
|
156
|
+
|
|
157
|
+
export default function HomeScreen() {
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
// Mark when meaningful content is displayed
|
|
160
|
+
performance.mark('screenInteractive');
|
|
161
|
+
}, []);
|
|
162
|
+
|
|
163
|
+
return <TabNavigator />;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 5. Collect and Report Metrics
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
import performance from 'react-native-performance';
|
|
171
|
+
|
|
172
|
+
const collectTTIMetrics = () => {
|
|
173
|
+
const entries = performance.getEntriesByType('mark');
|
|
174
|
+
|
|
175
|
+
// Calculate durations
|
|
176
|
+
const metrics = {
|
|
177
|
+
nativeInit: getMarkDuration('nativeLaunchStart', 'nativeLaunchEnd'),
|
|
178
|
+
appCreation: getMarkDuration('appCreationStart', 'appCreationEnd'),
|
|
179
|
+
jsBundleLoad: getMarkDuration('runJSBundleStart', 'runJSBundleEnd'),
|
|
180
|
+
tti: getMarkDuration('nativeLaunchStart', 'screenInteractive'),
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Send to analytics
|
|
184
|
+
analytics.track('app_performance', metrics);
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Built-in Markers
|
|
189
|
+
|
|
190
|
+
`react-native-performance` provides automatic markers:
|
|
191
|
+
|
|
192
|
+
| Marker | Description |
|
|
193
|
+
|--------|-------------|
|
|
194
|
+
| `nativeLaunchStart` | Process start (pre-main) |
|
|
195
|
+
| `nativeLaunchEnd` | Native init complete |
|
|
196
|
+
| `runJSBundleStart` | JS bundle loading starts |
|
|
197
|
+
| `runJSBundleEnd` | JS bundle loaded |
|
|
198
|
+
| `contentAppeared` | RN root view rendered |
|
|
199
|
+
|
|
200
|
+
`nativeLaunchStart` is pre-main and may include iOS prewarming. For prewarm-sensitive analysis, add a custom marker in `main()` and compare it with `nativeLaunchStart`.
|
|
201
|
+
|
|
202
|
+
## Listening to Native Events
|
|
203
|
+
|
|
204
|
+
Use the native marker APIs exposed by the app's React Native version to record JS bundle load and content-appeared milestones. Keep marker names consistent across iOS, Android, analytics, and test scripts.
|
|
205
|
+
|
|
206
|
+
## Target Metrics
|
|
207
|
+
|
|
208
|
+
Treat 2-4s as a broad external heuristic, not a universal target. Define app-specific targets by device tier, startup path, release build, and user/product metrics; optimize only against cold-start measurements filtered for warm, hot, prewarmed, and background launches.
|
|
209
|
+
|
|
210
|
+
## Common Pitfalls
|
|
211
|
+
|
|
212
|
+
- **Including prewarmed starts**: iOS prewarming skews metrics
|
|
213
|
+
- **Measuring warm/hot starts**: Only cold starts are meaningful
|
|
214
|
+
- **Wrong screenInteractive placement**: Mark when truly interactive, not just mounted
|
|
215
|
+
- **Not filtering background launches**: Push notifications can start app in background
|
|
216
|
+
|
|
217
|
+
## Related Skills
|
|
218
|
+
|
|
219
|
+
- [bundle-analyze-js.md](./bundle-analyze-js.md) - Reduce JS bundle load time
|
|
220
|
+
- [native-profiling.md](./native-profiling.md) - Profile native init
|
|
221
|
+
- [bundle-hermes-mmap.md](./bundle-hermes-mmap.md) - Improve Android TTI
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hunt Native Memory Leaks
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
tags: memory, leaks, xcode, instruments, profiler
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Hunt Native Memory Leaks
|
|
8
|
+
|
|
9
|
+
Find native memory leaks using Xcode Leaks and Android Studio Memory Profiler.
|
|
10
|
+
|
|
11
|
+
## Quick Command
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# iOS: Profile with Leaks instrument
|
|
15
|
+
# Xcode → Product → Profile (Cmd+I) → Leaks template
|
|
16
|
+
|
|
17
|
+
# Android: Memory Profiler
|
|
18
|
+
# Android Studio → Run → Profile → Track Memory Consumption
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## When to Use
|
|
22
|
+
|
|
23
|
+
- App memory grows despite JS profiler showing no leaks
|
|
24
|
+
- Native modules suspected of leaking
|
|
25
|
+
- Activity recreation causes memory growth (Android)
|
|
26
|
+
- C++/Swift/Kotlin code under investigation
|
|
27
|
+
|
|
28
|
+
## iOS: Xcode Leaks
|
|
29
|
+
|
|
30
|
+
### Quick Check: Memory Report
|
|
31
|
+
|
|
32
|
+
1. Run app via Xcode
|
|
33
|
+
2. Open **Debug Navigator** (side panel)
|
|
34
|
+
3. Click **Memory**
|
|
35
|
+
4. Watch graph for continuous growth
|
|
36
|
+
|
|
37
|
+
### Deep Analysis: Instruments Leaks
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
1. **Xcode → Product → Profile** (or Cmd+I)
|
|
42
|
+
2. Select **Leaks** template (highlighted with orange triangle icon in the grid)
|
|
43
|
+
3. Click **Choose**
|
|
44
|
+
4. Click **Record** (red circle)
|
|
45
|
+
5. Use the app, perform suspect actions
|
|
46
|
+
6. Stop recording
|
|
47
|
+
|
|
48
|
+
### Analyzing Results
|
|
49
|
+
|
|
50
|
+
**Red markers** = Leaked memory detected
|
|
51
|
+
|
|
52
|
+
Click on leak to see:
|
|
53
|
+
- **Leaked Object**: Type and size
|
|
54
|
+
- **Responsible Library**: Which code leaked
|
|
55
|
+
- **Responsible Frame**: Exact function
|
|
56
|
+
- **Stack Trace**: Full call path (right panel)
|
|
57
|
+
|
|
58
|
+
Open the responsible frame to jump to source when symbols are available.
|
|
59
|
+
|
|
60
|
+
### Common Native Leak: Missing Ownership
|
|
61
|
+
|
|
62
|
+
```cpp
|
|
63
|
+
void createNewStrings() {
|
|
64
|
+
auto str = std::make_unique<std::string>("Hello");
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prefer RAII/smart pointers over raw `new`/`delete` in native module code.
|
|
69
|
+
|
|
70
|
+
## Android: Memory Profiler
|
|
71
|
+
|
|
72
|
+
### Launch Profiler
|
|
73
|
+
|
|
74
|
+
Use Android Studio Memory Profiler and select a memory-consumption recording for the target process.
|
|
75
|
+
|
|
76
|
+
### Recording
|
|
77
|
+
|
|
78
|
+
1. Start the app
|
|
79
|
+
2. Perform actions that might leak
|
|
80
|
+
3. Watch memory graph for growth patterns
|
|
81
|
+
|
|
82
|
+
### Analyzing Allocations
|
|
83
|
+
|
|
84
|
+
Memory profiler shows:
|
|
85
|
+
- **Allocations count**: Objects created
|
|
86
|
+
- **Deallocations count**: Objects freed
|
|
87
|
+
- **Live objects**: Still in memory
|
|
88
|
+
|
|
89
|
+
If allocations greatly exceed deallocations after GC and after repeating the same flow, suspect a leak; confirm via retained objects, references, and lifecycle expectations.
|
|
90
|
+
|
|
91
|
+
### LeakCanary (Android JVM Leaks)
|
|
92
|
+
|
|
93
|
+
Use LeakCanary as a debug-only first line of defense for Android JVM leaks such as retained Activity/Context references, listeners, and coroutines that outlive a module. It does not see JS heap leaks or JSI/C++ Turbo Module leaks and can report React Native framework false positives.
|
|
94
|
+
|
|
95
|
+
### Common Android Leak: Listener Not Removed
|
|
96
|
+
|
|
97
|
+
```kotlin
|
|
98
|
+
// BAD: Leaks MainActivity on config change
|
|
99
|
+
class MainActivity : AppCompatActivity(), Callback {
|
|
100
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
101
|
+
super.onCreate(savedInstanceState)
|
|
102
|
+
EventManager.addListener(this)
|
|
103
|
+
// Never removed!
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// GOOD: Remove listener
|
|
108
|
+
class MainActivity : AppCompatActivity(), Callback {
|
|
109
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
110
|
+
super.onCreate(savedInstanceState)
|
|
111
|
+
EventManager.addListener(this)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
override fun onDestroy() {
|
|
115
|
+
EventManager.removeListener(this)
|
|
116
|
+
super.onDestroy()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Activity Recreation Test
|
|
122
|
+
|
|
123
|
+
Repeat navigation and configuration-change flows, then check whether old activities or module instances are retained after GC.
|
|
124
|
+
|
|
125
|
+
React Native note: RN opts out via `android:configChanges` in manifest, but native code might not.
|
|
126
|
+
|
|
127
|
+
Use `agent-device` to repeat rotation/navigation scenarios, capture snapshots/screenshots, and collect device evidence. If it is missing and device verification is needed, install it through the environment's approved/trusted path or ask the user to install or enable it. Read the `agent-device` skill or CLI help when available before writing exact commands.
|
|
128
|
+
|
|
129
|
+
## Debugging Workflow
|
|
130
|
+
|
|
131
|
+
### iOS
|
|
132
|
+
|
|
133
|
+
1. Profile with Instruments Leaks
|
|
134
|
+
2. Trigger suspect actions repeatedly
|
|
135
|
+
3. Wait for red leak markers
|
|
136
|
+
4. Click to identify responsible frame
|
|
137
|
+
5. Fix and re-test
|
|
138
|
+
|
|
139
|
+
### Android
|
|
140
|
+
|
|
141
|
+
1. Profile memory consumption
|
|
142
|
+
2. Trigger suspect actions (rotate, navigate)
|
|
143
|
+
3. Check allocation/deallocation counts
|
|
144
|
+
4. Look for classes with 0 deallocations
|
|
145
|
+
5. Fix and re-test
|
|
146
|
+
|
|
147
|
+
## Code Fixes by Pattern
|
|
148
|
+
|
|
149
|
+
### Reference Cycle (Swift)
|
|
150
|
+
|
|
151
|
+
```swift
|
|
152
|
+
// BAD
|
|
153
|
+
class Parent {
|
|
154
|
+
var child: Child?
|
|
155
|
+
}
|
|
156
|
+
class Child {
|
|
157
|
+
var parent: Parent? // Strong reference cycle
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// GOOD
|
|
161
|
+
class Parent {
|
|
162
|
+
var child: Child?
|
|
163
|
+
}
|
|
164
|
+
class Child {
|
|
165
|
+
weak var parent: Parent? // Weak breaks cycle
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Missing Cleanup (C++)
|
|
170
|
+
|
|
171
|
+
```cpp
|
|
172
|
+
// BAD
|
|
173
|
+
void process() {
|
|
174
|
+
auto* data = new LargeData();
|
|
175
|
+
if (error) return; // Leak!
|
|
176
|
+
delete data;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// GOOD: RAII with unique_ptr
|
|
180
|
+
void process() {
|
|
181
|
+
auto data = std::make_unique<LargeData>();
|
|
182
|
+
if (error) return; // Automatically cleaned up
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Verification
|
|
187
|
+
|
|
188
|
+
After fixing:
|
|
189
|
+
1. Re-run profiler
|
|
190
|
+
2. Perform same actions
|
|
191
|
+
3. Verify:
|
|
192
|
+
- iOS: No red leak markers
|
|
193
|
+
- Android: Allocations return to a stable baseline after GC and repeated flows
|
|
194
|
+
|
|
195
|
+
## Common Pitfalls
|
|
196
|
+
|
|
197
|
+
- **Testing in debug mode**: Some leaks only appear in release
|
|
198
|
+
- **Not waiting for GC**: Force GC before concluding no leak
|
|
199
|
+
- **Ignoring small leaks**: They add up over time
|
|
200
|
+
- **Missing cleanup in invalidate()**: Turbo Modules need proper cleanup
|
|
201
|
+
|
|
202
|
+
## Related Skills
|
|
203
|
+
|
|
204
|
+
- [native-memory-patterns.md](./native-memory-patterns.md) - Understanding memory patterns
|
|
205
|
+
- [js-memory-leaks.md](./js-memory-leaks.md) - JS-side leaks
|
|
206
|
+
- [native-threading-model.md](./native-threading-model.md) - Module invalidation
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Native Memory Management
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
tags: memory, c++, swift, kotlin, arc, smart-pointers
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Native Memory Management
|
|
8
|
+
|
|
9
|
+
Understand memory management patterns in C++, Swift, and Kotlin for React Native native modules.
|
|
10
|
+
|
|
11
|
+
## Quick Reference
|
|
12
|
+
|
|
13
|
+
| Pattern | Languages | Mechanism |
|
|
14
|
+
|---------|-----------|-----------|
|
|
15
|
+
| Reference Counting | Swift, Obj-C | Count refs, free at zero |
|
|
16
|
+
| Smart pointers | C++ | Ownership encoded in pointer type |
|
|
17
|
+
| Garbage Collection | Kotlin/Java, JavaScript | GC scans and frees unreachable |
|
|
18
|
+
| Manual | C, C++ (raw pointers) | Explicit new/delete |
|
|
19
|
+
|
|
20
|
+
**Key rule**: Prefer stack allocation or `std::unique_ptr` for single ownership; use `std::shared_ptr` only for real shared ownership and `std::weak_ptr` to break cycles. In Swift, use `weak` when the referenced object can disappear first; use `unowned` only when its lifetime is guaranteed to be at least as long.
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
- Writing native modules with manual memory management
|
|
25
|
+
- Debugging native memory leaks
|
|
26
|
+
- Interfacing C++ with Swift/Kotlin
|
|
27
|
+
- Understanding reference counting vs garbage collection
|
|
28
|
+
|
|
29
|
+
## C++ Smart Pointers
|
|
30
|
+
|
|
31
|
+
### `std::unique_ptr` - Single Owner
|
|
32
|
+
|
|
33
|
+
```cpp
|
|
34
|
+
#include <memory>
|
|
35
|
+
|
|
36
|
+
void takeOwnership(std::unique_ptr<std::string> s) {
|
|
37
|
+
std::cout << *s;
|
|
38
|
+
// Automatically deleted when function ends
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
int main() {
|
|
42
|
+
auto str = std::make_unique<std::string>("Hello");
|
|
43
|
+
|
|
44
|
+
// Can only be moved, not copied
|
|
45
|
+
takeOwnership(std::move(str));
|
|
46
|
+
// str is now empty
|
|
47
|
+
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `std::shared_ptr` - Multiple Owners
|
|
53
|
+
|
|
54
|
+
```cpp
|
|
55
|
+
void useShared(std::shared_ptr<std::string> s) {
|
|
56
|
+
std::cout << *s; // Reference count temporarily +1
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void useReference(const std::shared_ptr<std::string>& s) {
|
|
60
|
+
std::cout << *s; // No ref count change (passed by reference)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
int main() {
|
|
64
|
+
auto str = std::make_shared<std::string>("Hello");
|
|
65
|
+
|
|
66
|
+
useShared(str); // Copies pointer, ref count +1
|
|
67
|
+
useReference(str); // No copy, ref count unchanged
|
|
68
|
+
|
|
69
|
+
std::cout << *str; // Still valid
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `std::weak_ptr` - Non-Owning Reference
|
|
75
|
+
|
|
76
|
+
```cpp
|
|
77
|
+
void useWeak(std::weak_ptr<std::string> weak) {
|
|
78
|
+
if (auto shared = weak.lock()) { // Check if still exists
|
|
79
|
+
std::cout << *shared;
|
|
80
|
+
} else {
|
|
81
|
+
std::cout << "Object destroyed";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
int main() {
|
|
86
|
+
auto str = std::make_shared<std::string>("Hello");
|
|
87
|
+
std::weak_ptr<std::string> weak = str; // No ref count increase
|
|
88
|
+
|
|
89
|
+
useWeak(weak); // Works
|
|
90
|
+
str.reset(); // Destroys object
|
|
91
|
+
useWeak(weak); // "Object destroyed"
|
|
92
|
+
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Swift ARC (Automatic Reference Counting)
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
class Person {
|
|
101
|
+
let name: String
|
|
102
|
+
init(name: String) { self.name = name }
|
|
103
|
+
deinit { print("Deallocated") }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
do {
|
|
107
|
+
let person1 = Person(name: "John") // Ref count: 1
|
|
108
|
+
|
|
109
|
+
do {
|
|
110
|
+
let person2 = person1 // Ref count: 2
|
|
111
|
+
} // person2 out of scope, ref count: 1
|
|
112
|
+
|
|
113
|
+
} // person1 out of scope, ref count: 0, "Deallocated"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Breaking Reference Cycles with `weak`
|
|
117
|
+
|
|
118
|
+
```swift
|
|
119
|
+
// BAD: Reference cycle (memory leak)
|
|
120
|
+
class A {
|
|
121
|
+
var b: B?
|
|
122
|
+
}
|
|
123
|
+
class B {
|
|
124
|
+
var a: A? // Strong reference creates cycle
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// GOOD: Use weak to break cycle
|
|
128
|
+
class A {
|
|
129
|
+
var b: B?
|
|
130
|
+
}
|
|
131
|
+
class B {
|
|
132
|
+
weak var a: A? // Weak reference, doesn't prevent deallocation
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Kotlin/Android GC
|
|
137
|
+
|
|
138
|
+
### Weak References for Caches
|
|
139
|
+
|
|
140
|
+
`WeakHashMap` weakens keys, not values. Store `WeakReference` values explicitly when the cached value itself should not be strongly retained. Do not rely on deterministic `System.gc()` behavior in tests.
|
|
141
|
+
|
|
142
|
+
### WeakReference for Callbacks
|
|
143
|
+
|
|
144
|
+
```kotlin
|
|
145
|
+
class DataManager {
|
|
146
|
+
// Weak references to listeners prevent memory leaks
|
|
147
|
+
private val listeners = mutableListOf<WeakReference<DataListener>>()
|
|
148
|
+
|
|
149
|
+
fun addListener(listener: DataListener) {
|
|
150
|
+
listeners.add(WeakReference(listener))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fun notifyListeners(data: String) {
|
|
154
|
+
listeners.forEach { ref ->
|
|
155
|
+
ref.get()?.onDataChanged(data)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Common Memory Leak Sources
|
|
162
|
+
|
|
163
|
+
### 1. Forgetting to Delete (C++)
|
|
164
|
+
|
|
165
|
+
```cpp
|
|
166
|
+
// BAD: Memory leak
|
|
167
|
+
int main() {
|
|
168
|
+
std::string* str = new std::string("Hello");
|
|
169
|
+
// Forgot to delete!
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// GOOD: Use smart pointers or stack allocation
|
|
174
|
+
int main() {
|
|
175
|
+
auto str = std::make_unique<std::string>("Hello");
|
|
176
|
+
// Automatically deleted
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 2. Reference Cycles (Swift/C++)
|
|
182
|
+
|
|
183
|
+
```cpp
|
|
184
|
+
// BAD: Cycle
|
|
185
|
+
class A { std::shared_ptr<B> b; };
|
|
186
|
+
class B { std::shared_ptr<A> a; };
|
|
187
|
+
|
|
188
|
+
// GOOD: Break with weak_ptr
|
|
189
|
+
class A { std::shared_ptr<B> b; };
|
|
190
|
+
class B { std::weak_ptr<A> a; };
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 3. Unremoved Listeners (Kotlin)
|
|
194
|
+
|
|
195
|
+
```kotlin
|
|
196
|
+
// BAD: Listener never removed
|
|
197
|
+
class MyClass {
|
|
198
|
+
private val listener = object : Callback {
|
|
199
|
+
override fun onEvent() { /* ... */ }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
init {
|
|
203
|
+
EventManager.addListener(listener)
|
|
204
|
+
// Never removed!
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// GOOD: Implement cleanup
|
|
209
|
+
class MyClass : AutoCloseable {
|
|
210
|
+
private val listener = object : Callback {
|
|
211
|
+
override fun onEvent() { /* ... */ }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
init {
|
|
215
|
+
EventManager.addListener(listener)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
override fun close() {
|
|
219
|
+
EventManager.removeListener(listener)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Swift `Unmanaged` (Advanced)
|
|
225
|
+
|
|
226
|
+
Use `Unmanaged` only for C interop that explicitly transfers ownership. Match `passRetained` with `takeRetainedValue`, and `passUnretained` with `takeUnretainedValue`.
|
|
227
|
+
|
|
228
|
+
## Best Practices Summary
|
|
229
|
+
|
|
230
|
+
| Language | Best Practice |
|
|
231
|
+
|----------|---------------|
|
|
232
|
+
| C++ | Prefer stack or `unique_ptr`; use `shared_ptr` only for shared ownership |
|
|
233
|
+
| Swift | Use `weak` for delegates and disappearing references; use `unowned` only with guaranteed lifetime |
|
|
234
|
+
| Kotlin | Implement `AutoCloseable`, use `WeakReference` |
|
|
235
|
+
| All | Prefer stack over heap when possible |
|
|
236
|
+
|
|
237
|
+
## Related Skills
|
|
238
|
+
|
|
239
|
+
- [native-memory-leaks.md](./native-memory-leaks.md) - Find leaks with profilers
|
|
240
|
+
- [native-turbo-modules.md](./native-turbo-modules.md) - Build memory-safe modules
|