Daptin: a self-hosted application server that turns schema files into running APIs
Self-hosted application server for schema-driven APIs, identity, files, automation, integrations, realtime, metering, and protocols.
At a glance
- What is it?
- Daptin loads YAML or JSON schema definitions at runtime and attaches JSON:API, identity, storage, automation and protocol surfaces to each configured table. It suits teams that want a self-hosted backend they can configure as data rather than write as code, and it is a poor fit for anyone expecting a small, single-purpose service.
- Who is it for?
- Adopt Daptin if you want a self-hosted backend where tables, permissions, actions and schedules are rows you can edit at runtime, and you are willing to run PostgreSQL or SQLite plus the storage and pub/sub components it expects. Do not adopt it if you need a narrow service with a small audit surface, or if you cannot accept LGPL-3.0 terms for the server you deploy.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Daptin solves: one schema, many backend surfaces
Most small backend projects repeat the same work. You define tables, then write CRUD endpoints, then add authentication, then add row-level authorization, then add file uploads, then add a scheduler for background jobs, then add a WebSocket channel so the frontend stops polling. Daptin's premise is that all of these can be derived from the data model itself. The README states that Daptin loads schema files into its runtime configuration, and that each configured table is recorded as `world` metadata and becomes a permission-aware JSON:API resource at `/api/{entity}`. The other surfaces (GraphQL, WebSockets, feeds, OAuth endpoints, file routes, LLM routes) attach around that resource runtime rather than being configured separately per table. The audience is therefore developers who are comfortable describing their domain as tables and relations, and who would rather edit a schema file and a few configuration rows than maintain a conventional application codebase. It is not aimed at teams that want a library to embed, because Daptin is a server process you run, not a package you import.
How the runtime works: schema in, world metadata out
The mechanism described in the README is a two-stage one. First, schema files in YAML or JSON are loaded into the server's runtime configuration. The schema describes records, fields, relationships, validation and optional behavior flags, and the feature table lists 41 column types along with relations, joins, composite keys, translations, and audit, state and metering flags. Second, each configured table is registered as `world` metadata and exposed as a resource. Permission gates are evaluated against the table, an individual row, a relation, or an action before the work is performed, which means authorization is not a middleware you bolt on afterwards but a check the resource runtime consults on each operation. A large part of the server's own behavior is then configured as ordinary data. The README names tables such as `action`, `task`, `smd`, `cloud_store`, `site`, `integration`, `llm_provider` and `api_plan`, and says rows in those tables tell the running server what to execute or expose. That is the design decision worth noticing: automation is not compiled in, it is stored. An action is a row with inputs, validation, conformations, conditions and ordered outcomes, and a task row schedules it. The trade-off is that the running server's behavior lives in the same database as your application data, so a bad row can change what the server does.
Getting a first instance running
The README gives three entry points. The fastest is a single Docker command: `docker run --pull=always --rm -p 127.0.0.1:6336:8080 daptin/daptin:latest`, which serves the UI on port 6336 and discards state when the container stops. For something durable with PostgreSQL, the documented path is `cp .env.example .env` followed by `docker compose up --wait`. The README notes that this Compose stack binds Daptin only to `127.0.0.1:6336`, keeps PostgreSQL inside its private network, stores database and asset data in named volumes, and that the development password in `.env` should be changed before using the stack beyond local evaluation. A Linux binary is also published: download `daptin-linux-amd64` from the latest release, `chmod +x daptin`, then run `./daptin -port=6336`. After that the documented flow is to open http://localhost:6336, create the first administrator, and continue with the Getting Started Guide. Kubernetes users are pointed at the Kustomize deployment guide under `kubernetes/`. The `-port` flag is the only runtime flag shown in the supplied material; everything else is expected to arrive through the schema files and the system tables.
Actions, tasks and state: automation stored as rows
The automation model is the part that most distinguishes Daptin from a plain REST framework. An action, per the feature table, carries inputs, validation, conformations, conditions, ordered outcomes, CRUD steps, Go performers, client responses and chained work. Tasks invoke actions on a schedule, and state tracking is a separate documented concern. Because these are rows rather than code, the same mechanism that lets you add a business rule through the API also lets you change server behavior without a redeploy. For workflows that fit the CRUD-step and condition vocabulary, that is a genuine reduction in code. For workflows that do not, the escape hatch is a Go performer, which puts you back in the position of writing and compiling code against the project. The README does not describe how performers are registered or versioned, so if your logic needs arbitrary computation, treat that boundary as something to verify in the wiki rather than assume. The same caution applies to state tracking: the feature table lists it, but the supplied material does not explain how state transitions are defined or enforced.
The breadth is the limitation
Daptin ships JSON:API CRUD with filtering, sorting and pagination, a separate aggregation API, optional GraphQL, OpenAPI and metadata routes, OAuth 2 and OIDC provider endpoints with JWKS, rclone-backed local and cloud storage with presigned flows, Olric PubSub with `/live` WebSockets, RSS, Atom and JSON feeds, SMTP and IMAP, FTP and FTPS, WebDAV-style CalDAV and CardDAV, OpenAPI v2 and v3 operations installed as actions, gRPC and short-lived WebSocket transports, and multi-deployment LLM routing with OpenAI-compatible chat, Responses, embeddings, image generation and streaming. That is a large surface to run and to reason about. If your requirement is a small service that stores three tables and returns JSON, Daptin is the wrong tool: you take on a database, a storage backend, a pub/sub component and a protocol stack in exchange for capabilities you will not use, and every one of those is something you have to keep patched. A second limitation is operational coupling. Because actions, tasks, storage configuration and sites are rows, the correctness of your running server depends on the contents of tables that a sufficiently privileged user can edit through the same API surface. The permission gates described in the README are the only thing standing between that and accidental changes to production behavior, so the permission model is not optional hardening here, it is the control plane.
How it compares to assembling the pieces yourself
The obvious alternative is the conventional stack: Postgres for storage, a framework such as Django or Rails or a Go router for the API layer, a separate identity provider, an object store, and a job runner. The difference is not features, it is where the configuration lives. In the conventional stack, adding a table means writing a model, a migration, a serializer, a permission class and a route, then deploying. In Daptin, adding a table means editing a schema file or a row, and the API, the permission checks and the discovery routes follow from that. The conventional stack wins on auditability and on the size of the surface you have to defend, and it wins clearly when your domain logic is too irregular for CRUD steps and conditions. Daptin wins when the domain is genuinely tabular and the work you are avoiding is the boilerplate around it. A narrower self-hosted option is to take a headless CMS or a backend-as-a-service and add only the pieces you need; that keeps the surface small but usually means giving up the protocol breadth (FTP, CalDAV, CardDAV, IMAP) that Daptin includes. None of these is strictly better. The decision turns on whether your tables describe your application well enough that deriving the API from them is a saving rather than a constraint.
Licence, upgrades and what to check before adopting
Daptin is licensed under LGPL-3.0. The practical consequence, stated plainly and without legal advice, is that the licence is a copyleft licence with a linking exception for some kinds of use, and the exact obligations depend on whether you modify Daptin itself, distribute it, or only run it as a separate server behind your own application. If you intend to ship a modified Daptin to customers, or to link it into a proprietary product, that is a question for your own counsel rather than for this article. On maintenance, the supplied material shows a steady release cadence around v0.13.5 through v0.13.7 in September 2026, and the repository is not archived, but the recent releases are all patch-level within a 0.13 line, which tells you the project is iterating rather than stabilizing an API. Expect schema and system-table changes to arrive with releases, and plan to read the release notes before upgrading a production instance. The concrete thing to verify first is the migration story: the README describes schema loading and 41 column types but does not describe how an existing table's schema is evolved in place, so test that against a copy of your own data before you commit to Daptin as the system of record.
Editorial conclusion
Adopt Daptin if you want a self-hosted backend where tables, permissions, actions and schedules are rows you can edit at runtime, and you are willing to run PostgreSQL or SQLite plus the storage and pub/sub components it expects. Do not adopt it if you need a narrow service with a small audit surface, or if you cannot accept LGPL-3.0 terms for the server you deploy. Before committing, verify three things against your own requirements: that the 41 documented column types cover your data, that the action and task tables can express your workflow without custom Go performers, and that the schema migration path in the current release notes matches how you intend to evolve tables in production.
Community notes