Getting started

What Voodoo.js is and when to use it

Voodoo.js is the HTML-first JavaScript framework: you build reactive applications straight in the HTML, describing the behaviour of the page in attributes. It was built for the middle ground: pages that need real interactivity, but that do not justify turning into a whole JavaScript application.

The problem it solves

You want a list that filters, a form that validates and submits over AJAX, a modal and a success message. Four ordinary behaviours, and there are two well-worn roads to get there.

Down the jQuery road, each one turns into a handful of addEventListener calls, selectors and manual DOM work. It works, and six months later nobody knows which snippet writes into which element.

Down the Vue or React road, each one turns into a component — and with it come a build step, a bundler, a config file and a dependency folder weighing hundreds of megabytes. For one page. That was already HTML.

Voodoo's answer is the third road: the attributes describe the behaviour, and the library takes care of the rest.

What you wantWhat you write
A counter that reacts<button @click="n++">
Show it when signed in<div v-show="loggedIn">
Repeat a list<li v-for="u in users">
A field bound to state<input v-model="search">
Load data from an API<div v-get="/api/users" v-target="#list">
A validated AJAX form<form v-submit="/api/users" v-validate>
A CPF mask<input v-mask="cpf">
Confirm before deleting<button v-delete="/api/x" v-confirm="Delete?">
A success message<button @click="$toast.success('Saved!')">
A sound on click<button v-sound="click">
A line chart<div v-chart="{ type: 'line', data: sales }">
State that survives F5<div v-data="{...}" v-persist="draft">

What it does differently

The HTML ends up clean

Once a directive has been processed, the v-* attribute leaves the document. In the browser inspector you see <button>Save</button>, not <button v-click="save()" v-loading="#spin">. The behaviour keeps working because the value is held in the runtime.

Practical consequence

Never write CSS or a querySelectorAll that leans on selectors like [v-tab]: by the time you look, the attribute is already gone. Use classes or data-*, which stay. If you need the old behaviour, you can turn this off in V.config.cleanAttributes.

No eval and no new Function

Attribute expressions go through a lexer, a Pratt parser and a tree interpreter written by hand. The library runs under a restrictive Content Security Policy, with no unsafe-eval. That also explains why an expression accepts less than full JavaScript: there is no function, there is no new, and the globals it exposes are a closed list.

Granular updates, with no Virtual DOM

Tracking is per key. When count changes, only the effects that read count run again, and each effect writes only into the node it created itself. There is no virtual tree to diff, and no whole-component render because of one number.

Interpolation with a single brace

{ variable } is the standard form. {{ variable }} is accepted too, for anyone coming from Vue whose fingers are already trained.

<div v-data="{ n: 3 }">
  <p>One brace: { n * 2 }</p>
  <p>Two braces: {{ n * 2 }}</p>
</div>

Zero runtime dependencies

No React, Vue, lodash, jQuery or Axios underneath. Only browser APIs. The file you download is the whole project.

Who it is for

When not to use it

Worth saying plainly, because picking the wrong tool is expensive later.

An honest comparison

Voodoo.jsAlpine.jsHTMXVue 3React 19jQuery
Gzipped size42 to 124 KB15 KB14 KB34 KB45 KB30 KB
Needs a buildNoNoNoRecommendedYesNo
ReactivityYesYesNoYesYesNo
ComponentsYesLimitedNoYesYesNo
Declarative HTTPYesNoYesNoNoNo
Forms and validationIncludedNoNoLibraryLibraryPlugin
Field masksIncludedNoNoLibraryLibraryPlugin
UI components29 ready-madeNoNoLibraryLibraryjQuery UI
ChartsIncludedNoNoLibraryLibraryPlugin
Spring animationIncludedNoNoLibraryLibraryBasic
RouterIncludedNoPartialOfficialLibraryNo
Works under a strict CSPYesNoYesWith a buildYesYes
EcosystemNewMediumMediumHugeHugeHuge

The honest reading: Alpine and HTMX are smaller because they do less. Vue and React have an ecosystem, tooling and a community that Voodoo does not have. What Voodoo delivers, in one file, is the set you would normally assemble out of five libraries.

What does not exist yet

This list is here so that nobody goes hunting through the documentation for something that has not been delivered.

Roadmap

The common problems page lists, separately, the known details that are waiting on a fix and how to work around each one in the meantime.