v0.20.0

ruvnet/RuViewv0.20.0Jan 9, 2026by dswbx

AI Summary

A major release that migrates the project to the Apache 2.0 license, merges PostgreSQL support into the main package, and introduces a new Email OTP plugin for passwordless authentication. It also adds a dedicated SvelteKit adapter and enables browser-based execution using SQLocal.

Key Highlights

  • License changed to Apache 2.0
  • PostgreSQL support merged into main package
  • New Email OTP plugin for passwordless login
  • Added SvelteKit adapter
  • Browser execution support with SQLocal (OPFS)

Breaking Changes

  • License changed to Apache 2.0
  • PostgreSQL package merged into main package (may require import path updates)
  • Implicit joins in repository where clauses (may affect query behavior)

New Features

  • Email OTP plugin
  • Plunk email driver
  • SvelteKit adapter
  • SQLocal/OPFS support
  • Overwrite option for media uploads
  • Hybrid mode improvements

Full Release Notes

## License change to Apache 2.0 
bknd is now licensed under the Apache 2.0 license, making it even more permissive and enterprise-friendly.

## Postgres support now included
The separate `@bknd/postgres` package has been merged into the main `bknd` package. PostgreSQL connections are now available directly:

```ts
import { pgPostgres, postgresJs } from "bknd";
import { Pool } from "pg";
import postgres from 'postgres'

// using pg library
const connection = pg({
  pool: new Pool({
    connectionString: "postgresql://user:password@localhost:5432/database",
  }),
});

// using postgres.js
const connection = postgresJs({
  postgres: postgres("postgresql://user:password@localhost:5432/database"),
});
```

## MCP in admin navigation 
The MCP (Model Context Protocol) tool is now accessible directly from the main navigation when enabled. The UI has been improved to be route-aware, making it easier to interact with AI tools directly from the admin interface.

## Improved hybrid mode
The hybrid mode has been enhanced with better type inference and improved configuration handling:
- Reader function can now return objects directly (not just strings)
- Automatic schema syncing in development with `sync_required` flag
- Better handling of missing config files with automatic defaults

## Repository auto-join for related entities
When querying with `where` clauses that reference related entities, bknd now automatically adds the necessary joins. This means you can filter by related entity fields without explicitly specifying joins:

```ts
// automatically joins "author" when filtering by author.name
const posts = await api.data.readMany("posts", {
  where: { "author.name": "John" },
});
```

## Email OTP plugin
A new authentication plugin for passwordless login using one-time passwords sent via email. The plugin supports both login and registration flows, with configurable TTL, custom email templates, and automatic code invalidation.

```ts
import { emailOTP } from "bknd/plugins";
import { resendEmail } from "bknd";

export default {
   options: {
      plugins: [
         emailOTP({
            generateEmail: (otp) => ({
               subject: "OTP Code",
               body: `Your OTP code is: ${otp.code}`,
            }),
         })
      ],
   },
} satisfies BkndConfig;
```

## Plunk email driver
Added support for [Plunk](https://useplunk.com/) as an email driver, joining Resend as supported transactional email services:

```ts
import { plunkEmail } from "bknd";

export default {
   options: {
      drivers: {
         email: plunkEmail({ 
            apiKey: "<api-key>",
            from: "hello@example.com",
         }),
      },
  }
}
```

Special thanks to @cameronapak for adding this πŸ”₯ 

## SvelteKit adapter
bknd now has first-class support for SvelteKit applications. The new adapter follows the same pattern as the existing Astro and Next.js adapters. Read more in the [SvelteKit integration guide](https://docs.bknd.io/integration/sveltekit). Special thanks to @screenfluent for adding this πŸ”₯ 

## MediaAPI `uploadToEntity` now supports `overwrite`
While already available using the REST endpoints, the SDK itself didn't add an option to specify to overwrite existing media entries. Now it is possible to overwrite existing entries if max items reached:

```ts
const { data } = await api.media.uploadToEntity(
  "pets",
  pet.id,
  "pet_photo",
  file,
  { overwrite: true }  // This parameter
);
```

Special thanks to @jonaspm for adding this πŸ”₯ 

## Run bknd in your browser with SQLocal
You can now run bknd entirely in your browser without any server required. Using [SQLocal](https://sqlocal.dallashoffman.com/), bknd now supports in-browser SQLite databases using OPFS (Origin Private File System), with data persisting locally in your browser. This is perfect for offline-first applications, local development, or demo purposes.

The new `BkndBrowserApp` component wraps everything you need to get started:

```tsx
import { BkndBrowserApp } from "bknd/adapter/browser";
import { Route } from "wouter";

export function App() {
  return (
    <BkndBrowserApp
       config={{
          /* ... your bknd config */
          adminOptions: { basepath: "/admin" }
       }}
       /* add additional options you're used to from `bknd.config.ts` */
       onBuilt={async (app) => {}}
    >
      {/* your routes */}
      <Route path="/" component={() => <div>hello</div>} />
    </BkndBrowserApp>
  );
}
```

Additionally, bknd now includes the `OpfsStorageAdapter` for media storage, allowing full file upload/download support in the browser environment.

## Changelog
* upgrade deps by @dswbx in https://github.com/bknd-io/bknd/pull/290
* upgrade biome and vscode settings by @dswbx in https://github.com/bknd-io/bknd/pull/293
* fix hybrid schema sync by @dswbx in https://github.com/bknd-io/bknd/pull/295
* Update Astro integration documentation by @jonaspm in https://github.com/bknd-io/bknd/pull/296 πŸ”₯
* Update import path for getApi in astro.mdx by @jonaspm in https://github.com/bknd-io/bknd/pull/297 πŸ”₯
* Email Driver: Add Plunk Support by @cameronapak in https://github.com/bknd-io/bknd/pull/294 πŸ”₯
* Fix: cf proxy and modes by @dswbx in https://github.com/bknd-io/bknd/pull/302
* Add Cloudflare Vite templates for fullstack deployments by @dswbx in https://github.com/bknd-io/bknd/pull/303
* fix cli url opener and add minimal debug docker config by @dswbx in https://github.com/bknd-io/bknd/pull/301
* fix: recursive `with` omitted join clauses by @dswbx in https://github.com/bknd-io/bknd/pull/299
* OTP plugin by @dswbx in https://github.com/bknd-io/bknd/pull/292
* fix config reconciliation for specific field types, remove lodash by @dswbx in https://github.com/bknd-io/bknd/pull/311
* Fix UI client import by @dswbx in https://github.com/bknd-io/bknd/pull/307
* fix: putting schema related endpoints behind schema permission and added tests by @dswbx in https://github.com/bknd-io/bknd/pull/312
* feat: Add implicit joins in repository where clauses by @dswbx in https://github.com/bknd-io/bknd/pull/313
* docs: updated react-router and react sdk by @dswbx in https://github.com/bknd-io/bknd/pull/314
* feat: move postgres as part of the main repo by @dswbx in https://github.com/bknd-io/bknd/pull/289
* feat: opfs and sqlocal by @dswbx in https://github.com/bknd-io/bknd/pull/308
* feat: add local auth support if api storage provided by @dswbx in https://github.com/bknd-io/bknd/pull/315
* docs: Add documentation for auth.logout method in SDK usage by @jonaspm in https://github.com/bknd-io/bknd/pull/319 πŸ”₯
* feat: add `default_role_register` and password `minLength` config by @dswbx in https://github.com/bknd-io/bknd/pull/320
* feat(admin): add mcp as main navigation item when enabled, and make it route-aware by @dswbx in https://github.com/bknd-io/bknd/pull/321
* docs: Document data.readOneBy method with usage examples by @jonaspm in https://github.com/bknd-io/bknd/pull/323 πŸ”₯
* change license to apache 2.0 by @dswbx in https://github.com/bknd-io/bknd/pull/331
* feat: add SvelteKit adapter by @screenfluent in https://github.com/bknd-io/bknd/pull/324 πŸ”₯
* fix: Add overwrite option to uploadToEntity method by @jonaspm in https://github.com/bknd-io/bknd/pull/330 πŸ”₯

## New Contributors
* @jonaspm made their first contribution in https://github.com/bknd-io/bknd/pull/296
* @screenfluent made their first contribution in https://github.com/bknd-io/bknd/pull/324

**Full Changelog**: https://github.com/bknd-io/bknd/compare/v0.19.0...v0.20.0