diff --git a/README.md b/README.md
index 0cba095..2d08d83 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ It's designed to avoid vendor lock-in and architectural limitations. Built exclu
* SQLite: LibSQL, Node SQLite, Bun SQLite, Cloudflare D1, Cloudflare Durable Objects SQLite, SQLocal
* Postgres: Vanilla Postgres, Supabase, Neon, Xata
* **Frameworks**: React, Next.js, React Router, Astro, Vite, Waku
-* **Storage**: AWS S3, S3-compatible (Tigris, R2, Minio, etc.), Cloudflare R2 (binding), Cloudinary, Filesystem
+* **Storage**: AWS S3, S3-compatible (Tigris, R2, Minio, etc.), Cloudflare R2 (binding), Cloudinary, Filesystem, Origin Private File System (OPFS)
* **Deployment**: Standalone, Docker, Cloudflare Workers, Vercel, Netlify, Deno Deploy, AWS Lambda, Valtown etc.
**For documentation and examples, please visit https://docs.bknd.io.**
diff --git a/packages/sqlocal/README.md b/packages/sqlocal/README.md
deleted file mode 100644
index 4c09768..0000000
--- a/packages/sqlocal/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# SQLocal adapter for `bknd` (experimental)
-This packages adds an adapter to use a SQLocal database with `bknd`](https://github.com/bknd-io/bknd). It is based on [`sqlocal`](https://github.com/DallasHoff/sqlocal) and the driver included for [`kysely`](https://github.com/kysely-org/kysely).
-
-## Installation
-Install the adapter with:
-```bash
-npm install @bknd/sqlocal
-```
-
-## Usage
-Create a connection:
-
-```ts
-import { SQLocalConnection } from "@bknd/sqlocal";
-
-const connection = new SQLocalConnection({
- databasePath: "db.sqlite"
-});
-```
-
-Use the connection depending on which framework or runtime you are using. E.g., when using `createApp`, you can use the connection as follows:
-
-```ts
-import { createApp } from "bknd";
-import { SQLocalConnection } from "@bknd/sqlocal";
-
-const connection = new SQLocalConnection();
-const app = createApp({ connection });
-```
\ No newline at end of file
diff --git a/packages/sqlocal/package.json b/packages/sqlocal/package.json
deleted file mode 100644
index b25041d..0000000
--- a/packages/sqlocal/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "@bknd/sqlocal",
- "version": "0.0.1",
- "type": "module",
- "main": "dist/index.js",
- "module": "dist/index.js",
- "types": "dist/index.d.ts",
- "publishConfig": {
- "access": "public"
- },
- "scripts": {
- "build": "tsup",
- "test": "vitest --run",
- "updater": "bun x npm-check-updates -ui",
- "typecheck": "tsc --noEmit",
- "prepublishOnly": "bun run typecheck && bun run test && bun run build"
- },
- "dependencies": {
- "sqlocal": "^0.16.0"
- },
- "devDependencies": {
- "@vitest/browser": "^3.0.8",
- "@vitest/ui": "^3.0.8",
- "@types/node": "^24.10.1",
- "bknd": "workspace:*",
- "kysely": "^0.27.6",
- "tsup": "^8.4.0",
- "typescript": "^5.8.2",
- "vitest": "^3.0.8",
- "webdriverio": "^9.12.0"
- },
- "tsup": {
- "entry": ["src/index.ts"],
- "format": ["esm"],
- "target": "es2022",
- "clean": true,
- "minify": true,
- "dts": true,
- "external": ["bknd", "kysely"]
- },
- "files": ["dist", "README.md", "!*.map", "!metafile*.json"]
-}
diff --git a/packages/sqlocal/src/index.ts b/packages/sqlocal/src/index.ts
deleted file mode 100644
index 9ed7173..0000000
--- a/packages/sqlocal/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { SQLocalConnection } from "./SQLocalConnection";
diff --git a/packages/sqlocal/test/base.test.ts b/packages/sqlocal/test/base.test.ts
deleted file mode 100644
index 661c61a..0000000
--- a/packages/sqlocal/test/base.test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { describe, expect, it } from "vitest";
-import { SQLocal } from "sqlocal";
-
-describe("base", () => {
- const { sql } = new SQLocal(":memory:");
-
- it("works", async () => {
- expect(await sql`SELECT 1`).toEqual([{ "1": 1 }]);
- });
-});
diff --git a/packages/sqlocal/test/connection.test.ts b/packages/sqlocal/test/connection.test.ts
deleted file mode 100644
index d95c744..0000000
--- a/packages/sqlocal/test/connection.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { describe, expect, it } from "vitest";
-import { SQLocalConnection } from "../src";
-import type { ClientConfig } from "sqlocal";
-import { SQLocalKysely } from "sqlocal/kysely";
-
-describe(SQLocalConnection, () => {
- function create(config: ClientConfig = { databasePath: ":memory:" }) {
- return new SQLocalConnection(new SQLocalKysely(config));
- }
-
- it("constructs", async () => {
- const connection = create();
- await connection.init();
- expect(connection.client).toBeDefined();
- expect(await connection.client.sql`SELECT 1`).toEqual([{ "1": 1 }]);
- });
-});
diff --git a/packages/sqlocal/test/integration.test.ts b/packages/sqlocal/test/integration.test.ts
deleted file mode 100644
index 3d08558..0000000
--- a/packages/sqlocal/test/integration.test.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { describe, expect, it } from "bun:test";
-import { SQLocalConnection } from "../src";
-import { createApp, em, entity, text } from "bknd";
-import type { ClientConfig } from "sqlocal";
-import { SQLocalKysely } from "sqlocal/kysely";
-
-describe("integration", () => {
- function create(config: ClientConfig = { databasePath: ":memory:" }) {
- return new SQLocalConnection(new SQLocalKysely(config));
- }
-
- it("should create app and ping", async () => {
- const app = createApp({
- connection: create(),
- });
- await app.build();
-
- expect(app.version()).toBeDefined();
- expect(await app.em.ping()).toBe(true);
- });
-
- it("should create a basic schema", async () => {
- const schema = em(
- {
- posts: entity("posts", {
- title: text().required(),
- content: text(),
- }),
- comments: entity("comments", {
- content: text(),
- }),
- },
- (fns, s) => {
- fns.relation(s.comments).manyToOne(s.posts);
- fns.index(s.posts).on(["title"], true);
- },
- );
-
- const app = createApp({
- connection: create(),
- config: {
- data: schema.toJSON(),
- },
- });
-
- await app.build();
-
- expect(app.em.entities.length).toBe(2);
- expect(app.em.entities.map((e) => e.name)).toEqual(["posts", "comments"]);
-
- const api = app.getApi();
-
- expect(
- (
- await api.data.createMany("posts", [
- {
- title: "Hello",
- content: "World",
- },
- {
- title: "Hello 2",
- content: "World 2",
- },
- ])
- ).data,
- ).toEqual([
- {
- id: 1,
- title: "Hello",
- content: "World",
- },
- {
- id: 2,
- title: "Hello 2",
- content: "World 2",
- },
- ] as any);
-
- // try to create an existing
- expect(
- (
- await api.data.createOne("posts", {
- title: "Hello",
- })
- ).ok,
- ).toBe(false);
-
- // add a comment to a post
- await api.data.createOne("comments", {
- content: "Hello",
- posts_id: 1,
- });
-
- // and then query using a `with` property
- const result = await api.data.readMany("posts", { with: ["comments"] });
- expect(result.length).toBe(2);
- expect(result[0].comments.length).toBe(1);
- expect(result[0].comments[0].content).toBe("Hello");
- expect(result[1].comments.length).toBe(0);
- });
-});
diff --git a/packages/sqlocal/tsconfig.json b/packages/sqlocal/tsconfig.json
deleted file mode 100644
index d2359e0..0000000
--- a/packages/sqlocal/tsconfig.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "compilerOptions": {
- "composite": false,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": false,
- "target": "ES2022",
- "noImplicitAny": false,
- "allowJs": true,
- "verbatimModuleSyntax": true,
- "declaration": true,
- "strict": true,
- "allowUnusedLabels": false,
- "allowUnreachableCode": false,
- "exactOptionalPropertyTypes": false,
- "noFallthroughCasesInSwitch": true,
- "noImplicitOverride": true,
- "noImplicitReturns": true,
- "noPropertyAccessFromIndexSignature": false,
- "noUncheckedIndexedAccess": true,
- "noUnusedLocals": false,
- "noUnusedParameters": false,
- "isolatedModules": true,
- "esModuleInterop": true,
- "skipLibCheck": true
- },
- "include": ["./src/**/*.ts"],
- "exclude": ["node_modules"]
-}
diff --git a/packages/sqlocal/vitest.config.ts b/packages/sqlocal/vitest.config.ts
deleted file mode 100644
index 0e3faec..0000000
--- a/packages/sqlocal/vitest.config.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-///
-///
-import { defineConfig } from "vitest/config";
-
-// https://github.com/DallasHoff/sqlocal/blob/main/vite.config.ts
-export default defineConfig({
- test: {
- testTimeout: 1000,
- hookTimeout: 1000,
- teardownTimeout: 1000,
- includeTaskLocation: true,
- browser: {
- enabled: true,
- headless: true,
- screenshotFailures: false,
- provider: "webdriverio",
- instances: [{ browser: "chrome" }],
- },
- },
- optimizeDeps: {
- exclude: ["@sqlite.org/sqlite-wasm"],
- },
- plugins: [
- {
- enforce: "pre",
- name: "configure-response-headers",
- configureServer: (server) => {
- server.middlewares.use((_req, res, next) => {
- res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
- res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
- next();
- });
- },
- },
- ],
-});