@thierrynakoa/fire-flow 12.2.2 → 13.0.1
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/CREDITS.md +25 -0
- package/DOMINION-FLOW-OVERVIEW.md +182 -38
- package/README.md +399 -690
- package/TROUBLESHOOTING.md +264 -367
- package/agents/fire-debugger.md +54 -0
- package/agents/fire-executor.md +1610 -1033
- package/agents/fire-fact-checker.md +1 -1
- package/agents/fire-planner.md +85 -17
- package/agents/fire-project-researcher.md +1 -1
- package/agents/fire-researcher.md +4 -22
- package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
- package/agents/fire-reviewer.md +552 -499
- package/agents/fire-verifier.md +114 -19
- package/bin/cli.js +18 -101
- package/commands/fire-0-orient.md +2 -2
- package/commands/fire-1a-new.md +50 -15
- package/commands/fire-1c-setup.md +33 -5
- package/commands/fire-1d-discuss.md +87 -1
- package/commands/fire-2-plan.md +556 -527
- package/commands/fire-3-execute.md +2046 -1356
- package/commands/fire-4-verify.md +975 -906
- package/commands/fire-5-handoff.md +46 -5
- package/commands/fire-6-resume.md +2 -31
- package/commands/fire-add-new-skill.md +138 -19
- package/commands/fire-autonomous.md +14 -2
- package/commands/fire-complete-milestone.md +1 -1
- package/commands/fire-cost.md +179 -183
- package/commands/fire-debug.md +1 -6
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +2 -15
- package/commands/fire-map-codebase.md +1 -1
- package/commands/fire-migrate-database.md +548 -0
- package/commands/fire-new-milestone.md +1 -1
- package/commands/fire-reflect.md +1 -2
- package/commands/fire-research.md +142 -21
- package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
- package/commands/fire-scaffold.md +297 -0
- package/commands/fire-search.md +1 -2
- package/commands/fire-security-scan.md +483 -484
- package/commands/fire-setup.md +359 -0
- package/commands/fire-skill.md +770 -0
- package/commands/fire-skills-diff.md +506 -506
- package/commands/fire-skills-history.md +388 -388
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +470 -470
- package/commands/fire-test.md +5 -5
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/commands/fire-validate-skills.md +282 -0
- package/commands/fire-verify-uat.md +9 -177
- package/commands/fire-vuln-scan.md +492 -493
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -25
- package/plugin.json +7 -7
- package/references/autonomy-levels.md +235 -0
- package/references/behavioral-directives.md +95 -3
- package/references/blocker-tracking.md +1 -1
- package/references/circuit-breaker.md +93 -2
- package/references/context-engineering.md +227 -9
- package/references/honesty-protocols.md +70 -1
- package/references/issue-to-pr-pipeline.md +149 -150
- package/references/metrics-and-trends.md +1 -2
- package/references/research-improvements.md +4 -108
- package/references/sdlc-mapping.md +73 -0
- package/references/state-machine.md +151 -0
- package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
- package/skills-library/SKILLS-INDEX.md +57 -558
- package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
- package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
- package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
- package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
- package/skills-library/_general/automation/settings-gui-generator.md +172 -0
- package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
- package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
- package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
- package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
- package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
- package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
- package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
- package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
- package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
- package/skills-library/_general/frontend/color-token-migration.md +112 -0
- package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
- package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
- package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
- package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
- package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
- package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
- package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
- package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
- package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
- package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
- package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
- package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
- package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
- package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
- package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
- package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
- package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
- package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
- package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
- package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
- package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
- package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
- package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
- package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
- package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
- package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
- package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
- package/skills-library/_general/methodology/dead-code-activation.md +123 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
- package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
- package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
- package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
- package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
- package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
- package/skills-library/_general/performance/liveclock-extraction.md +112 -0
- package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
- package/skills-library/_general/performance/use-visible-interval.md +131 -0
- package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
- package/skills-library/_quarantine/README.md +30 -0
- package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
- package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
- package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
- package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
- package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
- package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
- package/skills-library/api-patterns/graphql-content-queries.md +708 -0
- package/skills-library/appointment-scheduler-design.md +423 -0
- package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
- package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
- package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
- package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
- package/skills-library/automation/scheduled-content-publishing.md +608 -0
- package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
- package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
- package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
- package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
- package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
- package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
- package/skills-library/cms-patterns/content-branch-preview.md +515 -0
- package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
- package/skills-library/cms-patterns/mdx-component-content.md +649 -0
- package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
- package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
- package/skills-library/complexity-metrics/complexity-divider.md +707 -0
- package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
- package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
- package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
- package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
- package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
- package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
- package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
- package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
- package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
- package/skills-library/creative-multimedia/og-image-generator.md +635 -0
- package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
- package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
- package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
- package/skills-library/creative-multimedia/svg-generation.md +750 -0
- package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
- package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
- package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
- package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
- package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
- package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
- package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
- package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
- package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
- package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
- package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
- package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
- package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
- package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
- package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
- package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
- package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
- package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
- package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
- package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
- package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
- package/skills-library/database-solutions/content-publishing-states.md +631 -0
- package/skills-library/database-solutions/database-schema-designer.md +522 -0
- package/skills-library/database-solutions/er-diagram-components.md +569 -0
- package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
- package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
- package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
- package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
- package/skills-library/database-solutions/normalization-validator.md +778 -0
- package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
- package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
- package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
- package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
- package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
- package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
- package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
- package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
- package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
- package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
- package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
- package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
- package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
- package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
- package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
- package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
- package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
- package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
- package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
- package/skills-library/deployment-security/SECURITY.md +41 -0
- package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
- package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
- package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
- package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
- package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
- package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
- package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
- package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
- package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
- package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
- package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
- package/skills-library/deployment-security/vps-deployment.md +135 -0
- package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
- package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
- package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
- package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
- package/skills-library/document-processing/md-to-word-converter.md +318 -0
- package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
- package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
- package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
- package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
- package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
- package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
- package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
- package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
- package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
- package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
- package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
- package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
- package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
- package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
- package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
- package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
- package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
- package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
- package/skills-library/ecommerce/inventory-stock-management.md +270 -0
- package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
- package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
- package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
- package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
- package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
- package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
- package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
- package/skills-library/excalidraw-diagrams/LICENSE +21 -0
- package/skills-library/excalidraw-diagrams/README.md +178 -0
- package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
- package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
- package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
- package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
- package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
- package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
- package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
- package/skills-library/infrastructure/observability-designer.md +264 -0
- package/skills-library/infrastructure/performance-profiler.md +621 -0
- package/skills-library/installer-wizard-patterns.md +249 -0
- package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
- package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
- package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
- package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
- package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
- package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
- package/skills-library/integrations/headless-cms-architecture.md +484 -0
- package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
- package/skills-library/integrations/payload-cms-patterns.md +674 -0
- package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
- package/skills-library/integrations/rss-podcast-integration.md +300 -0
- package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/marketing/campaign-analytics.md +97 -0
- package/skills-library/marketing/content-creator.md +105 -0
- package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
- package/skills-library/marketing/social-media-analyzer.md +81 -0
- package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
- package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
- package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
- package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
- package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
- package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
- package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
- package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
- package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
- package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
- package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
- package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
- package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
- package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
- package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
- package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
- package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
- package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
- package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
- package/skills-library/methodology/tech-debt-tracker.md +570 -0
- package/skills-library/parallel-debug/SKILL.md +60 -0
- package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
- package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
- package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
- package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
- package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
- package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
- package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
- package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
- package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
- package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
- package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
- package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
- package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
- package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
- package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
- package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
- package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
- package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
- package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
- package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
- package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
- package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
- package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
- package/skills-library/security/admin-deletion-safety.md +396 -0
- package/skills-library/security/application-vuln-patterns.md +477 -0
- package/skills-library/security/env-secrets-manager.md +686 -0
- package/skills-library/security/secure-ai-application-templates.md +347 -0
- package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
- package/skills-library/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
- package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
- package/skills-library/system-context/SKILL.md +40 -0
- package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
- package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
- package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
- package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
- package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
- package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
- package/skills-library/testing/playwright-api-security-tests.md +202 -0
- package/skills-library/toolbox/SKILL.md +84 -0
- package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
- package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
- package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
- package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
- package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
- package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills-library/wordpress-style-theme-components.md +1526 -0
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/DECISION_LOG.md +0 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +6 -6
- package/templates/skill-api-integration.md +106 -0
- package/templates/skill-architecture-pattern.md +92 -0
- package/templates/skill-debug-pattern.md +98 -0
- package/templates/skill-devops-recipe.md +107 -0
- package/templates/skill-general.md +65 -0
- package/templates/skill-ui-component.md +113 -0
- package/version.json +7 -3
- package/workflows/handoff-session.md +2 -2
- package/workflows/new-project.md +2 -2
- package/workflows/plan-phase.md +1 -1
- package/.claude-plugin/plugin.json +0 -64
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
- package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
- package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
- package/skills-library/specialists/api-architecture/api-designer.md +0 -49
- package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
- package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
- package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
- package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
- package/skills-library/specialists/backend/django-expert.md +0 -52
- package/skills-library/specialists/backend/fastapi-expert.md +0 -52
- package/skills-library/specialists/backend/laravel-specialist.md +0 -52
- package/skills-library/specialists/backend/nestjs-expert.md +0 -51
- package/skills-library/specialists/backend/rails-expert.md +0 -53
- package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
- package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
- package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
- package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
- package/skills-library/specialists/data-ml/rag-architect.md +0 -51
- package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
- package/skills-library/specialists/frontend/angular-architect.md +0 -52
- package/skills-library/specialists/frontend/flutter-expert.md +0 -51
- package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
- package/skills-library/specialists/frontend/react-native-expert.md +0 -50
- package/skills-library/specialists/frontend/vue-expert.md +0 -51
- package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
- package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
- package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
- package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
- package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
- package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
- package/skills-library/specialists/languages/cpp-pro.md +0 -74
- package/skills-library/specialists/languages/csharp-developer.md +0 -69
- package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
- package/skills-library/specialists/languages/golang-pro.md +0 -51
- package/skills-library/specialists/languages/java-architect.md +0 -49
- package/skills-library/specialists/languages/javascript-pro.md +0 -68
- package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
- package/skills-library/specialists/languages/php-pro.md +0 -49
- package/skills-library/specialists/languages/python-pro.md +0 -52
- package/skills-library/specialists/languages/react-expert.md +0 -51
- package/skills-library/specialists/languages/rust-engineer.md +0 -50
- package/skills-library/specialists/languages/sql-pro.md +0 -56
- package/skills-library/specialists/languages/swift-expert.md +0 -69
- package/skills-library/specialists/languages/typescript-pro.md +0 -51
- package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
- package/skills-library/specialists/platform/embedded-systems.md +0 -53
- package/skills-library/specialists/platform/game-developer.md +0 -53
- package/skills-library/specialists/platform/salesforce-developer.md +0 -53
- package/skills-library/specialists/platform/shopify-expert.md +0 -49
- package/skills-library/specialists/platform/wordpress-pro.md +0 -49
- package/skills-library/specialists/quality/browser-use-expert.md +0 -210
- package/skills-library/specialists/quality/code-documenter.md +0 -51
- package/skills-library/specialists/quality/code-reviewer.md +0 -67
- package/skills-library/specialists/quality/debugging-wizard.md +0 -51
- package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
- package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
- package/skills-library/specialists/quality/playwright-expert.md +0 -65
- package/skills-library/specialists/quality/spec-miner.md +0 -56
- package/skills-library/specialists/quality/test-master.md +0 -65
- package/skills-library/specialists/security/secure-code-guardian.md +0 -55
- package/skills-library/specialists/security/security-reviewer.md +0 -53
- package/skills-library/specialists/workflow/architecture-designer.md +0 -53
- package/skills-library/specialists/workflow/cli-developer.md +0 -70
- package/skills-library/specialists/workflow/feature-forge.md +0 -65
- package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
- package/skills-library/specialists/workflow/the-fool.md +0 -62
- /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
|
@@ -0,0 +1,2011 @@
|
|
|
1
|
+
# React Production Deployment: Web + Desktop (Windows & Mac) Complete Guide
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [Overview](#overview)
|
|
6
|
+
2. [Deployment Strategy Comparison](#deployment-strategy-comparison)
|
|
7
|
+
3. [Web Deployment with Vercel](#web-deployment-with-vercel)
|
|
8
|
+
4. [Desktop App Framework: Electron vs Tauri](#desktop-app-framework-electron-vs-tauri)
|
|
9
|
+
5. [Building Desktop Apps with Electron + React](#building-desktop-apps-with-electron--react)
|
|
10
|
+
6. [Creating Installers (Windows .exe, Mac .dmg)](#creating-installers-windows-exe-mac-dmg)
|
|
11
|
+
7. [Code Signing for Windows & Mac](#code-signing-for-windows--mac)
|
|
12
|
+
8. [Auto-Update Mechanism](#auto-update-mechanism)
|
|
13
|
+
9. [App Store Distribution](#app-store-distribution)
|
|
14
|
+
10. [Security Best Practices (API Keys)](#security-best-practices-api-keys)
|
|
15
|
+
11. [Hybrid Deployment (Web + Desktop)](#hybrid-deployment-web--desktop)
|
|
16
|
+
12. [Complete Implementation for Budget App](#complete-implementation-for-budget-app)
|
|
17
|
+
13. [Resources](#resources)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
This guide covers deploying your React application in **three ways**:
|
|
24
|
+
|
|
25
|
+
1. **Web App (Vercel)** - Cloud-hosted, accessible via browser
|
|
26
|
+
2. **Windows Desktop App** - Downloadable .exe installer
|
|
27
|
+
3. **Mac Desktop App** - Downloadable .dmg installer
|
|
28
|
+
|
|
29
|
+
### Why Multi-Platform Deployment?
|
|
30
|
+
|
|
31
|
+
**Web App Benefits:**
|
|
32
|
+
- ✅ Zero installation required
|
|
33
|
+
- ✅ Instant updates (no downloads)
|
|
34
|
+
- ✅ Cross-platform (works on any device)
|
|
35
|
+
- ✅ Easy sharing (just send a URL)
|
|
36
|
+
- ✅ Lower maintenance overhead
|
|
37
|
+
|
|
38
|
+
**Desktop App Benefits:**
|
|
39
|
+
- ✅ Better offline capabilities
|
|
40
|
+
- ✅ Native OS integration (notifications, file system)
|
|
41
|
+
- ✅ Perceived as "more professional"
|
|
42
|
+
- ✅ Can access native APIs
|
|
43
|
+
- ✅ Better performance for heavy operations
|
|
44
|
+
- ✅ More control over user experience
|
|
45
|
+
|
|
46
|
+
**For Your Budget App:**
|
|
47
|
+
Since you need internet for AI and Plaid anyway, a **hybrid approach** makes sense:
|
|
48
|
+
- Deploy web version on Vercel (primary)
|
|
49
|
+
- Offer desktop downloads for users who prefer native apps
|
|
50
|
+
- Share 95%+ of codebase between both
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Deployment Strategy Comparison
|
|
55
|
+
|
|
56
|
+
### Option 1: Web Only (Vercel) ⭐ RECOMMENDED TO START
|
|
57
|
+
|
|
58
|
+
| Aspect | Details |
|
|
59
|
+
|--------|---------|
|
|
60
|
+
| **Cost** | Free tier: Unlimited hobby projects<br>Pro: $20/mo (team features) |
|
|
61
|
+
| **Setup Time** | 5-10 minutes |
|
|
62
|
+
| **Updates** | Instant (push to Git) |
|
|
63
|
+
| **Maintenance** | Minimal (Vercel handles infrastructure) |
|
|
64
|
+
| **User Access** | URL (e.g., https://budget-app.vercel.app) |
|
|
65
|
+
| **Best For** | MVP, testing, most users |
|
|
66
|
+
|
|
67
|
+
**Verdict:** Start here. Add desktop later if users request it.
|
|
68
|
+
|
|
69
|
+
### Option 2: Desktop Only (Electron)
|
|
70
|
+
|
|
71
|
+
| Aspect | Details |
|
|
72
|
+
|--------|---------|
|
|
73
|
+
| **Cost** | Free (self-hosted) + code signing ($99-299/year) |
|
|
74
|
+
| **Setup Time** | 2-4 hours (initial), 1-2 hours per update |
|
|
75
|
+
| **Updates** | Manual download or auto-updater setup |
|
|
76
|
+
| **Maintenance** | High (build for each platform, signing, testing) |
|
|
77
|
+
| **User Access** | Download .exe (Windows) or .dmg (Mac) |
|
|
78
|
+
| **Best For** | Enterprise, offline-first, specific use cases |
|
|
79
|
+
|
|
80
|
+
**Verdict:** Only if you have specific desktop requirements.
|
|
81
|
+
|
|
82
|
+
### Option 3: Hybrid (Web + Desktop) ⭐ BEST LONG-TERM
|
|
83
|
+
|
|
84
|
+
| Aspect | Details |
|
|
85
|
+
|--------|---------|
|
|
86
|
+
| **Cost** | Vercel free + code signing ($99-299/year) |
|
|
87
|
+
| **Setup Time** | 1-2 days (initial) |
|
|
88
|
+
| **Updates** | Web: instant, Desktop: auto-updater |
|
|
89
|
+
| **Maintenance** | Moderate (web is easy, desktop needs releases) |
|
|
90
|
+
| **User Access** | Both URL and downloadable installers |
|
|
91
|
+
| **Best For** | Maximum reach, professional product |
|
|
92
|
+
|
|
93
|
+
**Verdict:** Ideal for mature product with diverse user base.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Web Deployment with Vercel
|
|
98
|
+
|
|
99
|
+
### What is Vercel?
|
|
100
|
+
|
|
101
|
+
Vercel is a cloud platform for deploying React, Next.js, and other frontend frameworks with:
|
|
102
|
+
- **Zero configuration** (auto-detects React)
|
|
103
|
+
- **Global CDN** (fast worldwide)
|
|
104
|
+
- **Automatic HTTPS** (free SSL)
|
|
105
|
+
- **Instant previews** (every Git push gets a preview URL)
|
|
106
|
+
- **Custom domains** (e.g., budgetapp.com)
|
|
107
|
+
|
|
108
|
+
### Step-by-Step: Deploy Your React App
|
|
109
|
+
|
|
110
|
+
#### Prerequisites
|
|
111
|
+
|
|
112
|
+
- Git repository (GitHub, GitLab, or Bitbucket)
|
|
113
|
+
- Vercel account (free at [vercel.com](https://vercel.com))
|
|
114
|
+
|
|
115
|
+
#### Method 1: Git Integration (Recommended)
|
|
116
|
+
|
|
117
|
+
**Step 1: Push your code to Git**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Initialize Git (if not already)
|
|
121
|
+
git init
|
|
122
|
+
git add .
|
|
123
|
+
git commit -m "Initial commit"
|
|
124
|
+
|
|
125
|
+
# Create GitHub repository and push
|
|
126
|
+
git remote add origin https://github.com/yourusername/budget-app.git
|
|
127
|
+
git branch -M main
|
|
128
|
+
git push -u origin main
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Step 2: Connect to Vercel**
|
|
132
|
+
|
|
133
|
+
1. Go to [vercel.com](https://vercel.com) and sign up/login
|
|
134
|
+
2. Click **"Add New"** → **"Project"**
|
|
135
|
+
3. Select your Git provider (GitHub/GitLab/Bitbucket)
|
|
136
|
+
4. Authorize Vercel to access your repositories
|
|
137
|
+
5. Select your React app repository
|
|
138
|
+
|
|
139
|
+
**Step 3: Configure Build Settings**
|
|
140
|
+
|
|
141
|
+
Vercel auto-detects Create React App, but verify:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
Framework Preset: Create React App
|
|
145
|
+
Build Command: npm run build
|
|
146
|
+
Output Directory: build
|
|
147
|
+
Install Command: npm install
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Step 4: Add Environment Variables**
|
|
151
|
+
|
|
152
|
+
Click **"Environment Variables"** and add:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
156
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
157
|
+
OPENAI_API_KEY=sk-proj-...
|
|
158
|
+
PLAID_CLIENT_ID=your-plaid-client-id
|
|
159
|
+
PLAID_SECRET=your-plaid-secret
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
⚠️ **Important:** Only expose client-safe keys with `NEXT_PUBLIC_` prefix. Server-side keys (OpenAI, Plaid secret) should ONLY be used in API routes.
|
|
163
|
+
|
|
164
|
+
**Step 5: Deploy**
|
|
165
|
+
|
|
166
|
+
Click **"Deploy"** - Vercel will:
|
|
167
|
+
1. Clone your repository
|
|
168
|
+
2. Install dependencies
|
|
169
|
+
3. Run `npm run build`
|
|
170
|
+
4. Deploy to global CDN
|
|
171
|
+
5. Assign a URL: `https://your-app-name.vercel.app`
|
|
172
|
+
|
|
173
|
+
**Total time: 2-5 minutes** 🚀
|
|
174
|
+
|
|
175
|
+
#### Method 2: Vercel CLI (Alternative)
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Install Vercel CLI
|
|
179
|
+
npm install -g vercel
|
|
180
|
+
|
|
181
|
+
# Login
|
|
182
|
+
vercel login
|
|
183
|
+
|
|
184
|
+
# Deploy (from project root)
|
|
185
|
+
vercel
|
|
186
|
+
|
|
187
|
+
# Follow prompts, then deploy to production
|
|
188
|
+
vercel --prod
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Post-Deployment Configuration
|
|
192
|
+
|
|
193
|
+
**Add Custom Domain:**
|
|
194
|
+
|
|
195
|
+
1. Go to **Project Settings** → **Domains**
|
|
196
|
+
2. Add your domain (e.g., `budgetapp.com`)
|
|
197
|
+
3. Update DNS records (Vercel provides instructions)
|
|
198
|
+
4. SSL automatically configured ✅
|
|
199
|
+
|
|
200
|
+
**Set Up Continuous Deployment:**
|
|
201
|
+
|
|
202
|
+
Every Git push auto-deploys:
|
|
203
|
+
- `main` branch → Production
|
|
204
|
+
- Feature branches → Preview URLs
|
|
205
|
+
|
|
206
|
+
**Monitor Analytics:**
|
|
207
|
+
|
|
208
|
+
- Go to **Analytics** tab
|
|
209
|
+
- View page views, load times, user locations
|
|
210
|
+
- Free tier: Basic analytics
|
|
211
|
+
- Pro tier: Advanced metrics
|
|
212
|
+
|
|
213
|
+
### Build Optimization
|
|
214
|
+
|
|
215
|
+
**1. Code Splitting (Automatic in CRA)**
|
|
216
|
+
|
|
217
|
+
React automatically splits code, but you can optimize:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// Lazy load heavy components
|
|
221
|
+
import { lazy, Suspense } from 'react'
|
|
222
|
+
|
|
223
|
+
const Form656Wizard = lazy(() => import('./components/Form656Wizard'))
|
|
224
|
+
|
|
225
|
+
function App() {
|
|
226
|
+
return (
|
|
227
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
228
|
+
<Form656Wizard />
|
|
229
|
+
</Suspense>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**2. Image Optimization**
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Use WebP format, compress images
|
|
238
|
+
// Use lazy loading
|
|
239
|
+
<img src="image.webp" loading="lazy" alt="Description" />
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**3. Bundle Analysis**
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Install analyzer
|
|
246
|
+
npm install --save-dev source-map-explorer
|
|
247
|
+
|
|
248
|
+
# Add script to package.json
|
|
249
|
+
"analyze": "source-map-explorer 'build/static/js/*.js'"
|
|
250
|
+
|
|
251
|
+
# Run analysis
|
|
252
|
+
npm run build
|
|
253
|
+
npm run analyze
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Desktop App Framework: Electron vs Tauri
|
|
259
|
+
|
|
260
|
+
### Comparison Table
|
|
261
|
+
|
|
262
|
+
| Feature | Electron | Tauri | Winner |
|
|
263
|
+
|---------|----------|-------|--------|
|
|
264
|
+
| **Bundle Size** | 85MB+ (includes Chromium) | 2.5-10MB (uses OS WebView) | 🏆 Tauri |
|
|
265
|
+
| **RAM Usage** | 100-300MB idle | 30-40MB idle | 🏆 Tauri |
|
|
266
|
+
| **Startup Time** | Slower (Chromium init) | Faster (native WebView) | 🏆 Tauri |
|
|
267
|
+
| **Backend Language** | JavaScript/Node.js | Rust | 🏆 Electron (easier) |
|
|
268
|
+
| **Cross-Platform UI** | Consistent (Chromium) | Varies by OS | 🏆 Electron |
|
|
269
|
+
| **Security** | Moderate (can decompile) | High (compiled binary) | 🏆 Tauri |
|
|
270
|
+
| **React Support** | ✅ Excellent | ✅ Excellent | 🤝 Tie |
|
|
271
|
+
| **Ecosystem** | Massive (mature) | Growing (newer) | 🏆 Electron |
|
|
272
|
+
| **Learning Curve** | Low (JavaScript) | Medium (need Rust) | 🏆 Electron |
|
|
273
|
+
| **Adoption** | VS Code, Slack, Discord | Growing rapidly | 🏆 Electron |
|
|
274
|
+
| **Native APIs** | Good (Node.js) | Excellent (Rust) | 🏆 Tauri |
|
|
275
|
+
| **Auto-Updates** | electron-updater | Built-in | 🤝 Tie |
|
|
276
|
+
|
|
277
|
+
### Which to Choose?
|
|
278
|
+
|
|
279
|
+
**Choose Electron if:**
|
|
280
|
+
- ✅ You want JavaScript everywhere (no Rust learning curve)
|
|
281
|
+
- ✅ You need maximum cross-platform UI consistency
|
|
282
|
+
- ✅ You value mature ecosystem and community
|
|
283
|
+
- ✅ Bundle size is not a primary concern
|
|
284
|
+
- ✅ You're building complex desktop features quickly
|
|
285
|
+
|
|
286
|
+
**Choose Tauri if:**
|
|
287
|
+
- ✅ Bundle size matters (10MB vs 100MB)
|
|
288
|
+
- ✅ You want best performance and security
|
|
289
|
+
- ✅ You're willing to learn Rust basics
|
|
290
|
+
- ✅ You're building a new app from scratch
|
|
291
|
+
- ✅ RAM usage is critical
|
|
292
|
+
|
|
293
|
+
### Recommendation for Budget App
|
|
294
|
+
|
|
295
|
+
**🏆 Electron** - Here's why:
|
|
296
|
+
|
|
297
|
+
1. **JavaScript familiarity** - You're already in React/TypeScript
|
|
298
|
+
2. **Faster development** - No Rust learning curve
|
|
299
|
+
3. **Mature ecosystem** - electron-builder, electron-updater battle-tested
|
|
300
|
+
4. **Your use case** - Budget app needs internet anyway (AI, Plaid), so bundle size less critical
|
|
301
|
+
5. **Consistent UI** - Financial data displays identically on all platforms (important!)
|
|
302
|
+
|
|
303
|
+
**When to reconsider Tauri:**
|
|
304
|
+
- If users complain about 100MB download
|
|
305
|
+
- If you expand to offline-first features
|
|
306
|
+
- If you want to learn Rust (valuable skill!)
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Building Desktop Apps with Electron + React
|
|
311
|
+
|
|
312
|
+
### Architecture Overview
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
Your Budget App
|
|
316
|
+
├── src/ # React app (renderer process)
|
|
317
|
+
│ ├── components/
|
|
318
|
+
│ ├── hooks/
|
|
319
|
+
│ ├── lib/
|
|
320
|
+
│ └── App.tsx
|
|
321
|
+
├── public/ # Public assets
|
|
322
|
+
├── electron/ # Electron main process
|
|
323
|
+
│ ├── main.js # Entry point
|
|
324
|
+
│ ├── preload.js # Security bridge
|
|
325
|
+
│ └── menu.js # App menu
|
|
326
|
+
├── build/ # React build output
|
|
327
|
+
└── dist/ # Electron installers (.exe, .dmg)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Two Processes:**
|
|
331
|
+
1. **Main Process** (Node.js) - Controls app lifecycle, native menus, windows
|
|
332
|
+
2. **Renderer Process** (Chromium) - Your React app runs here
|
|
333
|
+
|
|
334
|
+
### Step-by-Step Setup
|
|
335
|
+
|
|
336
|
+
#### Step 1: Install Electron Dependencies
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# In your existing React project
|
|
340
|
+
npm install --save-dev electron electron-builder electron-is-dev wait-on concurrently cross-env
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Package explanations:**
|
|
344
|
+
- `electron` - Core framework
|
|
345
|
+
- `electron-builder` - Creates installers (.exe, .dmg)
|
|
346
|
+
- `electron-is-dev` - Detects dev vs production
|
|
347
|
+
- `wait-on` - Waits for React dev server before launching Electron
|
|
348
|
+
- `concurrently` - Runs React + Electron simultaneously
|
|
349
|
+
- `cross-env` - Cross-platform environment variables
|
|
350
|
+
|
|
351
|
+
#### Step 2: Create Electron Main Process
|
|
352
|
+
|
|
353
|
+
**Create `public/electron.js`:**
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
const { app, BrowserWindow, Menu } = require('electron');
|
|
357
|
+
const path = require('path');
|
|
358
|
+
const isDev = require('electron-is-dev');
|
|
359
|
+
|
|
360
|
+
let mainWindow;
|
|
361
|
+
|
|
362
|
+
function createWindow() {
|
|
363
|
+
mainWindow = new BrowserWindow({
|
|
364
|
+
width: 1200,
|
|
365
|
+
height: 800,
|
|
366
|
+
minWidth: 800,
|
|
367
|
+
minHeight: 600,
|
|
368
|
+
webPreferences: {
|
|
369
|
+
nodeIntegration: false, // Security: disable Node in renderer
|
|
370
|
+
contextIsolation: true, // Security: isolate contexts
|
|
371
|
+
enableRemoteModule: false, // Security: disable remote
|
|
372
|
+
preload: path.join(__dirname, 'preload.js') // Security bridge
|
|
373
|
+
},
|
|
374
|
+
icon: path.join(__dirname, 'icon.png')
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// Load React app
|
|
378
|
+
const startUrl = isDev
|
|
379
|
+
? 'http://localhost:3000' // Dev server
|
|
380
|
+
: `file://${path.join(__dirname, '../build/index.html')}`; // Production build
|
|
381
|
+
|
|
382
|
+
mainWindow.loadURL(startUrl);
|
|
383
|
+
|
|
384
|
+
// Open DevTools in development
|
|
385
|
+
if (isDev) {
|
|
386
|
+
mainWindow.webContents.openDevTools();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Hide menu bar (optional)
|
|
390
|
+
Menu.setApplicationMenu(null);
|
|
391
|
+
|
|
392
|
+
mainWindow.on('closed', () => {
|
|
393
|
+
mainWindow = null;
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// App lifecycle
|
|
398
|
+
app.whenReady().then(createWindow);
|
|
399
|
+
|
|
400
|
+
app.on('window-all-closed', () => {
|
|
401
|
+
if (process.platform !== 'darwin') {
|
|
402
|
+
app.quit();
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
app.on('activate', () => {
|
|
407
|
+
if (BrowserWindow.getAllWindows().length === 0) {
|
|
408
|
+
createWindow();
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**Create `public/preload.js` (Security Bridge):**
|
|
414
|
+
|
|
415
|
+
```javascript
|
|
416
|
+
const { contextBridge, ipcRenderer } = require('electron');
|
|
417
|
+
|
|
418
|
+
// Expose safe APIs to renderer process
|
|
419
|
+
contextBridge.exposeInMainWorld('electron', {
|
|
420
|
+
// Example: Safe API exposure
|
|
421
|
+
platform: process.platform,
|
|
422
|
+
|
|
423
|
+
// IPC communication (if needed)
|
|
424
|
+
send: (channel, data) => {
|
|
425
|
+
// Whitelist channels
|
|
426
|
+
const validChannels = ['toMain'];
|
|
427
|
+
if (validChannels.includes(channel)) {
|
|
428
|
+
ipcRenderer.send(channel, data);
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
|
|
432
|
+
receive: (channel, func) => {
|
|
433
|
+
const validChannels = ['fromMain'];
|
|
434
|
+
if (validChannels.includes(channel)) {
|
|
435
|
+
ipcRenderer.on(channel, (event, ...args) => func(...args));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### Step 3: Update package.json
|
|
442
|
+
|
|
443
|
+
Add these configurations:
|
|
444
|
+
|
|
445
|
+
```json
|
|
446
|
+
{
|
|
447
|
+
"name": "budget-app",
|
|
448
|
+
"version": "1.0.0",
|
|
449
|
+
"description": "Budget Management & GTA Tax Forms",
|
|
450
|
+
"author": "Your Name",
|
|
451
|
+
"homepage": "./",
|
|
452
|
+
"main": "public/electron.js",
|
|
453
|
+
|
|
454
|
+
"scripts": {
|
|
455
|
+
"start": "react-scripts start",
|
|
456
|
+
"build": "react-scripts build",
|
|
457
|
+
"test": "react-scripts test",
|
|
458
|
+
|
|
459
|
+
"electron:dev": "concurrently \"cross-env BROWSER=none npm start\" \"wait-on http://localhost:3000 && electron .\"",
|
|
460
|
+
"electron:build": "npm run build && electron-builder",
|
|
461
|
+
"electron:build:win": "npm run build && electron-builder --win --x64",
|
|
462
|
+
"electron:build:mac": "npm run build && electron-builder --mac",
|
|
463
|
+
"electron:build:linux": "npm run build && electron-builder --linux"
|
|
464
|
+
},
|
|
465
|
+
|
|
466
|
+
"build": {
|
|
467
|
+
"appId": "com.yourcompany.budgetapp",
|
|
468
|
+
"productName": "Budget App",
|
|
469
|
+
"copyright": "Copyright © 2025 Your Company",
|
|
470
|
+
"directories": {
|
|
471
|
+
"buildResources": "build",
|
|
472
|
+
"output": "dist"
|
|
473
|
+
},
|
|
474
|
+
"files": [
|
|
475
|
+
"build/**/*",
|
|
476
|
+
"node_modules/**/*",
|
|
477
|
+
"package.json"
|
|
478
|
+
],
|
|
479
|
+
"mac": {
|
|
480
|
+
"category": "public.app-category.finance",
|
|
481
|
+
"target": ["dmg", "zip"],
|
|
482
|
+
"icon": "build/icon.icns",
|
|
483
|
+
"hardenedRuntime": true,
|
|
484
|
+
"gatekeeperAssess": false,
|
|
485
|
+
"entitlements": "build/entitlements.mac.plist",
|
|
486
|
+
"entitlementsInherit": "build/entitlements.mac.plist"
|
|
487
|
+
},
|
|
488
|
+
"win": {
|
|
489
|
+
"target": ["nsis", "portable"],
|
|
490
|
+
"icon": "build/icon.ico"
|
|
491
|
+
},
|
|
492
|
+
"linux": {
|
|
493
|
+
"target": ["AppImage", "deb"],
|
|
494
|
+
"category": "Finance",
|
|
495
|
+
"icon": "build/icon.png"
|
|
496
|
+
},
|
|
497
|
+
"nsis": {
|
|
498
|
+
"oneClick": false,
|
|
499
|
+
"allowToChangeInstallationDirectory": true,
|
|
500
|
+
"createDesktopShortcut": true,
|
|
501
|
+
"createStartMenuShortcut": true
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
#### Step 4: Create App Icons
|
|
508
|
+
|
|
509
|
+
You need icons for each platform:
|
|
510
|
+
|
|
511
|
+
**Windows:** `build/icon.ico` (256x256)
|
|
512
|
+
**Mac:** `build/icon.icns` (512x512, use [online converter](https://cloudconvert.com/png-to-icns))
|
|
513
|
+
**Linux:** `build/icon.png` (512x512)
|
|
514
|
+
|
|
515
|
+
**Free icon tools:**
|
|
516
|
+
- [ICNS Creator](https://icnsify.com/) - PNG to ICNS
|
|
517
|
+
- [ICO Converter](https://convertico.com/) - PNG to ICO
|
|
518
|
+
|
|
519
|
+
#### Step 5: Mac Entitlements (Required for Mac)
|
|
520
|
+
|
|
521
|
+
**Create `build/entitlements.mac.plist`:**
|
|
522
|
+
|
|
523
|
+
```xml
|
|
524
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
525
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
526
|
+
<plist version="1.0">
|
|
527
|
+
<dict>
|
|
528
|
+
<key>com.apple.security.cs.allow-jit</key>
|
|
529
|
+
<true/>
|
|
530
|
+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
531
|
+
<true/>
|
|
532
|
+
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
|
533
|
+
<true/>
|
|
534
|
+
<key>com.apple.security.network.client</key>
|
|
535
|
+
<true/>
|
|
536
|
+
<key>com.apple.security.network.server</key>
|
|
537
|
+
<true/>
|
|
538
|
+
</dict>
|
|
539
|
+
</plist>
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
#### Step 6: Test in Development
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
# Run React + Electron together
|
|
546
|
+
npm run electron:dev
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Your app should open in an Electron window!
|
|
550
|
+
|
|
551
|
+
**Verify:**
|
|
552
|
+
- ✅ React app loads
|
|
553
|
+
- ✅ All components render
|
|
554
|
+
- ✅ API calls work (Supabase, AI, etc.)
|
|
555
|
+
- ✅ DevTools accessible (Ctrl+Shift+I / Cmd+Option+I)
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Creating Installers (Windows .exe, Mac .dmg)
|
|
560
|
+
|
|
561
|
+
### Build for Windows (.exe)
|
|
562
|
+
|
|
563
|
+
**On Windows machine:**
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
npm run electron:build:win
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**On Mac/Linux (cross-compile):**
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
# Install Wine (one-time setup)
|
|
573
|
+
# Mac:
|
|
574
|
+
brew install --cask wine-stable
|
|
575
|
+
|
|
576
|
+
# Linux:
|
|
577
|
+
sudo apt-get install wine
|
|
578
|
+
|
|
579
|
+
# Build
|
|
580
|
+
npm run electron:build:win
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
**Output (in `dist/` folder):**
|
|
584
|
+
- `Budget App Setup 1.0.0.exe` (NSIS installer, ~120MB)
|
|
585
|
+
- `Budget App 1.0.0.exe` (Portable version)
|
|
586
|
+
|
|
587
|
+
**Installer Features:**
|
|
588
|
+
- Installation wizard
|
|
589
|
+
- Desktop shortcut option
|
|
590
|
+
- Start menu shortcut
|
|
591
|
+
- Uninstaller
|
|
592
|
+
- Custom installation directory
|
|
593
|
+
|
|
594
|
+
### Build for Mac (.dmg)
|
|
595
|
+
|
|
596
|
+
**On Mac machine (REQUIRED):**
|
|
597
|
+
|
|
598
|
+
```bash
|
|
599
|
+
npm run electron:build:mac
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
⚠️ **Cannot build Mac apps on Windows/Linux** (Apple restriction)
|
|
603
|
+
|
|
604
|
+
**Output (in `dist/` folder):**
|
|
605
|
+
- `Budget App-1.0.0.dmg` (Disk image, ~100MB)
|
|
606
|
+
- `Budget App-1.0.0-mac.zip` (Zipped .app)
|
|
607
|
+
|
|
608
|
+
**DMG Features:**
|
|
609
|
+
- Drag-to-Applications folder
|
|
610
|
+
- Background image (customizable)
|
|
611
|
+
- Volume icon
|
|
612
|
+
|
|
613
|
+
### Build for Linux
|
|
614
|
+
|
|
615
|
+
**On any platform:**
|
|
616
|
+
|
|
617
|
+
```bash
|
|
618
|
+
npm run electron:build:linux
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
**Output:**
|
|
622
|
+
- `Budget App-1.0.0.AppImage` (Universal, ~120MB)
|
|
623
|
+
- `budget-app_1.0.0_amd64.deb` (Debian/Ubuntu)
|
|
624
|
+
|
|
625
|
+
### Build All Platforms at Once
|
|
626
|
+
|
|
627
|
+
```bash
|
|
628
|
+
npm run electron:build
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
⚠️ **Note:** Mac builds still require Mac machine
|
|
632
|
+
|
|
633
|
+
### Customizing the Installer
|
|
634
|
+
|
|
635
|
+
**Custom NSIS installer options:**
|
|
636
|
+
|
|
637
|
+
```json
|
|
638
|
+
"nsis": {
|
|
639
|
+
"oneClick": false, // Allow custom install dir
|
|
640
|
+
"allowToChangeInstallationDirectory": true,
|
|
641
|
+
"installerIcon": "build/installer.ico",
|
|
642
|
+
"uninstallerIcon": "build/uninstaller.ico",
|
|
643
|
+
"installerHeaderIcon": "build/icon.ico",
|
|
644
|
+
"createDesktopShortcut": true,
|
|
645
|
+
"createStartMenuShortcut": true,
|
|
646
|
+
"shortcutName": "Budget App",
|
|
647
|
+
"license": "LICENSE.txt", // Show license during install
|
|
648
|
+
"warningsAsErrors": false
|
|
649
|
+
}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
**Custom DMG background:**
|
|
653
|
+
|
|
654
|
+
```json
|
|
655
|
+
"dmg": {
|
|
656
|
+
"background": "build/dmg-background.png",
|
|
657
|
+
"iconSize": 100,
|
|
658
|
+
"contents": [
|
|
659
|
+
{
|
|
660
|
+
"x": 380,
|
|
661
|
+
"y": 180,
|
|
662
|
+
"type": "link",
|
|
663
|
+
"path": "/Applications"
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"x": 130,
|
|
667
|
+
"y": 180,
|
|
668
|
+
"type": "file"
|
|
669
|
+
}
|
|
670
|
+
],
|
|
671
|
+
"window": {
|
|
672
|
+
"width": 540,
|
|
673
|
+
"height": 380
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
---
|
|
679
|
+
|
|
680
|
+
## Code Signing for Windows & Mac
|
|
681
|
+
|
|
682
|
+
### Why Code Signing?
|
|
683
|
+
|
|
684
|
+
**Without Code Signing:**
|
|
685
|
+
- ❌ Windows SmartScreen: "Windows protected your PC"
|
|
686
|
+
- ❌ Mac Gatekeeper: "App cannot be opened because it is from an unidentified developer"
|
|
687
|
+
- ❌ Users scared to install
|
|
688
|
+
- ❌ Looks unprofessional
|
|
689
|
+
|
|
690
|
+
**With Code Signing:**
|
|
691
|
+
- ✅ No security warnings
|
|
692
|
+
- ✅ Professional appearance
|
|
693
|
+
- ✅ Users trust the installer
|
|
694
|
+
- ✅ Required for auto-updates
|
|
695
|
+
- ✅ Verifies app integrity
|
|
696
|
+
|
|
697
|
+
### Windows Code Signing
|
|
698
|
+
|
|
699
|
+
#### Option 1: Azure Trusted Signing (2025 Recommended) 💰 $8.99/mo
|
|
700
|
+
|
|
701
|
+
**Why:** Cheapest, cloud-based, no hardware needed, eliminates SmartScreen warnings
|
|
702
|
+
|
|
703
|
+
**Requirements:**
|
|
704
|
+
- US/Canada-based organization OR individual
|
|
705
|
+
- 3+ years verifiable business history (for orgs)
|
|
706
|
+
- Azure account
|
|
707
|
+
|
|
708
|
+
**Setup:**
|
|
709
|
+
|
|
710
|
+
1. **Sign up for Azure Trusted Signing:**
|
|
711
|
+
- Go to [Azure Portal](https://portal.azure.com)
|
|
712
|
+
- Search "Trusted Signing"
|
|
713
|
+
- Create account ($8.99/month)
|
|
714
|
+
|
|
715
|
+
2. **Verify identity:**
|
|
716
|
+
- Microsoft validates your business (2-3 days)
|
|
717
|
+
|
|
718
|
+
3. **Configure electron-builder:**
|
|
719
|
+
|
|
720
|
+
```json
|
|
721
|
+
"win": {
|
|
722
|
+
"sign": "./sign-win.js",
|
|
723
|
+
"target": ["nsis"]
|
|
724
|
+
}
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
**Create `sign-win.js`:**
|
|
728
|
+
|
|
729
|
+
```javascript
|
|
730
|
+
const { sign } = require('app-builder-lib/out/codeSign/windowsCodeSign');
|
|
731
|
+
|
|
732
|
+
exports.default = async function(configuration) {
|
|
733
|
+
await sign(configuration, {
|
|
734
|
+
path: configuration.path,
|
|
735
|
+
cert: process.env.AZURE_CERT_PATH,
|
|
736
|
+
password: process.env.AZURE_CERT_PASSWORD
|
|
737
|
+
});
|
|
738
|
+
};
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
4. **Set environment variables:**
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
export AZURE_CERT_PATH=/path/to/cert
|
|
745
|
+
export AZURE_CERT_PASSWORD=your-password
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
**Cost: $8.99/month** (best value 2025)
|
|
749
|
+
|
|
750
|
+
#### Option 2: Traditional EV Certificate 💰 $200-400/year
|
|
751
|
+
|
|
752
|
+
**Providers:**
|
|
753
|
+
- [DigiCert](https://www.digicert.com/) - $299/year
|
|
754
|
+
- [Sectigo](https://sectigo.com/) - $249/year
|
|
755
|
+
- [GlobalSign](https://www.globalsign.com/) - $279/year
|
|
756
|
+
|
|
757
|
+
**Setup:**
|
|
758
|
+
|
|
759
|
+
1. Purchase certificate
|
|
760
|
+
2. Receive USB hardware token (FIPS 140 Level 2)
|
|
761
|
+
3. Configure electron-builder:
|
|
762
|
+
|
|
763
|
+
```json
|
|
764
|
+
"win": {
|
|
765
|
+
"certificateFile": "path/to/cert.p12",
|
|
766
|
+
"certificatePassword": "your-password"
|
|
767
|
+
}
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
Or use environment variables:
|
|
771
|
+
|
|
772
|
+
```bash
|
|
773
|
+
export CSC_LINK=path/to/cert.p12
|
|
774
|
+
export CSC_KEY_PASSWORD=your-password
|
|
775
|
+
npm run electron:build:win
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
**Cost: $249-399/year**
|
|
779
|
+
|
|
780
|
+
### Mac Code Signing
|
|
781
|
+
|
|
782
|
+
**Requirements:**
|
|
783
|
+
- Apple Developer Account ($99/year)
|
|
784
|
+
- Mac computer (cannot sign on Windows/Linux)
|
|
785
|
+
- Xcode Command Line Tools
|
|
786
|
+
|
|
787
|
+
**Setup:**
|
|
788
|
+
|
|
789
|
+
**Step 1: Join Apple Developer Program**
|
|
790
|
+
|
|
791
|
+
Go to [developer.apple.com](https://developer.apple.com) and enroll ($99/year)
|
|
792
|
+
|
|
793
|
+
**Step 2: Create Certificates**
|
|
794
|
+
|
|
795
|
+
1. Open **Xcode**
|
|
796
|
+
2. Go to **Preferences** → **Accounts**
|
|
797
|
+
3. Add your Apple ID
|
|
798
|
+
4. Click **Manage Certificates**
|
|
799
|
+
5. Click **+** → **Developer ID Application**
|
|
800
|
+
6. Certificate automatically created
|
|
801
|
+
|
|
802
|
+
**Step 3: Configure electron-builder**
|
|
803
|
+
|
|
804
|
+
```json
|
|
805
|
+
"mac": {
|
|
806
|
+
"identity": "Developer ID Application: Your Name (TEAM_ID)",
|
|
807
|
+
"hardenedRuntime": true,
|
|
808
|
+
"gatekeeperAssess": false,
|
|
809
|
+
"entitlements": "build/entitlements.mac.plist",
|
|
810
|
+
"entitlementsInherit": "build/entitlements.mac.plist"
|
|
811
|
+
}
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
**Step 4: Notarization (Required for macOS 10.15+)**
|
|
815
|
+
|
|
816
|
+
Apple requires apps to be "notarized" (scanned for malware):
|
|
817
|
+
|
|
818
|
+
```json
|
|
819
|
+
"afterSign": "scripts/notarize.js"
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
**Create `scripts/notarize.js`:**
|
|
823
|
+
|
|
824
|
+
```javascript
|
|
825
|
+
const { notarize } = require('@electron/notarize');
|
|
826
|
+
|
|
827
|
+
exports.default = async function notarizing(context) {
|
|
828
|
+
const { electronPlatformName, appOutDir } = context;
|
|
829
|
+
|
|
830
|
+
if (electronPlatformName !== 'darwin') {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const appName = context.packager.appInfo.productFilename;
|
|
835
|
+
|
|
836
|
+
return await notarize({
|
|
837
|
+
appBundleId: 'com.yourcompany.budgetapp',
|
|
838
|
+
appPath: `${appOutDir}/${appName}.app`,
|
|
839
|
+
appleId: process.env.APPLE_ID,
|
|
840
|
+
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
|
|
841
|
+
teamId: process.env.APPLE_TEAM_ID
|
|
842
|
+
});
|
|
843
|
+
};
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**Install notarization tool:**
|
|
847
|
+
|
|
848
|
+
```bash
|
|
849
|
+
npm install --save-dev @electron/notarize
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
**Set environment variables:**
|
|
853
|
+
|
|
854
|
+
```bash
|
|
855
|
+
export APPLE_ID=your-apple-id@example.com
|
|
856
|
+
export APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx # Generate at appleid.apple.com
|
|
857
|
+
export APPLE_TEAM_ID=YOUR_TEAM_ID
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Build & notarize:**
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
npm run electron:build:mac
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Notarization takes 5-30 minutes (automatic).
|
|
867
|
+
|
|
868
|
+
**Cost: $99/year** (Apple Developer Program)
|
|
869
|
+
|
|
870
|
+
### Cost Summary
|
|
871
|
+
|
|
872
|
+
| Platform | Method | Annual Cost |
|
|
873
|
+
|----------|--------|-------------|
|
|
874
|
+
| **Windows** | Azure Trusted Signing | **$108/year** |
|
|
875
|
+
| **Windows** | Traditional EV Cert | $249-399/year |
|
|
876
|
+
| **Mac** | Apple Developer Program | **$99/year** |
|
|
877
|
+
| **Both** | Azure + Apple | **$207/year** |
|
|
878
|
+
|
|
879
|
+
**Recommendation:** Azure Trusted Signing (Windows) + Apple Developer (Mac) = **$207/year total**
|
|
880
|
+
|
|
881
|
+
---
|
|
882
|
+
|
|
883
|
+
## Auto-Update Mechanism
|
|
884
|
+
|
|
885
|
+
### Why Auto-Updates?
|
|
886
|
+
|
|
887
|
+
**Without Auto-Updates:**
|
|
888
|
+
- ❌ Users stuck on old versions
|
|
889
|
+
- ❌ Must manually download new installers
|
|
890
|
+
- ❌ Security vulnerabilities linger
|
|
891
|
+
- ❌ Can't push bug fixes quickly
|
|
892
|
+
|
|
893
|
+
**With Auto-Updates:**
|
|
894
|
+
- ✅ Users always on latest version
|
|
895
|
+
- ✅ Seamless update experience
|
|
896
|
+
- ✅ Fast bug fixes and security patches
|
|
897
|
+
- ✅ Professional user experience
|
|
898
|
+
|
|
899
|
+
### electron-updater Setup
|
|
900
|
+
|
|
901
|
+
#### Step 1: Install Package
|
|
902
|
+
|
|
903
|
+
```bash
|
|
904
|
+
npm install electron-updater
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
#### Step 2: Update Main Process (`public/electron.js`)
|
|
908
|
+
|
|
909
|
+
```javascript
|
|
910
|
+
const { app, BrowserWindow } = require('electron');
|
|
911
|
+
const { autoUpdater } = require('electron-updater');
|
|
912
|
+
const log = require('electron-log');
|
|
913
|
+
|
|
914
|
+
// Configure logging
|
|
915
|
+
autoUpdater.logger = log;
|
|
916
|
+
autoUpdater.logger.transports.file.level = 'info';
|
|
917
|
+
|
|
918
|
+
let mainWindow;
|
|
919
|
+
|
|
920
|
+
function createWindow() {
|
|
921
|
+
mainWindow = new BrowserWindow({
|
|
922
|
+
width: 1200,
|
|
923
|
+
height: 800,
|
|
924
|
+
webPreferences: {
|
|
925
|
+
nodeIntegration: false,
|
|
926
|
+
contextIsolation: true
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
mainWindow.loadURL(/* ... */);
|
|
931
|
+
|
|
932
|
+
// Check for updates after window loads
|
|
933
|
+
mainWindow.once('ready-to-show', () => {
|
|
934
|
+
autoUpdater.checkForUpdatesAndNotify();
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// Auto-updater events
|
|
939
|
+
autoUpdater.on('checking-for-update', () => {
|
|
940
|
+
log.info('Checking for updates...');
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
autoUpdater.on('update-available', (info) => {
|
|
944
|
+
log.info('Update available:', info);
|
|
945
|
+
mainWindow.webContents.send('update-available', info);
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
autoUpdater.on('update-not-available', (info) => {
|
|
949
|
+
log.info('Update not available');
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
autoUpdater.on('error', (err) => {
|
|
953
|
+
log.error('Error in auto-updater:', err);
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
autoUpdater.on('download-progress', (progressObj) => {
|
|
957
|
+
let message = `Download speed: ${progressObj.bytesPerSecond}`;
|
|
958
|
+
message += ` - Downloaded ${progressObj.percent}%`;
|
|
959
|
+
log.info(message);
|
|
960
|
+
mainWindow.webContents.send('download-progress', progressObj);
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
autoUpdater.on('update-downloaded', (info) => {
|
|
964
|
+
log.info('Update downloaded');
|
|
965
|
+
mainWindow.webContents.send('update-downloaded', info);
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
// App lifecycle
|
|
969
|
+
app.whenReady().then(() => {
|
|
970
|
+
createWindow();
|
|
971
|
+
|
|
972
|
+
// Check for updates every 10 minutes
|
|
973
|
+
setInterval(() => {
|
|
974
|
+
autoUpdater.checkForUpdates();
|
|
975
|
+
}, 600000);
|
|
976
|
+
});
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
#### Step 3: Update Renderer (React Component)
|
|
980
|
+
|
|
981
|
+
```typescript
|
|
982
|
+
// src/components/UpdateNotification.tsx
|
|
983
|
+
import { useEffect, useState } from 'react';
|
|
984
|
+
|
|
985
|
+
export function UpdateNotification() {
|
|
986
|
+
const [updateAvailable, setUpdateAvailable] = useState(false);
|
|
987
|
+
const [downloadProgress, setDownloadProgress] = useState(0);
|
|
988
|
+
const [updateDownloaded, setUpdateDownloaded] = useState(false);
|
|
989
|
+
|
|
990
|
+
useEffect(() => {
|
|
991
|
+
// Check if running in Electron
|
|
992
|
+
if (!window.electron) return;
|
|
993
|
+
|
|
994
|
+
// Listen for update events
|
|
995
|
+
window.electron.receive('update-available', () => {
|
|
996
|
+
setUpdateAvailable(true);
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
window.electron.receive('download-progress', (progress: any) => {
|
|
1000
|
+
setDownloadProgress(Math.round(progress.percent));
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
window.electron.receive('update-downloaded', () => {
|
|
1004
|
+
setUpdateDownloaded(true);
|
|
1005
|
+
});
|
|
1006
|
+
}, []);
|
|
1007
|
+
|
|
1008
|
+
if (updateDownloaded) {
|
|
1009
|
+
return (
|
|
1010
|
+
<div className="update-banner">
|
|
1011
|
+
✅ Update downloaded!
|
|
1012
|
+
<button onClick={() => window.electron.send('restart-app')}>
|
|
1013
|
+
Restart Now
|
|
1014
|
+
</button>
|
|
1015
|
+
</div>
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
if (updateAvailable) {
|
|
1020
|
+
return (
|
|
1021
|
+
<div className="update-banner">
|
|
1022
|
+
📦 Downloading update... {downloadProgress}%
|
|
1023
|
+
</div>
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
```
|
|
1030
|
+
|
|
1031
|
+
#### Step 4: Configure Update Server
|
|
1032
|
+
|
|
1033
|
+
**Option 1: GitHub Releases (Free, Recommended)**
|
|
1034
|
+
|
|
1035
|
+
Add to `package.json`:
|
|
1036
|
+
|
|
1037
|
+
```json
|
|
1038
|
+
"build": {
|
|
1039
|
+
"publish": {
|
|
1040
|
+
"provider": "github",
|
|
1041
|
+
"owner": "yourusername",
|
|
1042
|
+
"repo": "budget-app",
|
|
1043
|
+
"private": false
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
**Create GitHub release:**
|
|
1049
|
+
|
|
1050
|
+
```bash
|
|
1051
|
+
# Build app
|
|
1052
|
+
npm run electron:build
|
|
1053
|
+
|
|
1054
|
+
# Create GitHub release
|
|
1055
|
+
gh release create v1.0.1 \
|
|
1056
|
+
--title "Version 1.0.1" \
|
|
1057
|
+
--notes "Bug fixes and improvements" \
|
|
1058
|
+
./dist/*.exe \
|
|
1059
|
+
./dist/*.dmg \
|
|
1060
|
+
./dist/latest*.yml
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
**Option 2: Amazon S3**
|
|
1064
|
+
|
|
1065
|
+
```json
|
|
1066
|
+
"build": {
|
|
1067
|
+
"publish": {
|
|
1068
|
+
"provider": "s3",
|
|
1069
|
+
"bucket": "your-bucket-name",
|
|
1070
|
+
"region": "us-east-1",
|
|
1071
|
+
"acl": "public-read"
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
**Option 3: Self-Hosted Server**
|
|
1077
|
+
|
|
1078
|
+
```json
|
|
1079
|
+
"build": {
|
|
1080
|
+
"publish": {
|
|
1081
|
+
"provider": "generic",
|
|
1082
|
+
"url": "https://updates.yourapp.com/releases"
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
Host these files:
|
|
1088
|
+
- `latest.yml` (Windows update manifest)
|
|
1089
|
+
- `latest-mac.yml` (Mac update manifest)
|
|
1090
|
+
- `.exe` and `.dmg` installers
|
|
1091
|
+
|
|
1092
|
+
#### Step 5: Publish Update
|
|
1093
|
+
|
|
1094
|
+
```bash
|
|
1095
|
+
# Bump version in package.json
|
|
1096
|
+
npm version patch # 1.0.0 → 1.0.1
|
|
1097
|
+
|
|
1098
|
+
# Build
|
|
1099
|
+
npm run electron:build
|
|
1100
|
+
|
|
1101
|
+
# Publish to GitHub (auto-uploads artifacts)
|
|
1102
|
+
npm run electron:build -- --publish always
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
Users automatically download updates in background!
|
|
1106
|
+
|
|
1107
|
+
### Update Flow
|
|
1108
|
+
|
|
1109
|
+
1. App checks for updates every 10 minutes (configurable)
|
|
1110
|
+
2. Update found → Downloads in background (silent)
|
|
1111
|
+
3. Download complete → Shows notification
|
|
1112
|
+
4. User clicks "Restart" → App updates and restarts
|
|
1113
|
+
5. User on latest version ✅
|
|
1114
|
+
|
|
1115
|
+
**User Experience:** Seamless, minimal interruption
|
|
1116
|
+
|
|
1117
|
+
---
|
|
1118
|
+
|
|
1119
|
+
## App Store Distribution
|
|
1120
|
+
|
|
1121
|
+
### Microsoft Store (Windows)
|
|
1122
|
+
|
|
1123
|
+
**Why Distribute on Microsoft Store?**
|
|
1124
|
+
- ✅ Trusted by Windows users
|
|
1125
|
+
- ✅ Automatic updates (built-in)
|
|
1126
|
+
- ✅ Easier discovery
|
|
1127
|
+
- ✅ Professional credibility
|
|
1128
|
+
|
|
1129
|
+
**Cost:** $19 one-time (individual) or $99 (company)
|
|
1130
|
+
|
|
1131
|
+
#### Setup Process
|
|
1132
|
+
|
|
1133
|
+
**Step 1: Create Microsoft Developer Account**
|
|
1134
|
+
|
|
1135
|
+
1. Go to [partner.microsoft.com/dashboard](https://partner.microsoft.com/dashboard)
|
|
1136
|
+
2. Register ($19 individual / $99 company)
|
|
1137
|
+
3. Verify identity (1-3 days)
|
|
1138
|
+
|
|
1139
|
+
**Step 2: Reserve App Name**
|
|
1140
|
+
|
|
1141
|
+
1. Click **"Apps and games"** → **"New product"**
|
|
1142
|
+
2. Reserve name: "Budget App"
|
|
1143
|
+
3. Note your app's identity values
|
|
1144
|
+
|
|
1145
|
+
**Step 3: Configure electron-builder**
|
|
1146
|
+
|
|
1147
|
+
```json
|
|
1148
|
+
"win": {
|
|
1149
|
+
"target": ["appx"],
|
|
1150
|
+
"appx": {
|
|
1151
|
+
"applicationId": "YourCompany.BudgetApp",
|
|
1152
|
+
"identityName": "12345YourCompany.BudgetApp",
|
|
1153
|
+
"publisher": "CN=12345678-1234-1234-1234-123456789ABC",
|
|
1154
|
+
"publisherDisplayName": "Your Company",
|
|
1155
|
+
"displayName": "Budget App",
|
|
1156
|
+
"backgroundColor": "#FFFFFF",
|
|
1157
|
+
"showNameOnTiles": true,
|
|
1158
|
+
"languages": ["en-US"]
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
Get values from Partner Center → **Product Identity**
|
|
1164
|
+
|
|
1165
|
+
**Step 4: Build APPX Package**
|
|
1166
|
+
|
|
1167
|
+
```bash
|
|
1168
|
+
npm run build
|
|
1169
|
+
electron-builder --win --x64 --appx
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
Output: `dist/Budget App 1.0.0.appx`
|
|
1173
|
+
|
|
1174
|
+
**Step 5: Submit to Microsoft Store**
|
|
1175
|
+
|
|
1176
|
+
1. Go to Partner Center → Your App
|
|
1177
|
+
2. Click **"Start your submission"**
|
|
1178
|
+
3. Upload `.appx` file
|
|
1179
|
+
4. Fill in:
|
|
1180
|
+
- Description
|
|
1181
|
+
- Screenshots (1366x768 minimum)
|
|
1182
|
+
- Age rating
|
|
1183
|
+
- Privacy policy URL
|
|
1184
|
+
5. Submit for certification (1-3 days review)
|
|
1185
|
+
|
|
1186
|
+
**Step 6: Wait for Approval**
|
|
1187
|
+
|
|
1188
|
+
Microsoft reviews for:
|
|
1189
|
+
- Security (malware scan)
|
|
1190
|
+
- Policy compliance
|
|
1191
|
+
- Technical requirements
|
|
1192
|
+
|
|
1193
|
+
Approval typically takes 1-3 days.
|
|
1194
|
+
|
|
1195
|
+
### Mac App Store
|
|
1196
|
+
|
|
1197
|
+
**Why Distribute on Mac App Store?**
|
|
1198
|
+
- ✅ Trusted by Mac users
|
|
1199
|
+
- ✅ Automatic updates
|
|
1200
|
+
- ✅ Easier payment processing (if paid app)
|
|
1201
|
+
- ✅ Sandboxed security
|
|
1202
|
+
|
|
1203
|
+
**Cost:** $99/year (Apple Developer Program)
|
|
1204
|
+
|
|
1205
|
+
#### Setup Process
|
|
1206
|
+
|
|
1207
|
+
**Step 1: Apple Developer Account**
|
|
1208
|
+
|
|
1209
|
+
Already have this from code signing setup.
|
|
1210
|
+
|
|
1211
|
+
**Step 2: Create App ID**
|
|
1212
|
+
|
|
1213
|
+
1. Go to [developer.apple.com](https://developer.apple.com)
|
|
1214
|
+
2. **Certificates, Identifiers & Profiles**
|
|
1215
|
+
3. **Identifiers** → **+** (Add)
|
|
1216
|
+
4. Select **App IDs** → **App**
|
|
1217
|
+
5. Bundle ID: `com.yourcompany.budgetapp`
|
|
1218
|
+
|
|
1219
|
+
**Step 3: Create Mac Installer Certificate**
|
|
1220
|
+
|
|
1221
|
+
1. **Certificates** → **+** (Add)
|
|
1222
|
+
2. Select **Mac Installer Distribution**
|
|
1223
|
+
3. Download certificate
|
|
1224
|
+
|
|
1225
|
+
**Step 4: Create Provisioning Profiles**
|
|
1226
|
+
|
|
1227
|
+
Need two profiles:
|
|
1228
|
+
- **Development** (for testing)
|
|
1229
|
+
- **Distribution** (for App Store)
|
|
1230
|
+
|
|
1231
|
+
1. **Profiles** → **+** (Add)
|
|
1232
|
+
2. Select **Mac App Development** / **Mac App Distribution**
|
|
1233
|
+
3. Select your App ID
|
|
1234
|
+
4. Download profiles
|
|
1235
|
+
|
|
1236
|
+
**Step 5: Configure electron-builder**
|
|
1237
|
+
|
|
1238
|
+
```json
|
|
1239
|
+
"mac": {
|
|
1240
|
+
"category": "public.app-category.finance",
|
|
1241
|
+
"target": ["mas"],
|
|
1242
|
+
"type": "distribution",
|
|
1243
|
+
"entitlements": "build/entitlements.mas.plist",
|
|
1244
|
+
"entitlementsInherit": "build/entitlements.mas.inherit.plist",
|
|
1245
|
+
"provisioningProfile": "path/to/distribution.provisionprofile"
|
|
1246
|
+
}
|
|
1247
|
+
```
|
|
1248
|
+
|
|
1249
|
+
**Create `build/entitlements.mas.plist`:**
|
|
1250
|
+
|
|
1251
|
+
```xml
|
|
1252
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
1253
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
1254
|
+
<plist version="1.0">
|
|
1255
|
+
<dict>
|
|
1256
|
+
<key>com.apple.security.app-sandbox</key>
|
|
1257
|
+
<true/>
|
|
1258
|
+
<key>com.apple.security.network.client</key>
|
|
1259
|
+
<true/>
|
|
1260
|
+
<key>com.apple.security.network.server</key>
|
|
1261
|
+
<true/>
|
|
1262
|
+
<key>com.apple.security.files.user-selected.read-write</key>
|
|
1263
|
+
<true/>
|
|
1264
|
+
</dict>
|
|
1265
|
+
</plist>
|
|
1266
|
+
```
|
|
1267
|
+
|
|
1268
|
+
**Step 6: Build for Mac App Store**
|
|
1269
|
+
|
|
1270
|
+
```bash
|
|
1271
|
+
npm run build
|
|
1272
|
+
electron-builder --mac --mas
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
Output: `dist/mas/Budget App-1.0.0.pkg`
|
|
1276
|
+
|
|
1277
|
+
**Step 7: Upload to App Store Connect**
|
|
1278
|
+
|
|
1279
|
+
1. Go to [appstoreconnect.apple.com](https://appstoreconnect.apple.com)
|
|
1280
|
+
2. **My Apps** → **+** (Add)
|
|
1281
|
+
3. Fill in app information
|
|
1282
|
+
4. Upload `.pkg` using **Transporter** app
|
|
1283
|
+
5. Submit for review
|
|
1284
|
+
|
|
1285
|
+
**Step 8: Wait for Review**
|
|
1286
|
+
|
|
1287
|
+
Apple reviews for:
|
|
1288
|
+
- UI guidelines compliance
|
|
1289
|
+
- Security (sandboxing)
|
|
1290
|
+
- Functionality testing
|
|
1291
|
+
|
|
1292
|
+
Approval typically takes 2-7 days (sometimes longer).
|
|
1293
|
+
|
|
1294
|
+
### Direct Distribution (Recommended Alternative)
|
|
1295
|
+
|
|
1296
|
+
**Why NOT use app stores?**
|
|
1297
|
+
- ❌ Lengthy review process (1-7 days per update)
|
|
1298
|
+
- ❌ 15-30% commission (if charging)
|
|
1299
|
+
- ❌ Strict guidelines (Apple especially)
|
|
1300
|
+
- ❌ Sandboxing restrictions (limited API access)
|
|
1301
|
+
|
|
1302
|
+
**Direct distribution benefits:**
|
|
1303
|
+
- ✅ Instant updates (auto-updater)
|
|
1304
|
+
- ✅ No commissions
|
|
1305
|
+
- ✅ Full API access
|
|
1306
|
+
- ✅ Faster iteration
|
|
1307
|
+
|
|
1308
|
+
**Recommended approach:**
|
|
1309
|
+
1. Deploy web version to Vercel (instant access)
|
|
1310
|
+
2. Offer direct downloads from your website
|
|
1311
|
+
3. Use auto-updater for seamless updates
|
|
1312
|
+
4. Skip app stores unless:
|
|
1313
|
+
- You need store credibility
|
|
1314
|
+
- You're charging money (stores handle payments)
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
## Security Best Practices (API Keys)
|
|
1319
|
+
|
|
1320
|
+
### The Problem
|
|
1321
|
+
|
|
1322
|
+
Desktop apps bundle your entire codebase, including:
|
|
1323
|
+
- ❌ API keys
|
|
1324
|
+
- ❌ Secrets
|
|
1325
|
+
- ❌ Private logic
|
|
1326
|
+
|
|
1327
|
+
Anyone can decompile and extract secrets:
|
|
1328
|
+
|
|
1329
|
+
```bash
|
|
1330
|
+
# Extract resources from .exe
|
|
1331
|
+
npx asar extract app.asar extracted/
|
|
1332
|
+
|
|
1333
|
+
# Now read your .env files!
|
|
1334
|
+
cat extracted/.env
|
|
1335
|
+
```
|
|
1336
|
+
|
|
1337
|
+
### Solution Architecture
|
|
1338
|
+
|
|
1339
|
+
**Never store secrets in desktop app.** Use a backend proxy.
|
|
1340
|
+
|
|
1341
|
+
#### Architecture Diagram
|
|
1342
|
+
|
|
1343
|
+
```
|
|
1344
|
+
Desktop App (Electron)
|
|
1345
|
+
↓ (calls)
|
|
1346
|
+
Your Backend API (Node.js/Supabase Edge Function)
|
|
1347
|
+
↓ (calls)
|
|
1348
|
+
External APIs (OpenAI, Plaid, etc.)
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
### Implementation
|
|
1352
|
+
|
|
1353
|
+
#### Option 1: Supabase Edge Functions (Recommended)
|
|
1354
|
+
|
|
1355
|
+
**Create Edge Function for OpenAI:**
|
|
1356
|
+
|
|
1357
|
+
```typescript
|
|
1358
|
+
// supabase/functions/ai-chat/index.ts
|
|
1359
|
+
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
|
1360
|
+
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
|
|
1361
|
+
|
|
1362
|
+
serve(async (req) => {
|
|
1363
|
+
// Verify user is authenticated
|
|
1364
|
+
const supabaseClient = createClient(
|
|
1365
|
+
Deno.env.get('SUPABASE_URL') ?? '',
|
|
1366
|
+
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
|
|
1367
|
+
{
|
|
1368
|
+
global: {
|
|
1369
|
+
headers: { Authorization: req.headers.get('Authorization')! },
|
|
1370
|
+
},
|
|
1371
|
+
}
|
|
1372
|
+
)
|
|
1373
|
+
|
|
1374
|
+
const {
|
|
1375
|
+
data: { user },
|
|
1376
|
+
} = await supabaseClient.auth.getUser()
|
|
1377
|
+
|
|
1378
|
+
if (!user) {
|
|
1379
|
+
return new Response('Unauthorized', { status: 401 })
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// Call OpenAI with server-side API key
|
|
1383
|
+
const { messages } = await req.json()
|
|
1384
|
+
|
|
1385
|
+
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
1386
|
+
method: 'POST',
|
|
1387
|
+
headers: {
|
|
1388
|
+
'Content-Type': 'application/json',
|
|
1389
|
+
Authorization: `Bearer ${Deno.env.get('OPENAI_API_KEY')}`, // SECRET!
|
|
1390
|
+
},
|
|
1391
|
+
body: JSON.stringify({
|
|
1392
|
+
model: 'gpt-4',
|
|
1393
|
+
messages: messages,
|
|
1394
|
+
}),
|
|
1395
|
+
})
|
|
1396
|
+
|
|
1397
|
+
const data = await response.json()
|
|
1398
|
+
return new Response(JSON.stringify(data), {
|
|
1399
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1400
|
+
})
|
|
1401
|
+
})
|
|
1402
|
+
```
|
|
1403
|
+
|
|
1404
|
+
**Deploy:**
|
|
1405
|
+
|
|
1406
|
+
```bash
|
|
1407
|
+
supabase functions deploy ai-chat --no-verify-jwt
|
|
1408
|
+
supabase secrets set OPENAI_API_KEY=sk-proj-...
|
|
1409
|
+
```
|
|
1410
|
+
|
|
1411
|
+
**Call from Desktop App:**
|
|
1412
|
+
|
|
1413
|
+
```typescript
|
|
1414
|
+
// In your Electron React app
|
|
1415
|
+
const { data, error } = await supabase.functions.invoke('ai-chat', {
|
|
1416
|
+
body: {
|
|
1417
|
+
messages: [
|
|
1418
|
+
{ role: 'user', content: 'Help me with my budget' }
|
|
1419
|
+
]
|
|
1420
|
+
}
|
|
1421
|
+
})
|
|
1422
|
+
```
|
|
1423
|
+
|
|
1424
|
+
**Security:** OpenAI API key NEVER leaves your server ✅
|
|
1425
|
+
|
|
1426
|
+
#### Option 2: Custom Backend (Express/Fastify)
|
|
1427
|
+
|
|
1428
|
+
**Create API server:**
|
|
1429
|
+
|
|
1430
|
+
```typescript
|
|
1431
|
+
// server/index.ts
|
|
1432
|
+
import express from 'express'
|
|
1433
|
+
import OpenAI from 'openai'
|
|
1434
|
+
|
|
1435
|
+
const app = express()
|
|
1436
|
+
const openai = new OpenAI({
|
|
1437
|
+
apiKey: process.env.OPENAI_API_KEY // SECRET!
|
|
1438
|
+
})
|
|
1439
|
+
|
|
1440
|
+
app.post('/api/chat', async (req, res) => {
|
|
1441
|
+
// Verify JWT token
|
|
1442
|
+
const token = req.headers.authorization?.split(' ')[1]
|
|
1443
|
+
// ... verify token with Supabase ...
|
|
1444
|
+
|
|
1445
|
+
const { messages } = req.body
|
|
1446
|
+
|
|
1447
|
+
const completion = await openai.chat.completions.create({
|
|
1448
|
+
model: 'gpt-4',
|
|
1449
|
+
messages: messages,
|
|
1450
|
+
})
|
|
1451
|
+
|
|
1452
|
+
res.json(completion)
|
|
1453
|
+
})
|
|
1454
|
+
|
|
1455
|
+
app.listen(3001, () => {
|
|
1456
|
+
console.log('API server running on port 3001')
|
|
1457
|
+
})
|
|
1458
|
+
```
|
|
1459
|
+
|
|
1460
|
+
**Deploy to:**
|
|
1461
|
+
- Vercel (serverless functions)
|
|
1462
|
+
- Railway (Node.js hosting)
|
|
1463
|
+
- Fly.io (Docker)
|
|
1464
|
+
|
|
1465
|
+
**Call from Desktop App:**
|
|
1466
|
+
|
|
1467
|
+
```typescript
|
|
1468
|
+
const response = await fetch('https://your-api.com/api/chat', {
|
|
1469
|
+
method: 'POST',
|
|
1470
|
+
headers: {
|
|
1471
|
+
'Content-Type': 'application/json',
|
|
1472
|
+
'Authorization': `Bearer ${userToken}`
|
|
1473
|
+
},
|
|
1474
|
+
body: JSON.stringify({ messages })
|
|
1475
|
+
})
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
### Storing User Credentials (Desktop Only)
|
|
1479
|
+
|
|
1480
|
+
For storing **user** credentials (not API keys):
|
|
1481
|
+
|
|
1482
|
+
#### Use node-keytar (OS-Level Encryption)
|
|
1483
|
+
|
|
1484
|
+
```bash
|
|
1485
|
+
npm install keytar
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
**Store password:**
|
|
1489
|
+
|
|
1490
|
+
```javascript
|
|
1491
|
+
// In main process (public/electron.js)
|
|
1492
|
+
const keytar = require('keytar');
|
|
1493
|
+
|
|
1494
|
+
// Save credentials
|
|
1495
|
+
async function saveCredentials(username, password) {
|
|
1496
|
+
await keytar.setPassword('BudgetApp', username, password);
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
// Retrieve credentials
|
|
1500
|
+
async function getCredentials(username) {
|
|
1501
|
+
return await keytar.getPassword('BudgetApp', username);
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
// Delete credentials
|
|
1505
|
+
async function deleteCredentials(username) {
|
|
1506
|
+
await keytar.deletePassword('BudgetApp', username);
|
|
1507
|
+
}
|
|
1508
|
+
```
|
|
1509
|
+
|
|
1510
|
+
**Security:**
|
|
1511
|
+
- ✅ Windows: Credentials Manager
|
|
1512
|
+
- ✅ Mac: Keychain
|
|
1513
|
+
- ✅ Linux: GNOME Keyring
|
|
1514
|
+
- ✅ Encrypted with user's login credentials
|
|
1515
|
+
|
|
1516
|
+
### Environment Variables (Development Only)
|
|
1517
|
+
|
|
1518
|
+
```bash
|
|
1519
|
+
# .env.local (NEVER commit to Git!)
|
|
1520
|
+
VITE_SUPABASE_URL=https://your-project.supabase.co
|
|
1521
|
+
VITE_SUPABASE_ANON_KEY=eyJhbGc... # Public key (safe)
|
|
1522
|
+
```
|
|
1523
|
+
|
|
1524
|
+
**For production builds, load from backend:**
|
|
1525
|
+
|
|
1526
|
+
```typescript
|
|
1527
|
+
// On app startup
|
|
1528
|
+
const config = await fetch('https://your-api.com/config')
|
|
1529
|
+
const { supabaseUrl, supabaseAnonKey } = await config.json()
|
|
1530
|
+
|
|
1531
|
+
const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
|
1532
|
+
```
|
|
1533
|
+
|
|
1534
|
+
### Security Checklist
|
|
1535
|
+
|
|
1536
|
+
- [ ] Never bundle server-side API keys in desktop app
|
|
1537
|
+
- [ ] Use backend proxy for all external API calls
|
|
1538
|
+
- [ ] Store user credentials with node-keytar (OS-level encryption)
|
|
1539
|
+
- [ ] Enable `contextIsolation: true` in BrowserWindow
|
|
1540
|
+
- [ ] Disable `nodeIntegration` in renderer
|
|
1541
|
+
- [ ] Use preload scripts for IPC communication
|
|
1542
|
+
- [ ] Validate all IPC messages (whitelist channels)
|
|
1543
|
+
- [ ] Implement authentication (Supabase Auth)
|
|
1544
|
+
- [ ] Use HTTPS for all API calls
|
|
1545
|
+
- [ ] Code sign your app (prevents tampering)
|
|
1546
|
+
- [ ] Regularly update dependencies (security patches)
|
|
1547
|
+
|
|
1548
|
+
---
|
|
1549
|
+
|
|
1550
|
+
## Hybrid Deployment (Web + Desktop)
|
|
1551
|
+
|
|
1552
|
+
### Strategy: Shared Codebase
|
|
1553
|
+
|
|
1554
|
+
**Goal:** Write code once, deploy everywhere
|
|
1555
|
+
|
|
1556
|
+
```
|
|
1557
|
+
src/
|
|
1558
|
+
├── components/ # Shared React components
|
|
1559
|
+
├── hooks/ # Shared custom hooks
|
|
1560
|
+
├── lib/ # Shared business logic
|
|
1561
|
+
├── types/ # Shared TypeScript types
|
|
1562
|
+
├── App.tsx # Shared app entry
|
|
1563
|
+
└── index.tsx # Platform-specific entry
|
|
1564
|
+
```
|
|
1565
|
+
|
|
1566
|
+
### Platform Detection
|
|
1567
|
+
|
|
1568
|
+
```typescript
|
|
1569
|
+
// src/lib/platform.ts
|
|
1570
|
+
export const isElectron = () => {
|
|
1571
|
+
return window.electron !== undefined
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
export const isWeb = () => {
|
|
1575
|
+
return !isElectron()
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
export const platform = isElectron() ? 'desktop' : 'web'
|
|
1579
|
+
```
|
|
1580
|
+
|
|
1581
|
+
**Use in components:**
|
|
1582
|
+
|
|
1583
|
+
```typescript
|
|
1584
|
+
import { isElectron } from '@/lib/platform'
|
|
1585
|
+
|
|
1586
|
+
export function Header() {
|
|
1587
|
+
return (
|
|
1588
|
+
<header>
|
|
1589
|
+
<h1>Budget App</h1>
|
|
1590
|
+
{isElectron() && (
|
|
1591
|
+
<span className="badge">Desktop</span>
|
|
1592
|
+
)}
|
|
1593
|
+
</header>
|
|
1594
|
+
)
|
|
1595
|
+
}
|
|
1596
|
+
```
|
|
1597
|
+
|
|
1598
|
+
### Platform-Specific Features
|
|
1599
|
+
|
|
1600
|
+
**File system access (desktop only):**
|
|
1601
|
+
|
|
1602
|
+
```typescript
|
|
1603
|
+
// src/lib/export.ts
|
|
1604
|
+
import { isElectron } from './platform'
|
|
1605
|
+
|
|
1606
|
+
export async function exportToFile(data: any) {
|
|
1607
|
+
if (isElectron()) {
|
|
1608
|
+
// Desktop: Native file dialog
|
|
1609
|
+
const filePath = await window.electron.showSaveDialog({
|
|
1610
|
+
defaultPath: 'budget-export.csv',
|
|
1611
|
+
filters: [{ name: 'CSV', extensions: ['csv'] }]
|
|
1612
|
+
})
|
|
1613
|
+
|
|
1614
|
+
if (filePath) {
|
|
1615
|
+
await window.electron.writeFile(filePath, data)
|
|
1616
|
+
}
|
|
1617
|
+
} else {
|
|
1618
|
+
// Web: Download file
|
|
1619
|
+
const blob = new Blob([data], { type: 'text/csv' })
|
|
1620
|
+
const url = URL.createObjectURL(blob)
|
|
1621
|
+
const a = document.createElement('a')
|
|
1622
|
+
a.href = url
|
|
1623
|
+
a.download = 'budget-export.csv'
|
|
1624
|
+
a.click()
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
```
|
|
1628
|
+
|
|
1629
|
+
**Notifications:**
|
|
1630
|
+
|
|
1631
|
+
```typescript
|
|
1632
|
+
export function showNotification(title: string, body: string) {
|
|
1633
|
+
if (isElectron()) {
|
|
1634
|
+
// Desktop: Native notifications
|
|
1635
|
+
window.electron.showNotification({ title, body })
|
|
1636
|
+
} else {
|
|
1637
|
+
// Web: Browser notifications
|
|
1638
|
+
if ('Notification' in window && Notification.permission === 'granted') {
|
|
1639
|
+
new Notification(title, { body })
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
```
|
|
1644
|
+
|
|
1645
|
+
### Development Workflow
|
|
1646
|
+
|
|
1647
|
+
**1. Develop in Browser (Fast)**
|
|
1648
|
+
|
|
1649
|
+
```bash
|
|
1650
|
+
npm run start
|
|
1651
|
+
# Open http://localhost:3000
|
|
1652
|
+
# Hot reload, React DevTools, etc.
|
|
1653
|
+
```
|
|
1654
|
+
|
|
1655
|
+
**2. Test in Electron (Before Release)**
|
|
1656
|
+
|
|
1657
|
+
```bash
|
|
1658
|
+
npm run electron:dev
|
|
1659
|
+
# Opens Electron window
|
|
1660
|
+
# Verify desktop-specific features
|
|
1661
|
+
```
|
|
1662
|
+
|
|
1663
|
+
**3. Deploy Both**
|
|
1664
|
+
|
|
1665
|
+
```bash
|
|
1666
|
+
# Web
|
|
1667
|
+
git push origin main # Auto-deploys to Vercel
|
|
1668
|
+
|
|
1669
|
+
# Desktop
|
|
1670
|
+
npm run electron:build
|
|
1671
|
+
# Upload installers to GitHub Releases
|
|
1672
|
+
```
|
|
1673
|
+
|
|
1674
|
+
### User Choice
|
|
1675
|
+
|
|
1676
|
+
**Landing page:** [budgetapp.com](http://budgetapp.com)
|
|
1677
|
+
|
|
1678
|
+
```html
|
|
1679
|
+
<div class="download-options">
|
|
1680
|
+
<a href="https://app.budgetapp.com" class="btn-primary">
|
|
1681
|
+
🌐 Launch Web App
|
|
1682
|
+
</a>
|
|
1683
|
+
|
|
1684
|
+
<div class="desktop-downloads">
|
|
1685
|
+
<p>Or download for desktop:</p>
|
|
1686
|
+
<a href="/downloads/BudgetApp-Setup-1.0.0.exe" class="btn-secondary">
|
|
1687
|
+
💻 Windows
|
|
1688
|
+
</a>
|
|
1689
|
+
<a href="/downloads/BudgetApp-1.0.0.dmg" class="btn-secondary">
|
|
1690
|
+
🍎 macOS
|
|
1691
|
+
</a>
|
|
1692
|
+
</div>
|
|
1693
|
+
</div>
|
|
1694
|
+
```
|
|
1695
|
+
|
|
1696
|
+
### Shared vs Platform-Specific Code
|
|
1697
|
+
|
|
1698
|
+
**Shared (95%):**
|
|
1699
|
+
- ✅ React components
|
|
1700
|
+
- ✅ Business logic
|
|
1701
|
+
- ✅ API calls (Supabase, backend)
|
|
1702
|
+
- ✅ State management (Zustand/Redux)
|
|
1703
|
+
- ✅ Styling (Tailwind CSS)
|
|
1704
|
+
- ✅ Types (TypeScript)
|
|
1705
|
+
|
|
1706
|
+
**Platform-Specific (5%):**
|
|
1707
|
+
- 🔹 File system operations
|
|
1708
|
+
- 🔹 Native menus (desktop)
|
|
1709
|
+
- 🔹 System tray (desktop)
|
|
1710
|
+
- 🔹 Deep linking (desktop)
|
|
1711
|
+
- 🔹 Auto-updates (desktop)
|
|
1712
|
+
|
|
1713
|
+
### Benefits
|
|
1714
|
+
|
|
1715
|
+
- ✅ Single codebase = easier maintenance
|
|
1716
|
+
- ✅ Features deploy to both simultaneously
|
|
1717
|
+
- ✅ Users choose their preferred platform
|
|
1718
|
+
- ✅ Web for quick access, desktop for "serious" users
|
|
1719
|
+
- ✅ Maximum reach
|
|
1720
|
+
|
|
1721
|
+
---
|
|
1722
|
+
|
|
1723
|
+
## Complete Implementation for Budget App
|
|
1724
|
+
|
|
1725
|
+
### Phase 1: Web Deployment (Week 1)
|
|
1726
|
+
|
|
1727
|
+
**Day 1-2: Prepare for Production**
|
|
1728
|
+
|
|
1729
|
+
```bash
|
|
1730
|
+
# Clean up
|
|
1731
|
+
npm run build
|
|
1732
|
+
npm run typecheck # Fix all TypeScript errors
|
|
1733
|
+
|
|
1734
|
+
# Test production build locally
|
|
1735
|
+
npm install -g serve
|
|
1736
|
+
serve -s build
|
|
1737
|
+
```
|
|
1738
|
+
|
|
1739
|
+
**Day 3: Deploy to Vercel**
|
|
1740
|
+
|
|
1741
|
+
1. Push to GitHub
|
|
1742
|
+
2. Connect to Vercel
|
|
1743
|
+
3. Deploy
|
|
1744
|
+
4. Test: `https://budget-app.vercel.app`
|
|
1745
|
+
|
|
1746
|
+
**Day 4: Custom Domain (Optional)**
|
|
1747
|
+
|
|
1748
|
+
1. Buy domain: `budgetapp.com`
|
|
1749
|
+
2. Add to Vercel
|
|
1750
|
+
3. Update DNS
|
|
1751
|
+
|
|
1752
|
+
**Day 5: Performance Optimization**
|
|
1753
|
+
|
|
1754
|
+
- Lazy load components
|
|
1755
|
+
- Compress images
|
|
1756
|
+
- Analyze bundle size
|
|
1757
|
+
|
|
1758
|
+
**Result:** 🚀 Live web app accessible worldwide
|
|
1759
|
+
|
|
1760
|
+
### Phase 2: Desktop Setup (Week 2)
|
|
1761
|
+
|
|
1762
|
+
**Day 1: Install Electron**
|
|
1763
|
+
|
|
1764
|
+
```bash
|
|
1765
|
+
npm install --save-dev electron electron-builder electron-is-dev
|
|
1766
|
+
```
|
|
1767
|
+
|
|
1768
|
+
**Day 2: Create Main Process**
|
|
1769
|
+
|
|
1770
|
+
- Create `public/electron.js`
|
|
1771
|
+
- Create `public/preload.js`
|
|
1772
|
+
- Update `package.json`
|
|
1773
|
+
|
|
1774
|
+
**Day 3: Test Development**
|
|
1775
|
+
|
|
1776
|
+
```bash
|
|
1777
|
+
npm run electron:dev
|
|
1778
|
+
```
|
|
1779
|
+
|
|
1780
|
+
Verify all features work in Electron.
|
|
1781
|
+
|
|
1782
|
+
**Day 4: Create Icons**
|
|
1783
|
+
|
|
1784
|
+
- Windows: `build/icon.ico`
|
|
1785
|
+
- Mac: `build/icon.icns`
|
|
1786
|
+
- Linux: `build/icon.png`
|
|
1787
|
+
|
|
1788
|
+
**Day 5: Build Installers**
|
|
1789
|
+
|
|
1790
|
+
```bash
|
|
1791
|
+
npm run electron:build
|
|
1792
|
+
```
|
|
1793
|
+
|
|
1794
|
+
Test installers on Windows/Mac.
|
|
1795
|
+
|
|
1796
|
+
**Result:** ✅ Working desktop app installers
|
|
1797
|
+
|
|
1798
|
+
### Phase 3: Code Signing (Week 3)
|
|
1799
|
+
|
|
1800
|
+
**Day 1-2: Windows Code Signing**
|
|
1801
|
+
|
|
1802
|
+
1. Sign up for Azure Trusted Signing ($8.99/mo)
|
|
1803
|
+
2. Verify identity (2-3 days)
|
|
1804
|
+
3. Configure electron-builder
|
|
1805
|
+
4. Build signed .exe
|
|
1806
|
+
|
|
1807
|
+
**Day 3-4: Mac Code Signing**
|
|
1808
|
+
|
|
1809
|
+
1. Join Apple Developer Program ($99/year)
|
|
1810
|
+
2. Create certificates in Xcode
|
|
1811
|
+
3. Configure notarization
|
|
1812
|
+
4. Build signed .dmg
|
|
1813
|
+
|
|
1814
|
+
**Day 5: Verify**
|
|
1815
|
+
|
|
1816
|
+
- Install on fresh Windows/Mac
|
|
1817
|
+
- Verify no security warnings
|
|
1818
|
+
|
|
1819
|
+
**Result:** ✅ Signed installers, professional trust
|
|
1820
|
+
|
|
1821
|
+
### Phase 4: Auto-Updates (Week 4)
|
|
1822
|
+
|
|
1823
|
+
**Day 1-2: Implement electron-updater**
|
|
1824
|
+
|
|
1825
|
+
- Update main process
|
|
1826
|
+
- Add UI notifications
|
|
1827
|
+
- Test update flow locally
|
|
1828
|
+
|
|
1829
|
+
**Day 3: Set Up GitHub Releases**
|
|
1830
|
+
|
|
1831
|
+
```bash
|
|
1832
|
+
gh release create v1.0.0 \
|
|
1833
|
+
--title "Version 1.0.0" \
|
|
1834
|
+
--notes "Initial release" \
|
|
1835
|
+
./dist/*.exe \
|
|
1836
|
+
./dist/*.dmg
|
|
1837
|
+
```
|
|
1838
|
+
|
|
1839
|
+
**Day 4: Test Auto-Update**
|
|
1840
|
+
|
|
1841
|
+
1. Install v1.0.0
|
|
1842
|
+
2. Release v1.0.1
|
|
1843
|
+
3. Verify auto-update works
|
|
1844
|
+
|
|
1845
|
+
**Day 5: Documentation**
|
|
1846
|
+
|
|
1847
|
+
Write update release notes template.
|
|
1848
|
+
|
|
1849
|
+
**Result:** ✅ Automatic updates working
|
|
1850
|
+
|
|
1851
|
+
### Phase 5: Launch (Week 5)
|
|
1852
|
+
|
|
1853
|
+
**Day 1: Final Testing**
|
|
1854
|
+
|
|
1855
|
+
- Test web app (all browsers)
|
|
1856
|
+
- Test Windows installer
|
|
1857
|
+
- Test Mac installer
|
|
1858
|
+
- Test auto-updates
|
|
1859
|
+
|
|
1860
|
+
**Day 2: Create Landing Page**
|
|
1861
|
+
|
|
1862
|
+
```html
|
|
1863
|
+
<!-- index.html -->
|
|
1864
|
+
<h1>Budget App</h1>
|
|
1865
|
+
<p>Manage your finances and GTA tax forms</p>
|
|
1866
|
+
|
|
1867
|
+
<a href="https://app.budgetapp.com">Launch Web App</a>
|
|
1868
|
+
|
|
1869
|
+
<h2>Download for Desktop</h2>
|
|
1870
|
+
<a href="/downloads/BudgetApp-Setup.exe">Windows</a>
|
|
1871
|
+
<a href="/downloads/BudgetApp.dmg">macOS</a>
|
|
1872
|
+
```
|
|
1873
|
+
|
|
1874
|
+
**Day 3: Documentation**
|
|
1875
|
+
|
|
1876
|
+
- User guide
|
|
1877
|
+
- Installation instructions
|
|
1878
|
+
- Troubleshooting
|
|
1879
|
+
|
|
1880
|
+
**Day 4: Announce**
|
|
1881
|
+
|
|
1882
|
+
- Blog post
|
|
1883
|
+
- Social media
|
|
1884
|
+
- Email to beta users
|
|
1885
|
+
|
|
1886
|
+
**Day 5: Monitor**
|
|
1887
|
+
|
|
1888
|
+
- Vercel analytics
|
|
1889
|
+
- Error tracking (Sentry)
|
|
1890
|
+
- User feedback
|
|
1891
|
+
|
|
1892
|
+
**Result:** 🎉 Public launch!
|
|
1893
|
+
|
|
1894
|
+
### Maintenance Schedule
|
|
1895
|
+
|
|
1896
|
+
**Weekly:**
|
|
1897
|
+
- Monitor error logs
|
|
1898
|
+
- Review user feedback
|
|
1899
|
+
- Plan feature updates
|
|
1900
|
+
|
|
1901
|
+
**Monthly:**
|
|
1902
|
+
- Release update (bug fixes + features)
|
|
1903
|
+
- Review analytics
|
|
1904
|
+
- Security audit
|
|
1905
|
+
|
|
1906
|
+
**Quarterly:**
|
|
1907
|
+
- Major feature release
|
|
1908
|
+
- Performance optimization
|
|
1909
|
+
- Dependency updates
|
|
1910
|
+
|
|
1911
|
+
---
|
|
1912
|
+
|
|
1913
|
+
## Resources
|
|
1914
|
+
|
|
1915
|
+
### Official Documentation
|
|
1916
|
+
|
|
1917
|
+
- **Vercel Docs**: https://vercel.com/docs
|
|
1918
|
+
- **Electron Docs**: https://www.electronjs.org/docs
|
|
1919
|
+
- **electron-builder**: https://www.electron.build
|
|
1920
|
+
- **electron-updater**: https://www.electron.build/auto-update
|
|
1921
|
+
|
|
1922
|
+
### Tutorials
|
|
1923
|
+
|
|
1924
|
+
- [FreeCodeCamp: Electron + React + TypeScript](https://www.freecodecamp.org/news/create-desktop-apps-with-electron-react-and-typescript/)
|
|
1925
|
+
- [Building Electron Apps with React (Codemagic)](https://blog.codemagic.io/building-electron-desktop-apps-with-react/)
|
|
1926
|
+
- [Electron Security Best Practices](https://www.electronjs.org/docs/latest/tutorial/security)
|
|
1927
|
+
|
|
1928
|
+
### Tools
|
|
1929
|
+
|
|
1930
|
+
- **Icon Generators**:
|
|
1931
|
+
- [ICNS Creator](https://icnsify.com/) - PNG to .icns (Mac)
|
|
1932
|
+
- [ICO Converter](https://convertico.com/) - PNG to .ico (Windows)
|
|
1933
|
+
- **Code Signing**:
|
|
1934
|
+
- [Azure Trusted Signing](https://azure.microsoft.com/en-us/products/trusted-signing)
|
|
1935
|
+
- [Apple Developer Program](https://developer.apple.com/programs/)
|
|
1936
|
+
- **Distribution**:
|
|
1937
|
+
- [Microsoft Partner Center](https://partner.microsoft.com/dashboard)
|
|
1938
|
+
- [App Store Connect](https://appstoreconnect.apple.com)
|
|
1939
|
+
|
|
1940
|
+
### Example Projects
|
|
1941
|
+
|
|
1942
|
+
- [Electron React Boilerplate](https://github.com/electron-react-boilerplate/electron-react-boilerplate)
|
|
1943
|
+
- [Electron Vite React](https://github.com/electron-vite/electron-vite-react)
|
|
1944
|
+
- [Tauri Examples](https://github.com/tauri-apps/tauri/tree/dev/examples)
|
|
1945
|
+
|
|
1946
|
+
### Community
|
|
1947
|
+
|
|
1948
|
+
- **Discord**:
|
|
1949
|
+
- [Electron Discord](https://discord.com/invite/electronjs)
|
|
1950
|
+
- [Tauri Discord](https://discord.com/invite/tauri)
|
|
1951
|
+
- **Forums**:
|
|
1952
|
+
- [Electron Forum](https://github.com/electron/electron/discussions)
|
|
1953
|
+
- [Stack Overflow - Electron](https://stackoverflow.com/questions/tagged/electron)
|
|
1954
|
+
|
|
1955
|
+
---
|
|
1956
|
+
|
|
1957
|
+
## Summary
|
|
1958
|
+
|
|
1959
|
+
### Key Takeaways
|
|
1960
|
+
|
|
1961
|
+
1. **Start with Web (Vercel)** - Fastest path to users, zero infrastructure
|
|
1962
|
+
2. **Add Desktop When Needed** - Only if users request native app
|
|
1963
|
+
3. **Electron > Tauri** (for your case) - JavaScript familiarity, mature ecosystem
|
|
1964
|
+
4. **Use electron-builder** - Creates installers for all platforms
|
|
1965
|
+
5. **Code Signing is Critical** - $207/year for professional distribution
|
|
1966
|
+
6. **Auto-Updates are Essential** - Keep users on latest version
|
|
1967
|
+
7. **Never Bundle Secrets** - Use backend proxy for API keys
|
|
1968
|
+
8. **Hybrid Deployment** - Share 95%+ codebase between web/desktop
|
|
1969
|
+
|
|
1970
|
+
### Recommended Path for Budget App
|
|
1971
|
+
|
|
1972
|
+
**Phase 1: Web Only (Now)**
|
|
1973
|
+
- Deploy to Vercel (free)
|
|
1974
|
+
- Get users, gather feedback
|
|
1975
|
+
- Iterate quickly
|
|
1976
|
+
|
|
1977
|
+
**Phase 2: Desktop (When Requested)**
|
|
1978
|
+
- Set up Electron
|
|
1979
|
+
- Create installers
|
|
1980
|
+
- Invest in code signing
|
|
1981
|
+
|
|
1982
|
+
**Phase 3: Polish (After Launch)**
|
|
1983
|
+
- Auto-updates
|
|
1984
|
+
- App store distribution (optional)
|
|
1985
|
+
- Performance optimization
|
|
1986
|
+
|
|
1987
|
+
### Cost Breakdown
|
|
1988
|
+
|
|
1989
|
+
| Item | Cost | When |
|
|
1990
|
+
|------|------|------|
|
|
1991
|
+
| **Vercel** | Free | Always |
|
|
1992
|
+
| **Azure Trusted Signing** | $108/year | Desktop launch |
|
|
1993
|
+
| **Apple Developer** | $99/year | Desktop launch |
|
|
1994
|
+
| **Domain name** | $12/year | Custom domain |
|
|
1995
|
+
| **Total Year 1** | **$219** | |
|
|
1996
|
+
| **Total Year 2+** | **$207/year** | |
|
|
1997
|
+
|
|
1998
|
+
**ROI:** Extremely low cost for professional multi-platform distribution.
|
|
1999
|
+
|
|
2000
|
+
### Next Steps
|
|
2001
|
+
|
|
2002
|
+
1. ✅ **Deploy web app to Vercel** (this week)
|
|
2003
|
+
2. ⏸️ **Wait for user feedback** (1-2 months)
|
|
2004
|
+
3. 🔄 **Add desktop if requested** (follow guide above)
|
|
2005
|
+
4. 🚀 **Launch officially** (web + desktop together)
|
|
2006
|
+
|
|
2007
|
+
---
|
|
2008
|
+
|
|
2009
|
+
**Ready to deploy?** 🎯
|
|
2010
|
+
|
|
2011
|
+
Your Budget App can be live on the web in **5 minutes** with Vercel, and desktop installers can be ready in **1-2 weeks** when you're ready!
|