-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeveloper-web.html
More file actions
191 lines (169 loc) · 9.5 KB
/
Copy pathdeveloper-web.html
File metadata and controls
191 lines (169 loc) · 9.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Developer — Web — StartOne Docs</title>
<meta name="description" content="The full StartOne web boilerplate: media studio, gallery, auth, database, storage. Setup, configuration, architecture, and deployment.">
<link rel="icon" type="image/svg+xml" href="img/mark.svg">
<link rel="icon" href="img/favicon.ico" sizes="any">
<link rel="apple-touch-icon" href="img/apple-touch-icon.png">
<meta name="theme-color" content="#7069ff">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="hwrap">
<a href="index.html" class="brand">
<img src="img/mark.svg" alt="">
<span>Start<span class="one">One</span><sup class="tm">™</sup><span class="docs"> docs</span></span>
</a>
<div class="hlinks">
<a href="https://startone.ai">Home</a>
<a href="https://github.com/startoneai/startone-community">GitHub</a>
<a href="https://startone.ai#pricing">Pricing</a>
</div>
</div>
</header>
<div class="shell">
<nav class="side">
<h4>Start here</h4>
<a href="index.html" >Overview</a>
<a href="index.html#which">Which edition?</a>
<h4>Community — free</h4>
<a href="community.html" >Quickstart</a>
<a href="community.html#config">Configuration</a>
<a href="community.html#limits">Limits</a>
<h4>Developer — Web</h4>
<a href="developer-web.html" class="active">Quickstart</a>
<a href="developer-web.html#config">Configuration</a>
<a href="developer-web.html#architecture">Architecture</a>
<a href="developer-web.html#deploy">Deploying</a>
<h4>Developer — Message</h4>
<a href="developer-message.html" >Quickstart</a>
<a href="developer-message.html#profile">Markets (US / CN)</a>
<a href="developer-message.html#channels">Channel setup</a>
<a href="developer-message.html#media">Media commands</a>
<a href="developer-message.html#deploy">Deploying</a>
<h4>Business</h4>
<a href="business.html" >Overview</a>
<h4>Reference</h4>
<a href="faq.html" >FAQ</a>
<a href="licensing.html" >Licensing</a>
</nav>
<main>
<span class="tag">$249 · Commercial license</span>
<h1>Developer — Web</h1>
<p class="lede">The full AI SaaS boilerplate for the web. Streaming multi-model chat, a complete media studio with a job queue and gallery, authentication, a database, and storage — all wired and deploy-ready.</p>
<h2>Requirements</h2>
<ul>
<li><strong>Node 22+</strong></li>
<li><strong>Docker</strong> — a <code>docker-compose.yml</code> is included for local Postgres and Redis. Or bring your own.</li>
<li>An API key from at least one AI provider (optional to start — see below)</li>
<li>A Clerk account for production auth (free tier is fine; optional in dev mode)</li>
</ul>
<h2>Quickstart</h2>
<pre><code>npm install
cp .env.example .env.local
docker compose up -d # local Postgres + Redis
npm run db:migrate # create the tables
npm run dev</code></pre>
<p>Open <code>http://localhost:3000</code>.</p>
<div class="note"><strong>It boots with zero keys.</strong> With no Clerk keys set it runs in <strong>dev mode</strong> — a single implicit user, no login required — and shows a dev-mode banner. AI calls return labelled dry-run responses. Explore first, configure second.</div>
<h3>Port conflicts</h3>
<p>The included <code>docker-compose.yml</code> binds Postgres on <code>5432</code> and Redis on <code>6379</code>. If you already run either locally, stop them first or change the ports in the compose file.</p>
<h2 id="config">Configuration</h2>
<h3>AI providers (chat)</h3>
<table>
<tr><th>Variable</th><th>Enables</th></tr>
<tr><td><code>OPENAI_API_KEY</code></td><td>GPT models</td></tr>
<tr><td><code>ANTHROPIC_API_KEY</code></td><td>Claude models</td></tr>
<tr><td><code>GOOGLE_GENERATIVE_AI_API_KEY</code></td><td>Gemini models</td></tr>
<tr><td><code>ZAI_API_KEY</code></td><td>GLM models</td></tr>
<tr><td><code>DEEPSEEK_API_KEY</code></td><td>DeepSeek models</td></tr>
<tr><td><code>DASHSCOPE_API_KEY</code></td><td>Qwen models</td></tr>
</table>
<p>These are your <strong>platform keys</strong> — the fallback used when a user has not supplied their own. Users can also add their own keys in <strong>Settings</strong> (BYOK); those are encrypted at rest with <code>APP_ENCRYPTION_KEY</code> and take precedence over the platform key.</p>
<h3>Media</h3>
<table>
<tr><th>Variable</th><th>Purpose</th></tr>
<tr><td><code>FAL_KEY</code></td><td>fal.ai — image, video, audio</td></tr>
<tr><td><code>REPLICATE_API_TOKEN</code></td><td>Replicate — the alternate provider</td></tr>
<tr><td><code>MEDIA_PROVIDER</code></td><td><code>fal</code> (default) or <code>replicate</code></td></tr>
</table>
<h3>Auth, data, storage</h3>
<table>
<tr><th>Variable</th><th>Purpose</th></tr>
<tr><td><code>CLERK_SECRET_KEY</code></td><td>Clerk auth. Leave blank for dev mode.</td></tr>
<tr><td><code>NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY</code></td><td>Clerk, client side</td></tr>
<tr><td><code>DATABASE_URL</code></td><td>Postgres. Defaults to the docker-compose service.</td></tr>
<tr><td><code>REDIS_URL</code></td><td>Redis. Defaults to the docker-compose service.</td></tr>
<tr><td><code>BLOB_READ_WRITE_TOKEN</code></td><td>Vercel Blob storage. Falls back to local disk if unset.</td></tr>
<tr><td><code>APP_ENCRYPTION_KEY</code></td><td>Encrypts user-supplied API keys at rest. <strong>Required in production.</strong></td></tr>
<tr><td><code>APP_URL</code></td><td>Public base URL. <code>http://localhost:3000</code> in dev.</td></tr>
<tr><td><code>CHAT_SYSTEM_PROMPT</code></td><td>Override the default system prompt</td></tr>
</table>
<div class="note"><strong>Set <code>APP_ENCRYPTION_KEY</code> before you go live.</strong> Without it, user-supplied API keys cannot be encrypted at rest.</div>
<h2 id="architecture">Architecture</h2>
<h3>Pages</h3>
<table>
<tr><th>Route</th><th>What it is</th></tr>
<tr><td><code>/</code></td><td>Landing page</td></tr>
<tr><td><code>/chat</code></td><td>Streaming chat with a model picker and persistent history</td></tr>
<tr><td><code>/studio</code></td><td>Media studio — image, video, audio generation</td></tr>
<tr><td><code>/gallery</code></td><td>Every generation, browsable and downloadable</td></tr>
<tr><td><code>/settings</code></td><td>BYOK key management</td></tr>
<tr><td><code>/design</code></td><td>Design-token reference page</td></tr>
</table>
<h3>API routes</h3>
<table>
<tr><th>Route</th><th>Purpose</th></tr>
<tr><td><code>POST /api/chat</code></td><td>Streaming chat completions</td></tr>
<tr><td><code>POST /api/media</code></td><td>Enqueue a generation job</td></tr>
<tr><td><code>GET /api/media/[id]</code></td><td>Poll job status</td></tr>
<tr><td><code>GET /api/storage/[...key]</code></td><td>Serve stored media</td></tr>
</table>
<h3>Database</h3>
<p>Postgres via Drizzle ORM. Five tables:</p>
<table>
<tr><th>Table</th><th>Holds</th></tr>
<tr><td><code>users</code></td><td>User records, keyed to the Clerk ID</td></tr>
<tr><td><code>user_api_keys</code></td><td>BYOK keys, encrypted at rest</td></tr>
<tr><td><code>conversations</code></td><td>Chat threads</td></tr>
<tr><td><code>messages</code></td><td>Individual messages</td></tr>
<tr><td><code>media_jobs</code></td><td>Generation jobs and their results</td></tr>
</table>
<p>Migrations live in <code>lib/db/migrations/</code>. Run <code>npm run db:migrate</code> to apply them, or <code>npm run db:studio</code> to browse the data.</p>
<h3>The media pipeline</h3>
<p>Generation is asynchronous. The client posts to <code>/api/media</code>, which writes a <code>media_jobs</code> row and returns an id; the client polls <code>/api/media/[id]</code> until the job completes. Providers (fal.ai, Replicate) sit behind a single contract in <code>lib/media/providers.ts</code>, so swapping providers means editing one module.</p>
<h2>Scripts</h2>
<table>
<tr><th>Command</th><th>What it does</th></tr>
<tr><td><code>npm run dev</code></td><td>Dev server</td></tr>
<tr><td><code>npm run build</code></td><td>Production build</td></tr>
<tr><td><code>npm run db:migrate</code></td><td>Apply migrations</td></tr>
<tr><td><code>npm run db:generate</code></td><td>Generate a migration from schema changes</td></tr>
<tr><td><code>npm run db:studio</code></td><td>Browse the database</td></tr>
<tr><td><code>npm run gate</code></td><td>Lint + typecheck + test</td></tr>
</table>
<h2 id="deploy">Deploying</h2>
<p>It is a standard Next.js app and deploys anywhere Next.js runs — Vercel, Fly, Railway, or your own host.</p>
<p><strong>You will need, in production:</strong></p>
<ul>
<li>A managed Postgres (Neon, Supabase, RDS…) → <code>DATABASE_URL</code></li>
<li>A managed Redis (Upstash, Redis Cloud…) → <code>REDIS_URL</code></li>
<li>Clerk production keys</li>
<li>Blob storage → <code>BLOB_READ_WRITE_TOKEN</code> (or the local-disk fallback, which will not survive on ephemeral hosts)</li>
<li><code>APP_ENCRYPTION_KEY</code> — do not skip this</li>
<li><code>APP_URL</code> set to your real domain</li>
</ul>
<p>Run <code>npm run db:migrate</code> against the production database before first boot.</p>
<h2>What this edition does not include</h2>
<p><strong>No billing.</strong> It is unmetered by design — no credits, no limits, no payment rails. Add your own, or upgrade to <a href="business.html">Business</a>, which is this codebase plus the money layer.</p>
<footer>
© 2026 Kredit Technology, LLC. StartOne™ is a trademark of Kredit Technology, LLC.
</footer>
</main>
</div>
</body>
</html>