Database
View as markdown.mdQuickstart
Enable the database, create a table, and read and write records from your app.
The Zeitlos database offers a managed data API — tables and records, no SQL. Your app talks to it through the @zeitlosapp/sdk package.
Note
The database is reached through the SDK, and the SDK is TypeScript and JavaScript only for now. There is no official client for other languages yet.
Enable the database
-
Open your project in the dashboard and go to Database → Tables.
-
Choose "Enable database"
A new project has no database until you add one.
-
Create a table
Add a table and its fields using our MCP server with your AI assistent.
Note
Schemas are not defined in code. There are no migration files in your repository. Editing schemas is currently only possible using the MCP server. We'll add schema editing to the dashboard in the future.
Install the SDK
npm install @zeitlosapp/sdkCreate a client
In a Zeitlos-hosted app this is zero-config. The data URL and key are injected into your app's environment, and the SDK reads them:
import { createClient } from '@zeitlosapp/sdk';
export const client = createClient();Important
The database is server-side only for now. Call client.from(...) from server components,
route handlers or server actions — never from the browser. The injected key is a service
key with full access, and there is no browser-safe flow yet.
Read and write
import { client } from '@/lib/db';
export const dynamic = 'force-dynamic';
export default async function Posts() {
const { records } = await client
.from('posts')
.filter({ published: true })
.sort('-created_at')
.limit(20)
.list();
return (
<ul>
{records.map((p) => (
<li key={p.id}>{p.title}</li>
))}
</ul>
);
}const post = await client.from('posts').create({ title: 'Hello', published: false });
await client.from('posts').update(post.id, { published: true });
await client.from('posts').delete(post.id);Every method and filter operator is in the API reference.
Type your tables
By default records are loosely typed. Pass a Database type for full type safety:
type Database = {
posts: { id: string; title: string; published: boolean; created_at: string };
};
const client = createClient<Database>();
const { records } = await client.from('posts').list(); // records: Database['posts'][]Warning
Use a type alias, not an interface. The SDK's generic expects an index signature, which
a named interface doesn't have — createClient<SomeInterface>() will not typecheck.
Generating type definitions
You don't have to write your type definition by hand. You can use the Zeitlos CLI to generate types:
npx @zeitlosapp/cli gen typesNote: this will generate types from your local development database. Make sure those are reflecting the types you want to generate. We'll provide better tools in the future to synchronize schemas between your development and production database.
Develop locally
npx @zeitlosapp/cli devThis runs the database, authentication and an MCP server on your own machine and writes the
connection details into .env.local, so the code above runs unchanged locally.
See Local development for giving the local database a schema, generating types and troubleshooting.