Skip to content

Repository files navigation

baseConfig

GitHub Workflow Status   npm downloads   npm   npm   La niina Twitter   views


baseconfig

The edge native, local first content
management system for
TanStack Start.

Build content-driven apps without managing another backend.
Define your content in code, deploy everything to a single Cloudflare Worker,
and edit locally with changes only published when you're ready.


[!WARNING] baseConfig is under active development.
The project is currently in **0.x**. While the core is functional, APIs,
field types, and behavior may change before the
first stable release. It's not yet recommended for production use.

Why baseConfig?

  • Edge-native Runs entirely on Cloudflare. Your website, CMS, API, and media library deploy together as a single Worker.

  • 💾 Local-first editing Write without worrying about your connection. Changes stay on your device until you choose to publish.

  • 🧩 Config-driven Describe your collections, globals, and fields in TypeScript. Your configuration becomes your CMS.

  • 📦 Batteries included Collections, globals, rich text, blocks, relationships, media, authentication, and plugins in one place.

  • 🔌 Built to extend Create your own fields, blocks, endpoints, hooks, and plugins without fighting the framework.

Quick Start

Starting a brand new project:

bunx @baseconfig/cli my-app

Follow the prompts (project name, D1/R2/KV resource names), then:

cd my-app
bun run local   # generate schemas + migrate a local D1
bun run dev

Adding baseConfig to an existing TanStack Start project instead:

bun add @baseconfig/core @baseconfig/ui hono drizzle-orm better-auth

Define your content model, mount the handler, and you're ready to go.

export default baseConfig({
  collections: [...],
  globals: [...],
})

That's it.

baseConfig automatically provides:

  • Content API - Mounted to /api/$.ts
  • Admin dashboard - Mounted to /admin or whatever path you prefer
  • Media library - Pass the binding
  • Authentication - But based on your own better auth setup
  • File uploads - Fully setup to work with R2
  • Storage - Pass R2 Binding
  • Dashboard - Covered in admin/$.ts catch all

All running from the same Cloudflare Worker.

Roadmap

  • ~20 field types (text, textarea, richtext, checkbox, switch, date, keywords, upload, select, combobox, radio, email, number, password, confirmPassword, hidden, code, json, slug, point), plus composite types (array, blocks, relationship, relations, meta, menu, links) and layout-only types (row, collapsible, group, tabs-as-field, ui)
  • Real D1-backed content persistence, one table per collection/global
  • Local-first drafting (edits live in localStorage until published)
  • 7 built-in page blocks (richtext, media, cta, banner, grid, code, relatedPosts)
  • Plugin system (endpointFactories/hooks/blocks) with a reference plugin (@baseconfig/plugin-form-builder)
  • R2-backed media library
  • Project-scaffolding CLI (@baseconfig/cli), with two reference templates (basics, a minimal end-to-end app; pharmacy, a fuller e-commerce-style example)
  • Generated per-collection/global TypeScript types (base.types.ts), giving base.find/findByID/findGlobal full type safety
  • Field pruning: reconciles stored data against the current schema, dropping anything left over from a renamed/removed field (an explicit admin "Prune" action, plus automatic reconciliation of local drafts)
  • Collection/global-level access control (Payload-style access: {create, read, update, delete} functions per collection, {read, update} per global; unset means open, matching Payload's own default)
  • Local API parity: createLocalAPI() (@baseconfig/core/api), an in-process find/findByID/create/update/delete/prune/findGlobal/updateGlobal/pruneGlobal client for server functions/loaders in the same Worker, no HTTP round-trip, overrideAccess defaulting to trusted (matching Payload's own Local API)
  • join field (virtual, reverse-relationship queries)
  • Field-level unique/index (blocked on every field currently living in one opaque data JSON column rather than its own SQL column)
  • Field-level conditional visibility (show/hide a field based on a sibling field's value)
  • virtual fields (computed, not stored)
  • Field-level validate/hooks/access (collection/global-level access is done, see above; field-level is a distinct, still-open piece)
  • A sidebar layout option for the document editor

Technologies we use & love

TanStack Start Cloudflare Turborepo Better Auth Claude Code Bun Drizzle ORM Git shadcn/ui

License

MIT

👏 Thanks to all our contributors

About

Build content driven apps with a config driven cms for tanstack start. local first editing, edge-first architecture, no separate backend.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages