To get started with Tanstack Start and bknd, create a new Tanstack Start project by following the official guide, and then install bknd as a dependency:
When run with Node.js, a version of 22 (LTS) or higher is required. Please
verify your version by running node -v, and
upgrade if necessary.
Now create a bknd.config.ts file in the root of your project:
bknd.config.ts
import { type TanstackStartConfig } from "bknd/adapter/tanstack-start";import { em, entity, text, boolean } from "bknd";const schema = em({ todos: entity("todos", { title: text(), done: boolean(), }),});export default { connection: { url: "file:data.db", }, config: { data: schema.toJSON(), auth: { enabled: true, jwt: { secret: "random_gibberish_please_change_this", // use something like `openssl rand -hex 32` for production }, }, }, options: { // the seed option is only executed if the database was empty seed: async (ctx) => { // create some entries await ctx.em.mutator("todos").insertMany([ { title: "Learn bknd", done: true }, { title: "Build something cool", done: false }, ]); // and create a user await ctx.app.module.auth.createUser({ email: "test@bknd.io", password: "12345678", }); }, },} satisfies TanstackStartConfig;
For more information about the connection object, refer to the Database guide.
See bknd.config.ts for more information on how to configure bknd. The TanstackStartConfig type extends the base config type with the following properties:
export type TanstackStartConfig<Env = TanstackStartEnv> = FrameworkBkndConfig<Env>;
Create a helper file to instantiate the bknd instance and retrieve the API, importing the configuration from the bknd.config.ts file:
src/bknd.ts
import config from "../bknd.config";import { getApp } from "bknd/adapter/tanstack-start";export async function getApi({ headers, verify,}: { verify?: boolean; headers?: Headers;}) { const app = await getApp(config, process.env); if (verify) { const api = app.getApi({ headers }); await api.verifyAuth(); return api; } return app.getApi();};
The adapter uses process.env to access environment variables, this works because Tanstack Start uses Nitro underneath and it will use polyfills for process.env making it platform/runtime agnostic.
import { createFileRoute } from "@tanstack/react-router";import { useAuth } from "bknd/client";import "bknd/dist/styles.css";import { Admin } from "bknd/ui";export const Route = createFileRoute("/admin/$")({ ssr: false, // "data-only" works too component: RouteComponent,});function RouteComponent() { const { user } = useAuth(); return ( <Admin withProvider={{ user: user }} config={{ basepath: "/admin", logo_return_path: "/../", theme: "system", }} baseUrl={import.meta.env.APP_URL} /> );};
Admin routes are expected to run on the client not using ssr: false will cause errors like ✘ [ERROR] No matching export in "node_modules/json-schema-library/dist/index.mjs" for import "Draft2019" and production build might fail because of this
You can use the getApp function to access the bknd API in your app:
These are a few examples how you can validate user and handle server-side requests using createServerFn.