import { useNavigate } from "@tanstack/react-router"; import { ChevronRight, GiftIcon, Sparkles, CheckCircle, AlertCircle, XCircle, Loader2, Settings, } from "lucide-react"; import { providerSettingsRoute } from "@/routes/settings/providers/$provider"; import { settingsRoute } from "@/routes/settings"; import { useState, useEffect, useCallback } from "react"; import { IpcClient } from "@/ipc/ipc_client"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { NodeSystemInfo } from "@/ipc/ipc_types"; import { usePostHog } from "posthog-js/react"; import { useLanguageModelProviders } from "@/hooks/useLanguageModelProviders"; type NodeInstallStep = | "install" | "waiting-for-continue" | "continue-processing" | "finished-checking"; export function SetupBanner() { const posthog = usePostHog(); const navigate = useNavigate(); const { isAnyProviderSetup, isLoading: loading } = useLanguageModelProviders(); const [nodeSystemInfo, setNodeSystemInfo] = useState( null, ); const [nodeCheckError, setNodeCheckError] = useState(false); const [nodeInstallStep, setNodeInstallStep] = useState("install"); const checkNode = useCallback(async () => { try { setNodeCheckError(false); const status = await IpcClient.getInstance().getNodejsStatus(); setNodeSystemInfo(status); } catch (error) { console.error("Failed to check Node.js status:", error); setNodeSystemInfo(null); setNodeCheckError(true); } }, [setNodeSystemInfo, setNodeCheckError]); useEffect(() => { checkNode(); }, [checkNode]); const handleAiSetupClick = () => { posthog.capture("setup-flow:ai-provider-setup:google:click"); navigate({ to: providerSettingsRoute.id, params: { provider: "google" }, }); }; const handleOtherProvidersClick = () => { posthog.capture("setup-flow:ai-provider-setup:other:click"); navigate({ to: settingsRoute.id, }); }; const handleNodeInstallClick = useCallback(async () => { posthog.capture("setup-flow:start-node-install-click"); setNodeInstallStep("waiting-for-continue"); IpcClient.getInstance().openExternalUrl(nodeSystemInfo!.nodeDownloadUrl); }, [nodeSystemInfo, setNodeInstallStep]); const finishNodeInstall = useCallback(async () => { posthog.capture("setup-flow:continue-node-install-click"); setNodeInstallStep("continue-processing"); await IpcClient.getInstance().reloadEnvPath(); await checkNode(); setNodeInstallStep("finished-checking"); }, [checkNode, setNodeInstallStep]); // We only check for node version because pnpm is not required for the app to run. const isNodeSetupComplete = Boolean(nodeSystemInfo?.nodeVersion); const itemsNeedAction: string[] = []; if (!isNodeSetupComplete && nodeSystemInfo) { itemsNeedAction.push("node-setup"); } if (!isAnyProviderSetup() && !loading) { itemsNeedAction.push("ai-setup"); } if (itemsNeedAction.length === 0) { return (

Build your dream app

); } const bannerClasses = cn( "w-full mb-6 border rounded-xl shadow-sm overflow-hidden", "border-zinc-200 dark:border-zinc-700", ); const getStatusIcon = (isComplete: boolean, hasError: boolean = false) => { if (hasError) { return ; } return isComplete ? ( ) : ( ); }; return ( <>

Follow these steps and you'll be ready to start building with Dyad...

{getStatusIcon(isNodeSetupComplete, nodeCheckError)} 1. Install Node.js (App Runtime)
{nodeCheckError && (

Error checking Node.js status. Try installing Node.js.

)} {isNodeSetupComplete ? (

Node.js ({nodeSystemInfo!.nodeVersion}) installed.{" "} {nodeSystemInfo!.pnpmVersion && ( {" "} (optional) pnpm ({nodeSystemInfo!.pnpmVersion}) installed. )}

) : (

Node.js is required to run apps locally.

{nodeInstallStep === "waiting-for-continue" && (

After you have installed Node.js, click "Continue". If the installer didn't work, try{" "} { IpcClient.getInstance().openExternalUrl( "https://nodejs.org/en/download", ); }} > more download options .

)}
)}
{getStatusIcon(isAnyProviderSetup())} 2. Setup AI Model Access

Connect your preferred AI provider to start generating code.

Setup Google Gemini API Key

Use Google Gemini for free

Setup other AI providers

OpenAI, Anthropic, OpenRouter and more

); } function NodeJsHelpCallout() { return ( ); } function NodeInstallButton({ nodeInstallStep, handleNodeInstallClick, finishNodeInstall, }: { nodeInstallStep: NodeInstallStep; handleNodeInstallClick: () => void; finishNodeInstall: () => void; }) { switch (nodeInstallStep) { case "install": return ( ); case "continue-processing": return ( ); case "waiting-for-continue": return ( ); case "finished-checking": return (
Node.js not detected. Closing and re-opening Dyad usually fixes this.
); default: const _exhaustiveCheck: never = nodeInstallStep; } }