PromptHub
Back to Blog
Developer Tools Backend Development

bknd: The Secret Backend Tool Killing Firebase Lock-in

B

Bright Coding

Author

14 min read 51 views
bknd: The Secret Backend Tool Killing Firebase Lock-in

bknd: The Secret Backend Tool Killing Firebase Lock-in

What if I told you that your next backend doesn't need to live on someone else's servers? That you could spin up a complete visual backend—with database management, authentication, media storage, and workflows—inside your own Next.js↗ Bright Coding Blog app, on Cloudflare's edge, or even bundled with your React Router project? No separate deployments. No vendor lock-in. No praying that Firebase doesn't change their pricing again.

Most developers have been trapped in a false dichotomy: either wrestle with raw databases and auth libraries for weeks, or surrender your data to proprietary platforms like Firebase and Supabase. The first path burns time you don't have. The second burns freedom you'll regret losing. But what if there's a third option that gives you the speed of a backend-as-a-service with the control of self-hosted infrastructure?

Enter bknd—the open-source backend framework that's making experienced developers question why they ever accepted platform lock-in. Built to run literally anywhere JavaScript↗ Bright Coding Blog runs, bknd delivers what previously required three separate services in a single, lightweight package. And the best part? Your data stays yours.

What is bknd?

bknd is a lightweight Firebase/Supabase alternative designed to run anywhere JavaScript executes. Created by the team at bknd-io, this open-source project reimagines backend development↗ Bright Coding Blog by providing a fully functional visual backend system that handles database management, authentication, media handling, and workflow automation—all while avoiding the architectural limitations and vendor lock-in that plague proprietary platforms.

The project is currently under active development (pre-1.0), which means rapid innovation but also potential breaking changes. It requires Node.js 22.13 or higher due to its use of the node:sqlite module, positioning it firmly on the cutting edge of JavaScript runtime capabilities.

What makes bknd genuinely different is its foundation on the WinterTC Minimum Common Web Platform API—a set of web standards designed for universal compatibility across JavaScript runtimes. This isn't marketing fluff. It means bknd runs identically whether you're deploying to Node.js, Bun, Deno, Cloudflare Workers, Vercel Edge Functions, or even the browser itself. No shim layers. No compatibility nightmares. Just standards-compliant code that works.

Every piece of functionality is modular and opt-in. Don't need media storage? Don't import it. Want only the data layer? Configure just that. This compositional approach keeps bundle sizes minimal—around 300 kB gzipped for a complete API deployment on Cloudflare Workers—while giving you precisely the backend primitives your application demands.

The architecture uses adapter-based infrastructure access with direct driver exposure, meaning you maintain full control over underlying databases and storage systems without abstraction layers hiding critical details from you.

Key Features That Separate bknd from the Pack

Instant REST API Generation

Define your data models through the visual admin interface or code, and bknd immediately exposes a complete REST API with querying, filtering, pagination, and relationship handling. The API follows OpenAPI specifications, enabling automatic client generation and predictable integration patterns.

Visual Database Management

The integrated admin UI provides graphical schema design, data exploration, and configuration management. No SQL required for basic operations—though direct database access remains available when you need it. This bridges the gap between no-code convenience and developer control.

Authentication Without Complexity

Implement reliable auth strategies through modular components that handle sessions, JWT tokens, social providers, and role-based access control. The system supports multi-tenant data isolation through Row-Level Security (RLS), critical for SaaS applications serving multiple organizations.

Media & Storage Abstraction

Unified media handling across AWS S3, Cloudflare R2, Cloudinary, filesystem storage, and Origin Private File System (OPFS). Upload once, serve anywhere. The storage adapters handle URL generation, transformations, and access control transparently.

Workflow Automation (Flows)

Design and execute automated workflows triggered by data changes, API calls, or scheduled events. While UI integration for flows is still incoming, the programmatic API enables sophisticated backend automation already.

MCP Server Integration

Built-in Model Context Protocol server, client, and UI components enable AI agent backends to communicate with your backend state—positioning bknd as infrastructure for the emerging AI application ecosystem.

Type-Safe SDK & React Hooks

The official TypeScript SDK provides compile-time safety for all API operations, while React-specific hooks (useApi, useEntity, useApiQuery, useEntityQuery) with SWR integration handle caching, invalidation, and optimistic updates automatically.

Real-World Use Cases Where bknd Dominates

Content Management System (CMS)

Replace WordPress↗ Bright Coding Blog or headless CMS platforms by embedding bknd directly in your frontend or hosting it separately. The visual admin interface gives content editors graphical tools while developers retain API access. Perfect for marketing sites, documentation platforms, and editorial workflows where non-technical users need data control.

AI Agent Backends

Manage persistent agent state with built-in data storage regardless of hosting environment. The integrated MCP server enables AI agents to query and modify backend state through standardized protocols. Build retrieval-augmented generation systems, agent memory stores, and multi-step reasoning pipelines without managing separate vector databases.

SaaS Products with Multi-Tenancy

Ship multi-tenant applications with confidence using Row-Level Security for data isolation between customers. Choose your own PostgreSQL↗ Bright Coding Blog provider (Supabase, Neon, Xata, or vanilla Postgres) and storage backend. Escape the pricing traps of proprietary BaaS platforms while maintaining enterprise-grade security boundaries.

Rapid Prototyping & MVPs

Validate ideas in hours, not weeks. The npx bknd run command spins up a complete backend instantly. Iterate on data models through the visual interface, add authentication with a few lines of code, and deploy to Vercel or Netlify without infrastructure configuration. When validation succeeds, the same codebase scales to production.

API-First Applications

Build reliable, type-safe backends for mobile apps, third-party integrations, or microservices. Consume the REST API directly with OpenAPI documentation, or use the TypeScript SDK for internal services. The modular architecture lets you expose only the endpoints your consumers need.

IoT & Embedded Deployments

The minimal footprint—approximately 300 kB gzipped for core API functionality—enables deployment on resource-constrained devices. Run SQLite locally on edge hardware, sync to central PostgreSQL when connectivity permits, and manage device authentication through the same system controlling your cloud infrastructure.

Step-by-Step Installation & Setup Guide

Prerequisites

Ensure you're running Node.js 22.13 or higher. Verify with:

node --version
# Must output v22.13.0 or greater

Quick Start (Zero Configuration)

The fastest path to a running backend:

# Spin up bknd instantly with npx
npx bknd run

This launches the complete backend with admin UI, API endpoints, and SQLite database—no configuration required.

Project Installation

For integration into existing projects:

# Install via npm
npm install bknd

# Or with Bun
bun add bknd

# Or with Deno
import { ... } from "npm:bknd";

Runtime-Specific Setup

Node.js Server:

// index.js — Minimal Node.js server
import { serve } from "bknd/adapter/node"

// Starts API server with default configuration
// Serves on PORT env variable or default port
serve();

Run with:

node index.js

Next.js Integration:

// app/admin/page.tsx — Embedded admin interface
import { Admin } from "bknd/ui"
import "bknd/dist/styles.css";

export default function AdminPage() {
   // Full visual backend management in your app
   return <Admin />
}

Cloudflare Worker:

// worker.ts — Edge-deployed backend
import { serve } from "bknd/adapter/cloudflare"

export default {
   async fetch(request, env, ctx) {
      return serve(request, { binding: env.DB })
   }
}

Database Configuration

bknd auto-detects available database drivers. For explicit configuration:

import { createApp } from "bknd"

const app = createApp({
   connection: {
      // SQLite variants
      type: "libsql",           // Turso/LibSQL
      // type: "bun-sqlite",    // Bun native
      // type: "d1",            // Cloudflare D1
      
      // PostgreSQL variants  
      // type: "postgres",      // Vanilla Postgres
      // type: "neon",          // Neon serverless
      url: process.env.DATABASE_URL
   }
})

Environment Variables

# Required minimum
DATABASE_URL="file:./data.db"     # SQLite default
# DATABASE_URL="postgres://..."   # PostgreSQL alternative

# Optional enhancements
JWT_SECRET="your-256-bit-secret"
STORAGE_ENDPOINT="https://..."     # S3-compatible storage

REAL Code Examples from bknd

Let's examine production-ready patterns from the official repository, with detailed explanations of what each accomplishes.

Example 1: Minimal Node.js API Server

// index.js — Production Node.js deployment
import { serve } from "bknd/adapter/node"

// This single function call initializes:
// - REST API with auto-generated CRUD endpoints
// - Authentication system with session/JWT support
// - Admin UI served at /admin path
// - SQLite database using node:sqlite (Node 22.13+)
serve();

What's happening here? The serve adapter from bknd/adapter/node encapsulates all backend initialization. It detects your environment, establishes database connections, mounts API routes, and serves the admin interface. In production, you'd pass configuration options for database URLs, JWT secrets, and feature flags. The adapter pattern means identical code works across runtimes—swap bknd/adapter/node for bknd/adapter/bun or bknd/adapter/cloudflare with zero application code changes.

Example 2: Embedded React Admin Interface

// app/admin/page.tsx — Next.js App Router integration
import { Admin } from "bknd/ui"
import "bknd/dist/styles.css";

export default function AdminPage() {
   // Renders complete visual backend management:
   // - Schema designer with drag-and-drop fields
   // - Data browser with filtering and pagination
   // - User management and role configuration
   // - Media library with upload and transformation
   // - System settings and environment monitoring
   return <Admin />
}

The power of this pattern: Your admin interface lives inside your application routing structure, protected by your existing authentication middleware. No separate deployments, no CORS configuration, no subdomain management. The CSS import provides the complete design system—customize via CSS variables or override specific classes. For React Router or Astro, the identical component import works with your framework's routing conventions.

Example 3: TypeScript SDK with React Query Integration

// components/TodoList.tsx — Type-safe data fetching
import { useState } from "react";
import { useEntityQuery } from "bknd/client";

export default function App() {
   // useEntityQuery wraps SWR for automatic:
   // - Cache invalidation on mutations
   // - Stale-while-revalidate freshness strategy
   // - Error retry with exponential backoff
   // - Type inference from your schema definition
   const { data, error, isLoading } = useEntityQuery("todos");
   
   if (isLoading) return <div>Loading tasks...</div>;
   if (error) return <div>Failed to load: {error.message}</div>;
   
   return (
      <ul>
         {data?.map(todo => (
            // Full TypeScript intellisense on todo properties
            // Based on your actual "todos" entity schema
            <li key={todo.id}>{todo.name}</li>
         ))}
      </ul>
   )
}

Why this matters: Traditional REST integrations require manual cache management and type definition maintenance. The useEntityQuery hook derives types from your live backend schema—change a field in the admin UI, and TypeScript immediately reflects it. The SWR integration means your UI stays fresh without explicit refresh logic, while mutations automatically invalidate dependent queries.

Example 4: Media Upload Without API Complexity

// components/UserAvatar.tsx — Drop-in media handling
import { Media } from "bknd/elements"
import "bknd/dist/main.css"

export function UserAvatar() {
   return (
      <Media.Dropzone
         // Links upload to specific entity field
         entity={{ name: "users", id: 1, field: "avatar" }}
         maxItems={1}        // Restrict to single file
         overwrite           // Replace existing on new upload
      />
   )
}

The developer experience breakthrough: No upload endpoint implementation. No presigned URL generation. No multipart form handling. The Media.Dropzone component communicates directly with bknd's media API, handles progress indication, manages the entity relationship, and triggers UI updates. The same component adapts to your configured storage backend—local filesystem in development, S3 in production—without code changes.

Example 5: Raw REST API Access

# Direct API consumption for non-JS environments
curl -XGET https://your-app.com/api/data/entity/todos

Response structure:

{
  "data": [
    { "id": 1, "name": "Ship v1", "completed": false },
    { "id": 2, "name": "Write docs", "completed": true }
  ],
  "meta": { 
    "total": 2,
    "page": 1,
    "perPage": 50
  }
}

Equivalent TypeScript SDK usage:

import { Api } from "bknd/client";

const api = new Api({ host: "https://your-app.com" });

// Fully typed response based on entity schema
const { data, meta } = await api.data.readMany("todos");

// Typed query parameters with validation
const filtered = await api.data.readMany("todos", {
   where: { completed: false },
   sort: { created_at: "desc" },
   limit: 10
});

Advanced Usage & Best Practices

Schema-Driven Development

Design your data model in the visual admin first, then export TypeScript definitions for frontend consumption. This "schema-first" approach eliminates API contract mismatches between frontend and backend teams.

Adapter Selection Strategy

Choose adapters based on deployment target, not development preference. The bknd/adapter/node adapter optimizes for long-running processes with connection pooling. Cloudflare and Vercel adapters optimize for cold-start latency and request-scoped execution. Benchmark with your actual query patterns before committing.

Database Migration Handling

While bknd auto-migrates schema changes in development, production deployments should use explicit migration scripts. Extract SQL from the admin interface's schema inspector, version control migrations, and apply through your CI/CD pipeline.

Authentication Hardening

Enable Row-Level Security early in development, not as an afterthought. Define RLS policies in code alongside your schema definition—visual configuration is convenient but code-reviewed policies are auditable. Rotate JWT secrets through environment variable updates without redeployment.

Bundle Optimization

Import only what you need. The bknd package includes CLI, UI components, and static assets. For API-only deployments, tree-shake unused UI code. For frontend-only SDK usage, import bknd/client without pulling backend dependencies.

Comparison with Alternatives

Capability bknd Firebase Supabase Direct Node.js/Express
Self-hosted / Edge deployable ✅ Any runtime ❌ Google only ⚠️ Partial ✅ Anywhere
Visual admin interface ✅ Built-in ✅ Firebase Console ✅ Studio ❌ Build yourself
Database flexibility ✅ SQLite, Postgres, multiple providers ❌ Firestore only ⚠️ Postgres only ✅ Unlimited
Authentication included ✅ Modular, multi-strategy ✅ Built-in ✅ Built-in ❌ Implement manually
Type-safe client SDK ✅ Auto-generated ⚠️ Limited ✅ Partial ❌ Manual
Vendor lock-in risk ✅ None (open source, standards-based) ❌ High ⚠️ Medium ✅ None
Bundle size (minimal API) ~300 kB gzipped N/A (client SDK) ~500 kB+ Varies wildly
React framework integration ✅ Native (Next.js, Router, Astro) ⚠️ SDK only ⚠️ SDK only ❌ Build yourself
AI/ MCP integration ✅ Built-in ❌ None ❌ None ❌ Build yourself
Pricing model Free (self-hosted) Usage-based, can spike Usage-based, can spike Infrastructure costs only

When to choose bknd over Firebase: You need deployment flexibility, worry about vendor lock-in, want SQLite for edge deployments, or require MCP/AI integration.

When to choose bknd over Supabase: You want lighter weight, need to run inside your framework (not alongside it), or require broader runtime support beyond Node.js.

When to choose bknd over DIY Express: You value development velocity, want visual data management for team members, and need auth/media without weeks of implementation.

Frequently Asked Questions

Is bknd production-ready?

bknd is pre-1.0 with active development. Core features are stable, but breaking changes may occur. The maintainers recommend it for new projects willing to track updates, with production use requiring thorough testing of your specific configuration.

Can I migrate from Firebase or Supabase to bknd?

Yes, though migration complexity varies. Firebase Firestore data exports to JSON can be imported into bknd's SQLite or Postgres backends. Authentication users require password reset flows since hashes aren't portable. The REST API structure differs, so client code needs updates.

Does bknd support real-time subscriptions like Firebase?

Real-time functionality is on the roadmap but not yet implemented. Current applications requiring live updates should implement polling with the SWR hooks or use Server-Sent Events through custom routes.

How does bknd handle scaling?

SQLite deployments scale vertically and through read replicas. PostgreSQL deployments leverage your chosen provider's scaling (Neon serverless, Supabase, etc.). The stateless API design enables horizontal scaling of application instances behind load balancers.

Can I use bknd with non-React frontends?

Absolutely. The REST API works with any HTTP client. The bknd/client SDK is JavaScript/TypeScript-specific, but Vue, Svelte, Angular, mobile apps, and server-to-server communication use standard fetch/axios against documented endpoints.

What happens to my data if bknd development stops?

Your data lives in standard SQLite or PostgreSQL databases—fully portable. The REST API follows OpenAPI conventions. Migration to alternative backends requires endpoint mapping but zero data transformation. This is the anti-lock-in promise in practice.

Is there commercial support available?

Currently community-supported through Discord and GitHub issues. Enterprise support arrangements are not publicly advertised; reach out to maintainers for specific needs.

Conclusion

The backend landscape has been stuck in a frustrating paradox: powerful platforms demand your data and freedom, while flexible tools consume your time and sanity. bknd shatters this false choice.

By building exclusively on web standards, embracing modular architecture, and delivering genuine deployment portability, bknd represents what backend development should have been all along—fast enough for prototypes, robust enough for production, and free enough for your future. The visual admin interface removes friction for teams. The TypeScript SDK eliminates API guesswork. The adapter system future-proofs your deployment strategy.

Is it perfect? Not yet—the pre-1.0 status means active evolution, and real-time features remain pending. But the foundation is technically sound, the momentum is genuine, and the philosophy of "primitives, not platforms" resonates with developers burned by past platform decisions.

If you're starting a new project, prototyping an idea, or simply exhausted by infrastructure complexity, clone the bknd repository today. Run npx bknd run. Experience what backend development feels like when the tool serves you, not the other way around. Your future self—deploying to an edge function on a platform that doesn't exist yet—will thank you.

Star the repo, join the Discord, and build something that lasts.

Comments (0)

Comments are moderated before appearing.

No comments yet. Be the first to share your thoughts!

Recommended Prompts

View All