Run your own copy
Self-host OpenKuasa on your own Supabase project and any Node server.
OpenKuasa is free to self-host under AGPL-3.0. You need a Supabase project for data and sign-in, and a server that runs Node.
Who can do this
Anyone running their own copy. You need access to a Supabase project and to the server you deploy on.
Before you start
- Node 22 or newer.
- pnpm. Always use pnpm, not npm or yarn.
- A Supabase project.
Steps
1. Get the code
git clone https://github.com/OpenKuasa/OpenKuasa.git
cd OpenKuasa
pnpm install
pnpm dev
Open http://localhost:3000. With no Supabase project set, the app opens in preview mode: every visitor is a read-only "Guest" in a "Preview workspace", and the screens show sample data.
2. Point it at your Supabase project
Create a .env.local file in the project root with your project's URL and anon key (Supabase dashboard → Project Settings → API):
NEXT_PUBLIC_SUPABASE_URL=https://<your-project-ref>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<your-anon-key>
The rest of the app is turned on by more variables. See Environment variables.
3. Create the tables
Run the migrations once against your project:
pnpm db:migrate --apply
It asks you to type the project ref before it writes anything. See Keep the database up to date.
4. Set up Supabase Auth
In the Supabase dashboard, under Authentication:
- Enable Anonymous sign-ins. It powers the demo workspace and the tests.
- Confirm email is your choice. With it off, signup signs the person in at once and lands on
/command. With it on, signup stops at a "check your email" message, and the person confirms and then signs in. Either way, an already-registered address always gets that same "check your email" message, so the form never says which addresses have an account. - Leave hCaptcha off. The sign-in forms do not send a captcha token yet, so turning hCaptcha on breaks sign-in and signup.
The sign-in email templates are in supabase/email-templates/. They are not set by the migrations: paste each file into the matching template in the Supabase dashboard (Authentication → Emails → Templates). Every link in them points at the app's /auth/confirm route.
5. Build and run it on your server
pnpm build
pnpm start
Any host that runs Node 22 and these two commands will do. openkuasa.com runs on Railway.
6. Add the scheduler
Some background work runs only when your scheduler calls it. See Scheduled jobs.
Common problems
- Every request answers
503 Service unavailable. A production server (pnpm start, or any host) refuses to serve whenNEXT_PUBLIC_SUPABASE_URLorNEXT_PUBLIC_SUPABASE_ANON_KEYis missing. The server log names the two required variables. This is on purpose: a deployment that loses a variable fails visibly instead of turning into the sample app. - You want the sample-data preview on a production build. Set
OPENKUASA_PREVIEW=1. It is read only when the Supabase values are missing, so it does nothing on a configured deployment. Do not set it on the deployment that serves your real data. - Some pages show sample data instead of yours. The database is missing a table or column that the code needs. Run
pnpm db:migrateto see which migrations your project lacks. - Rate limits count everyone together. The app tells clients apart by the
X-Real-IPheader that Railway's edge sets. On a host or proxy that does not set it, every request counts against one shared counter, which has its own, wider limit. A proxy that passes on anX-Real-IPthe client sent is worse: each client can pick its own counter and dodge the per-client limits. Have the proxy set the header itself, from the connection. - MCP limits don't add up across servers. The per-key limits on the MCP endpoint are counted in each server process's memory, so with several instances each one counts on its own, and a restart starts the count again.
- Password-reset links are sometimes refused. If you run several instances or a serverless host, set
AUTH_COOKIE_SECRET(32+ characters). See Environment variables.