Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@mszr/idb-dux

A DX/UX-first reimagining of the InstantDB developer experience.

dux keeps Instant's backend intact but rebuilds the authoring and client surface around a single question: what would feel most delightful to use?

Highlights

🔮 Typed perms authoring — definePerms replaces stringly-typed CEL with a schema-aware TypeScript surface. Write rules against real field names and link traversals; it compiles to exactly what Instant accepts. Completions, narrowing, and type errors on the authoring side — before anything reaches the backend.

⛱️ One registration, project-wide types — register your schema once next to defineSchema and every Idb* type utility knows it project-wide. No SomeUtil<AppSchema, 'namespace', { /* finally my shape */ }> threading — just IdbQueryEntity<'todos', { assignee: {} }>.

🍬 q — a typed query builder that goes anywhere — write queries in stores, composables, utilities, and factory callbacks and get completions, field validation, and operator checking at every level. The query object is fully typed before it ever reaches a useQuery or query call.

👽 Typed tx and linking — official linking requires lookup('email', val) with no validation on the field name or value type. dux's .link() knows your schema: link labels are suggested, and field-matched linking (.link({ 'assignee.email': val })) is narrowed to the linked namespace's field types, and validated.

🎈 Errors at the cursor, not the console — the wrong field name, invalid operator, or unknown namespace underlines exactly where the mistake is, with a message that says what's wrong and points you in the right direction. Completions and diagnostics are regression-tested with selenita so your DX has the same guarantees as runtime behaviors.

💫 Results without ceremony — query scopes arrive typed and normalized: arrays are never undefined; $only narrows a scope to T | undefined so you never reach for ?.[0]; $as and $m let you reshape in the query instead of after it.

👻 SSR-resilient by default — every hook returns safe inert state on the server and activates full subscriptions on the client. Zero configuration. Full support incoming when upstream marks SSR stable.

Install

npm install @mszr/idb-dux

@instantdb/core comes along as a dependency. Everything else is an optional peer you add only for the entrypoints you use:

npm install vue                          # for /vue
npm install @instantdb/admin             # for /admin
npm install @instantdb/webhooks          # for /webhooks
npm install @instantdb/admin @instantdb/webhooks       # for /server
npm install @instantdb/admin @instantdb/webhooks h3    # + the /h3 adapter (h3 v2)
# swap h3 for hono or elysia to use those adapters instead

The root and /perms need no peers.

The shape

One package, one framework-agnostic root, and thin overlays on it — including a server plane that works the same whether you reach for h3, Hono, or Elysia.

Entrypoint What it is
@mszr/idb-dux schema authoring (defineSchema, i), query authoring (q), typed tx, the Idb* type utilities
@mszr/idb-dux/perms typed CEL authoring (definePerms) — compiles to the rules object Instant already accepts
@mszr/idb-dux/admin the full server surface over @instantdb/admin
@mszr/idb-dux/webhooks webhook handling + management — admin-free by design
@mszr/idb-dux/vue the Vue client: init, defineDb, the enhanced db, components — SSR-resilient by default
@mszr/idb-dux/server the server plane's framework-agnostic core + adapter port: defineServerKit, defineAuthSyncHandler, defineWebhookHandler
@mszr/idb-dux/h3 · /hono · /elysia thin adapters — the same three utilities, native to your framework (/h3 covers h3 v2, Nitro 3, Nuxt 5, and h3-dux)

sideEffects: false and disjoint module graphs mean a Vue-only app pays zero bytes for the server planes, and a webhook-only worker installs nothing from the Vue stack. Subpath-only dependencies (vue, h3, hono, elysia, @instantdb/admin, @instantdb/webhooks) are optional peers — you install only what your entrypoints need.

A taste

// Queries destructure directly — no unwrapping, no ?? [] massaging
const { workspace, todos } = db.useQuery({
  workspaces: { $: { where: { id: workspaceId }, $only } }, // Workspace | undefined (automagically singularized, customizable)
  todos: {}, // Todo[] — never undefined
})
// One declaration; every Idb* type utility and `q` know your schema project-wide
declare module '@mszr/idb-dux' {
  interface IdbRegister { schema: typeof schema }
}

Editor tip — smoother where dot-paths

dux completes linked dot-paths in where clauses up to three hops (memberships, memberships.user, memberships.user.email). For the nicest experience, turn off accept-on-commit-character in your editor:

// VS Code settings.json
"editor.acceptSuggestionOnCommitCharacter": false

Otherwise typing . to continue a path (memberships.user.) auto-accepts the highlighted suggestion instead of letting you keep going. With it off, Tab / Enter / arrow keys still accept completions exactly as you'd expect.

The one hard contract

dux owes behavioral compatibility to Instant's backend, not API compatibility to Instant's SDKs. Everything dux emits — schema shapes for the CLI, perms CEL, wire queries — is something Instant already accepts. Inside that envelope, dux is free to reimagine the ergonomics.

Development

The public idb-dux repo is the package and demo face, not the standalone development workspace. Build, test, release, and demo-resolution commands live in the dux maintainer workspace inside the Instant fork: client/packages/dux (public link | local fork path).

Docs

About

A delightful reimagining of the InstantDB developer experience

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages