desktop

star 0

Use for any desktop app task — planning, designing, implementing pages, components, API routes, and building.

runablehq By runablehq schedule Updated 3/26/2026

name: desktop description: Use for any desktop app task — planning, designing, implementing pages, components, API routes, and building.

Desktop App

Stack

Electron + Vite + React frontend with a standalone Hono API server running on Bun.

Layer Tech Location
Shell Electron packages/app/electron/
Frontend React + Vite + TanStack Query packages/app/src/
API Hono (Bun) packages/api/src/
Database SQLite via bun:sqlite + Drizzle ORM packages/api/src/database/
RPC hono/client packages/app/src/lib/api.ts

Project Structure

.env                        ← all env vars (VITE_ = shared, rest = API-only)
packages/
  api/
    src/
      index.ts              ← Hono app, exports AppType, serves on port 3001
      database/
        index.ts            ← drizzle + bun:sqlite (data/app.db, WAL mode)
        schema.ts           ← Drizzle table definitions
    drizzle/                ← Generated SQL migrations
    drizzle.config.ts       ← Drizzle-kit config
    package.json
  app/
    electron/
      main.ts               ← Electron main process
      preload.ts             ← Preload script
    src/
      main.tsx               ← React entry, QueryClientProvider
      App.tsx                ← Root component
      lib/
        api.ts               ← hc<AppType>(import.meta.env.VITE_API_URL)
      index.css
    index.html
    vite.config.ts           ← aliases @runable/api → ../api
    package.json

Environment Variables

All env vars live in a single .env file at the project root.

Prefix Available to How to access
VITE_ Desktop app (renderer) and API server App: import.meta.env.VITE_* · API: process.env.VITE_*
No prefix API server only process.env.* (Bun auto-loads .env)

The desktop app (Vite/Electron renderer) cannot see non-prefixed vars — Vite strips them at build time. Use this to keep secrets (DB credentials, auth secrets, API keys) out of the frontend.

Example .env:

# API-only (secret, never exposed to renderer)
BETTER_AUTH_SECRET=supersecretkey
DATABASE_URL=data/app.db

# Shared (available to both app and API)
VITE_API_URL=http://localhost:3001

Development

# Run everything (API + Electron app)
bun run dev

# Run individually
bun run dev:api    # Hono server on :3001 with --hot
bun run dev:app    # Vite + Electron

Database

Schema lives in packages/api/src/database/schema.ts. After changing it:

cd packages/api
bun run db:generate    # Generate migration SQL
bun run db:migrate     # Apply migrations
bun run db:studio      # Browse data in Drizzle Studio

The SQLite database file is at packages/api/data/app.db (gitignored).

API Pattern

The API uses Hono with chained routes. The app consumes it via typed RPC client.

Adding a route in packages/api/src/index.ts:

const app = new Hono()
  .use("/*", cors())
  .get("/ping", (c) => c.json({ message: "pong" }))
  .get("/users", async (c) => {
    const result = await database.select().from(users);
    return c.json(result);
  });

export type AppType = typeof app;

Consuming from the app in packages/app/src/:

const res = await api.users.$get();
const data = await res.json();

Building

bun run build          # Vite build only
bun run build:mac      # macOS (dmg + zip, x64 + arm64)
bun run build:win      # Windows (nsis, x64)
bun run build:linux    # Linux (AppImage + deb, x64)
bun run build:all      # All platforms

Feature References

  • Authentication — Better Auth setup for Bun + Electron
  • AI Agent — AI SDK agent with tools and chat UI
  • Payments — Autumn payments and usage tracking
  • Email — Transactional emails with Resend
  • Analytics — Privacy-friendly usage tracking
  • Distribution — Icons, splash screens, store listings
Install via CLI
npx skills add https://github.com/runablehq/sandbox-desktop-template --skill desktop
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator