Bring an app from another tool
When bringing an app from another tool to Keelson, choose a deployment path based on its actual architecture, rather than the tool’s name. The same tool can generate different architectures depending on its settings and prompts.
- What you can do: Deploy an app whose source code you have locally, using the path that matches its architecture
- What you need: The complete source code (exported from the tool or in a Git repository), the Keelson CLI, and an AI agent (Quickstart)
- Done when: The app opens at its Keelson URL and connects to the same data as in its original environment
1. Check the architecture
Section titled “1. Check the architecture”Check these four things in the source code. Ask your AI agent to “check this app’s architecture,” and it will assess the app using the Skill’s procedure.
| What to check | Where to look |
|---|---|
| Does it have server-side processing? | Dependencies and scripts in package.json. API routes, Server Actions, or Express indicate server-side processing. If it only produces vite build output, it is frontend-only |
| Which database does it use? | Connection code for Supabase, Firebase, or PostgreSQL. File-based SQLite (sqlite3, better-sqlite3) needs to be rewritten |
| How does authentication work? | Login screens and session management using Supabase Auth, Firebase Auth, Clerk, or similar services. Keelson authenticates users at the app’s entrance, so you need to decide how to handle existing authentication |
| Where are files stored? | External storage (Supabase Storage, S3) can stay as it is. Writes to local disk need to be rewritten |
2. Choose a path for your architecture
Section titled “2. Choose a path for your architecture”| Actual architecture | Deployment path |
|---|---|
| Static frontend only (React, Vue, or Svelte build output; data comes from external service APIs) | assets mode. Specify the build output directory |
| Server-side processing (Next.js, Express, FastAPI, etc.) | Deploy as a server, started with command. See Framework notes |
| Frontend + API in a separate process | Hybrid configuration. Set both assets and command, and specify the API paths with assets.api |
| Depends on an external database, authentication, or storage | Use one of the paths above, keep the connections, and check what needs to change (section 3 below) |
Static frontend only
Section titled “Static frontend only”This is the simplest path. Build locally and send only the output directory. For static site deployments, the CLI uploads only the contents of assets.dir and keelson.yaml. It does not run a server-side build (npm install / npm run build).
-
Install dependencies and build locally. Put values that are embedded at build time, such as external service URLs and public keys, in the configuration file read during the build (
.env.productionfor Vite, for example). Do not embed secrets in the frontendTerminal window npm installnpm run build # Vite outputs to dist; Next.js static export outputs to out -
Add
keelson.yaml.type: webis required for a static site withoutcommandslug: my-apptype: webruntime: node-slimdb:mode: noneassets:dir: dist # Locally built output directoryfallback: index.html # For SPA routing -
Run
keelson deploy. Use--check --jsonto confirm that only files underdistandkeelson.yamlwill be uploaded
Automatic server-side builds (npm ci and npm run build --if-present) run only for server and hybrid configurations that have a command.
Server-side processing
Section titled “Server-side processing”Update the server to listen on 0.0.0.0 using PORT, and put the startup command in command. For Next.js, use next start after next build; for Express, use node server.js. See Framework notes for startup commands and considerations for each framework.
File-based SQLite, local disk storage, and in-app timers need to be rewritten. If you ask an AI agent to deploy the app, it automatically handles changes marked ”△ Rewrite” in the compatibility table.
3. Review external service dependencies
Section titled “3. Review external service dependencies”Supabase (database and storage)
Section titled “Supabase (database and storage)”You can keep using them. Set db.mode: none and pass connection details (URLs and keys) through secrets. Keelson does not restrict outbound connections.
Configurations that call Supabase directly from the browser (anon key + RLS) also work. In that case, Supabase RLS continues to protect the data.
Authentication such as Supabase Auth or Firebase Auth
Section titled “Authentication such as Supabase Auth or Firebase Auth”This requires the most consideration. On Keelson, users must log in through Keelson before entering the app. Decide what to do with the original authentication by examining authentication and data permissions together.
| Original configuration | Decision |
|---|---|
| Authentication only provides a login screen; data permissions do not depend on it | Remove the original authentication and identify users using Keelson headers such as X-Keelson-User-Id. This removes the second login |
Data permissions (RLS or policies using auth.uid()) depend on users from the original authentication system | You cannot simply remove authentication. The app would lose the original user’s identity, so permission checks based on auth.uid() would no longer work (ownership policies would hide the data). Either retain the original authentication and require two logins, or move data access to the server and implement permission checks using Keelson user IDs |
| Per-user data is stored using user IDs from the original authentication system | You need a mapping to Keelson user IDs. Matching by email address is a practical approach |
Before simplifying a two-login flow, check where permissions are enforced.
Local file storage
Section titled “Local file storage”Local files disappear on restart. Replace this storage with Managed SQLite or the Files / Media SDK.
4. Common patterns by tool
Section titled “4. Common patterns by tool”Generated architectures vary, so these are only guidelines. Always inspect the actual app as described in section 1.
| Tool | Common architecture | Likely path |
|---|---|---|
| Lovable | React + Vite frontend with Supabase (database, authentication, storage). Can sync to GitHub | Static frontend, keeping Supabase. Use the table above to decide how to handle Supabase Auth |
| Bolt | React + Vite or Next.js. Uses Bolt’s built-in database or Supabase | Static frontend or server-side processing. If using the built-in database, first check whether it accepts external connections |
| v0 | Next.js (App Router) by default. May include Server Actions or API routes | Server-side processing. Start with next start |
| Built from scratch with Claude Code / Codex / Cursor | Any architecture is possible | Check using section 1. The Skill assesses Python, Node.js, and Go apps |
5. Deploy
Section titled “5. Deploy”Open the app in your AI agent and ask it to “deploy this app to Keelson.” The agent assesses the app, creates keelson.yaml, declares secrets, deploys, and verifies the result. See Deploy an app for details.
After deployment, check that the app connects to the same data as in its original environment, uses Keelson login, and opens for other members.
What cannot be moved directly
Section titled “What cannot be moved directly”- Tool-specific backends (Lovable Cloud, Base44’s backend, etc.). Deploying source code to Keelson does not move the platform’s database, authentication, or functions with it. Keep them as external services (the tools provide guidance for hosting only the frontend elsewhere or migrating to Supabase), or rebuild them using Managed SQLite or other services
- The tool’s editing features. Keelson runs the app; you edit it using your local AI agent
- Languages such as Ruby, PHP, or Java, and architectures that require always-running processes. See Supported apps and constraints
Related pages
Section titled “Related pages”- Supported apps and constraints — compatibility table
- keelson.yaml configuration —
assetsand hybrid configurations - Environment variables and secrets
- FAQ