Skip to content

mono424/spooky

Repository files navigation

Spooky 👻

Warning

UNDER ACTIVE DEVELOPMENT

This project is currently in early development and is NOT in a working state. APIs and features are subject to breaking changes. Do not use in production.

The Reactive, Local-First Framework for SurrealDB.

Spooky simplifies building real-time, offline-capable applications by bridging your SurrealDB database directly to your frontend. It manages synchronization, caching, and reactivity so you can focus on building great user experiences.

✨ Features

  • 🚀 Live Queries: Your UI updates instantly when data changes.
  • 💾 Local-First: Works offline using IndexedDB, syncs when back online.
  • 🛡️ End-to-End Type Safety: Generated TypeScript definitions from your sql schema.
  • ⚡ Optimistic UI: Immediate feedback for user actions while syncing in the background.

📦 Components

  • @spooky/core: The main client SDK.
  • @spooky/client-solid: Bindings for SolidJS (React and other framework bindings coming soon).
  • Spooky CLI: CLI tool to generate type-safe schemas and synchronization logic.

🚀 Getting Started

1. Installation

pnpm add @spooky/client-solid

2. Configuration

Initialize the SyncedDb instance with your generated schema and database configuration.

// src/db.ts
import { SyncedDb, SyncedDbConfig } from '@spooky/client-solid';
import { schema, SURQL_SCHEMA } from './schema.gen'; // Generated by spooky CLI

const dbConfig = {
  logLevel: 'info',
  schema: schema,
  schemaSurql: SURQL_SCHEMA,
  database: {
    namespace: 'my_app',
    database: 'production',
    endpoint: 'ws://localhost:8000/rpc',
    store: 'indexeddb', // Persist data locally
  },
} satisfies SyncedDbConfig<typeof schema>;

export const db = new SyncedDb<typeof schema>(dbConfig);

// Initialize usually in your app entry point
await db.init();

3. Usage (SolidJS Example)

Use the useQuery hook to fetch data reactively.

import { useQuery } from '@spooky/client-solid';
import { db } from './db';

const ThreadList = () => {
  // Queries are automatically reactive!
  const threads = useQuery(() => db.query('thread').select('*').all());

  return (
    <ul>
      <For each={threads.data}>{(thread) => <li>{thread.title}</li>}</For>
    </ul>
  );
};

🛠️ Development

This repository is a monorepo containing the core packages and examples.

  • packages/core: Core logic.
  • example/app-solid: A full-featured reference application.

To run the example:

cd example/app-solid
pnpm install
pnpm dev

About

Offline-first sync engine for Flutter & Solid.js

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors