A Reactive JavaScript Framework

2 points | by kwy404 an hour ago

2 comments

  • bitpush an hour ago

    Hows this different from htmx?

  • kwy404 an hour ago

    I've been building a JavaScript framework called *Voodoo.js*. I'd rather get torn apart in the comments than hear that it looks cool.

    It started with one question: how much JavaScript do we really need for everyday interactive interfaces?

    For a lot of apps I don't want a component tree, a bundler, five libraries and state managed elsewhere, all wired back into HTML. Sometimes I just want to keep writing HTML.

    ## The 30-second version

    ```html <div v-data="{ count: 0 }"> <button @click="count--">-</button> <strong>{ count }</strong> <button @click="count++">+</button> </div> ```

    No `querySelector`. No `addEventListener`. No Virtual DOM. Voodoo observes the real DOM and connects HTML directives to a fine-grained reactive system built on `Proxy`.

    ## Why another JS framework?

    Voodoo isn't trying to replace React, Vue or Svelte. The target is projects where the server already renders the HTML — Laravel, Django, Rails, PHP, Go templates — plus small frontends where a full SPA is overkill.

    Philosophically it sits near Alpine.js, HTMX and petite-vue. The difference I was chasing: HTTP, forms, validation, state, components, routing and reactivity should feel like one system, not five glued together.

    ## Declarative HTTP

    Instead of wiring a button by hand:

    ```js button.addEventListener('click', async () => { if (!confirm('Delete user?')) return await fetch('/api/users/42', { method: 'DELETE' }) showToast('User deleted') }) ```

    You declare the intent:

    ```html <button v-delete="/api/users/42" v-confirm="Delete this user?" v-toast-success="User deleted"> Delete </button> ```

    Forms work the same way:

    ```html <form v-submit="/api/users" v-validate v-toast-success="User saved"> <input name="email" type="email" required> <button type="submit">Save</button> </form> ```

    The goal isn't to remove JavaScript. It's to stop writing JavaScript that only restates what the HTML already says. When you need more, plain JS is right there.

    ## No `eval()`, no `new Function()`

    The lazy way to implement `@click="count++"` is `eval()`. Voodoo does neither: expressions go through a real engine — Lexer → Pratt Parser → AST → Interpreter — parsed and interpreted by Voodoo itself, so the framework controls what syntax is supported and what expressions can reach.

    ## Fine-grained reactivity

    The reactive layer uses `Proxy`, tracking dependencies per object and per property. No Virtual DOM diff — the real DOM is patched directly. The API should feel familiar:

    ```js reactive() ref() computed() watch() watchEffect() effectScope() toRaw() markRaw() ```

    It runs from a plain `<script>` tag with no build step, or as ESM: `import { reactive } from 'voodoojs/reactivity'`.

    ## Where it fits

    Server-rendered HTML + Voodoo.js → reactive interface. In Laravel:

    ```blade @foreach($users as $user) <button v-delete="/users/{{ $user->id }}" v-confirm="Delete user?"> Delete </button> @endforeach ```

    The backend keeps rendering the app. No separate frontend application.

    ## The honest part

    What began as an experiment grew into reactivity, directives, components, stores, HTTP, forms, validation, routing, i18n, charts, devtools and a CLI. That growth is now the problem. It doesn't need more features — it needs stability: security hardening, parser edge cases, tests, API stability, benchmarks, docs.

    I'd rather ship a small set of features people can trust in production than a huge one nobody can.

    ## What I'm asking for

    If you work with Alpine.js, HTMX, Vue, petite-vue, Stimulus or Livewire:

    1. What would stop you from using this? 2. Which parts of the API feel intuitive? 3. Which feel unnecessary? 4. What would you need before calling it production-ready?

    If something looks questionable in the architecture, API or security model, tell me. That's the feedback I need.

    *GitHub:* https://github.com/kwy404/Voodoo.js