Blog

A headless backend for SvelteKit or Next.js in minutes

Need a headless backend for SvelteKit or Next.js? Run Kanesh in Docker, create collections in Studio and fetch them over REST from your server code.

A headless backend for SvelteKit or Next.js holds your data and serves it over an API, so your frontend only fetches and renders. With Kanesh you run one container, create collections in the Studio, and call the REST API from server code with a personal token. There are no SDKs yet, so you use plain fetch.

Set it up

Build the image from source and run it. SQLite is the default and needs no other service:

git clone https://github.com/kaneshdev/kanesh.git
cd kanesh
docker build --tag kanesh .
docker run --name kanesh -p 127.0.0.1:8080:8080 -v kanesh-data:/data kanesh

Open http://127.0.0.1:8080, claim the installation with the token from /data/claim-token, and create the owner account. Then in Studio open Settings → Data model → Create collection and add a posts collection with a title string and a body text field. The collection is available over REST and GraphQL immediately. Follow Getting started for the full steps.

Next, open Account → API tokens and create a personal token. The secret is shown once and stored only as a hash. Put it in your app’s server environment:

KANESH_URL=http://127.0.0.1:8080
KANESH_WORKSPACE=WORKSPACE_ID
KANESH_TOKEN=...

Fetch in SvelteKit

Call Kanesh from a server load function, so the token never reaches the browser:

// src/routes/posts/+page.server.ts
import { KANESH_URL, KANESH_WORKSPACE, KANESH_TOKEN } from '$env/static/private';

export async function load({ fetch }) {
	const res = await fetch(
		`${KANESH_URL}/api/v1/workspaces/${KANESH_WORKSPACE}/collections/posts/records`,
		{ headers: { Authorization: `Bearer ${KANESH_TOKEN}` } }
	);
	const body = await res.json();
	return { posts: body.data };
}

Fetch in Next.js

In the App Router, a server component can do the same:

// app/posts/page.tsx
export default async function Page() {
	const res = await fetch(
		`${process.env.KANESH_URL}/api/v1/workspaces/${process.env.KANESH_WORKSPACE}/collections/posts/records`,
		{ headers: { Authorization: `Bearer ${process.env.KANESH_TOKEN}` } }
	);
	const { data } = await res.json();
	return (
		<ul>
			{data.map((post: { title: string }) => (
				<li key={post.title}>{post.title}</li>
			))}
		</ul>
	);
}

REST responses use a data and meta envelope, and support filters, sort and lookups. GraphQL is available on the same collections. Because there is no SDK yet, generate types from the OpenAPI 3.1 export, which Kanesh builds from the live schema, with any generator you like.

What the frontend needs, and what Kanesh has

NeedIn Kanesh
Typed dataNine field types: string, text, integer, float, boolean, datetime, json, file and image
RelationsN:1, 1:N and N:N with real foreign keys on SQLite and PostgreSQL
APIREST, GraphQL and an OpenAPI 3.1 export
Server credentialsPersonal API tokens that are hashed, expiring and revocable
Public contentA Public role for unauthenticated access, off by default
Types for TypeScriptGenerate from the OpenAPI export
Realtime updatesNot yet
SDKsNot yet

Keep the token on the server

Call Kanesh from load functions, server components and route handlers. If a browser must call it directly, set CORS_ENABLED and CORS_ORIGINS to exact origins, and never put a personal token in client-side code. For content that is meant to be public, turn on the Public role only for the collections that need it. See configuration and access control.

FAQ

Does Kanesh have a SvelteKit or Next.js SDK?

No. There are no SDKs yet. Use fetch against the REST API, or any GraphQL client against the GraphQL endpoint, and generate types from the OpenAPI 3.1 export.

Can I use it for a blog or a store?

Yes, as a data source. The blog use case and the ecommerce use case show example collections and relations. Kanesh has no realtime, OAuth or SSO or workflows today, and all three are on the roadmap, so check that list against your project.

Does it work with frameworks other than these two?

Yes. Any framework or script that can send HTTP requests can read the REST or GraphQL API, since both are plain HTTP.

Next steps

Start with Getting started. If you are weighing it against a headless CMS, read Kanesh vs Strapi.

Buy me a coffee