Skip to content
Console →
Website →
Asking an AI? Paste this URL https://keelson.dev/llms.txt

Supported apps and constraints

Keelson supports Python, Node.js, and Go web apps, static sites, and scheduled jobs. Depending on your framework and storage choices, you may need to change code or configuration. Check the table below.

You do not need a Dockerfile. Keelson does not use one for its build, even if your app includes one.

AppStatusNotes
Python web apps (FastAPI, Flask, and others)SupportedStart on the port specified by PORT. Use gunicorn for Flask
Node.js web apps (Express, Hono, Next.js, and others)SupportedStart on the port specified by PORT. Use next start for Next.js
Go web apps (net/http, Gin, and others)SupportedKeelson builds the app and starts it with ./app
Prebuilt static sites / SPAs (React, Vue, Svelte, and others)SupportedPoint assets to the build output
Static frontend + API server (hybrid)SupportedSet the API path with assets.api
Scheduled jobs onlySupportedSet crons alongside the shared required fields; omit the web server command
Connections to external PostgreSQL / MySQL / libSQLSupportedSet db.mode: none. Supply connection details through secrets
Calls to external APIs (OpenAI, Slack, Google Sheets, and others)SupportedOutbound connections are unrestricted, except that the SMTP ports (TCP 25, 465, 587, 2525) are always blocked
Persistent data in SQLite files (sqlite3, better-sqlite3, and others)Changes requiredSwitch the connection to a libSQL client and set db.mode: libsql. SQL usually stays as it is (Managed SQLite is SQLite-compatible), but adapt to client API differences (async in Node.js, row_factory and others in Python). Local development in Python / Node.js keeps working with file:local.db
Data that must persist stored in local filesChanges requiredUse Managed SQLite or the Files SDK / Media SDK. Local data written during execution does not survive restarts
In-app timers or background threadsChanges requiredMove work that runs at set times to scheduled jobs, and enqueue work that continues after a request as a background task (How apps run)
DjangoExternal database onlyConnect to an external database such as PostgreSQL with db.mode: none and start with gunicorn. Managed SQLite (libSQL) has no backend for the Django ORM, so Django with Managed SQLite is not supported (Framework notes)
StreamlitUnsupportedIt requires WebSocket and currently does not work (Framework notes)
GradioUnder evaluationVersion 4 and later are being evaluated. Operation is not currently guaranteed
Ruby / PHP / Java / Rust / .NET / ElixirUnsupportedOnly Python, Node.js, and Go runtimes are available
Adding apt packages through a DockerfileUnsupportedNo root access. A -media runtime may cover image or video requirements
Apps requiring continuously running processes, daemons, or WebSocket serversUnsupportedIncompatible with the execution model, which stops idle apps
Running your own Redis / Kafka / database serverUnsupportedConnecting to an external service is allowed
GPU workloadsUnsupported

Apps marked “Changes required” may work after code or configuration changes. Ask your AI agent to review the app and propose the necessary changes.

You can store temporary data that can be regenerated in local files. Temporary SQLite use requires a db.local_sqlite declaration. See the keelson.yaml reference for requirements.

For apps built with other tools, such as Lovable, Bolt, or v0, see Bring an app from another tool.

Select a runtime with runtime in keelson.yaml. Start with -slim if you are unsure, and switch to -media if you need image, video, or PDF processing libraries such as Pillow, sharp, or ffmpeg.

RuntimeLanguage versionBuild behavior
python-slim / python-mediaPython 3.12Automatically installs dependencies from requirements.txt or pyproject.toml
node-slim / node-mediaNode.js 24Automatically installs dependencies from package.json and package-lock.json. Runs npm run build if defined
go-slim / go-mediaGo 1.26Builds from go.mod using go build and starts as ./app

The Go version is the toolchain used for the build. The build steps in this table apply to apps with server-side processing and scheduled jobs. Dependencies are installed at build time. Put only the startup command in command.

  • Node.js: Keelson uses npm for builds on the platform. Projects with only pnpm-lock.yaml or yarn.lock are unsupported; provide package-lock.json. Static sites built locally with pnpm or Yarn can still be served.
  • Go: Builds use CGO_ENABLED=0. Libraries that depend on cgo cannot be used.

See the keelson.yaml reference for dependency file requirements and build constraints.

ItemBehavior
OS / CPULinux / x86_64
Permissions and system packagesRuns as a non-root user. sudo and apt-get are unavailable
Web server startupListen on 0.0.0.0 and the port specified by PORT
Data storageLocal files are not persistent. Use Managed SQLite or the Files / Media SDK for data you need to keep
ProcessingRequest handling, background tasks, and scheduled jobs are supported. See How apps run

See Plans and limits for execution time, app count, and other limits.

This Python (FastAPI) example can be deployed with three files: keelson.yaml, requirements.txt, and app.py.

keelson.yaml
slug: my-app
runtime: python-slim
command: "python app.py"
db:
mode: none
requirements.txt
fastapi
uvicorn
app.py
import os
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
def index():
return {"message": "Hello from Keelson"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=int(os.environ["PORT"]))

Your AI agent normally writes keelson.yaml, so you do not need to create it yourself.