A demo chat application using the Factory Droid SDK with a React frontend and Express backend.
- Node.js 18+
- Factory CLI installed, and authenticated via login or the
FACTORY_API_KEYenvironment variable
npm installnpm run devThis starts both:
- Backend (Express + WebSocket) on http://localhost:3001
- Frontend (Vite + React) on http://localhost:5173
Open http://localhost:5173 in your browser.
The backend starts a Droid SDK session with the claude-opus-4-7 model and enables the app's configured tools: Execute, Read, Create, Edit, Glob, Grep, LS, and WebSearch.
To verify the configured tools are available for the selected model:
npm run tools:checkThe backend uses the SDK's daemon mode: a single connectDaemon connection is shared across every chat, and one droid daemon process multiplexes all sessions over one WebSocket. Each chat's daemon session id is stored on the chat so a reconnecting session resumes the same agent session (see server/daemon.ts and server/ai-client.ts). This replaced the earlier exec-mode approach, which spawned one droid exec subprocess per chat.
This is an example app for demonstration purposes. For production use, consider:
-
Isolate the Droid SDK - Run the
droid daemonas a separate container/service. This provides better security isolation since the agent can access configured tools such as command execution, file operations, and web search. Daemon mode also lets you target a remote/ephemeral machine per session via themachineoption. -
Persistent storage - Replace the in-memory
ChatStorewith a database. Currently all chats (and thedaemonSessionIdused to resume sessions) are lost on server restart. -
Session persistence across restarts - Resume-by-id works within a running server. To survive a full restart, persist each chat's
daemonSessionIdin the database and resume from it on boot. -
Authentication - Add user authentication and authorization. Currently anyone can access any chat.

