Mastering Jotai Vanilla via CDN: A Lightweight State Management for Any Web Project

Mastering Jotai Vanilla via CDN: A Lightweight State Management for Any Web Project
Photo by HANVIN CHEONG / Unsplash

When people talk about state management, they usually mention big frameworks like React, Vue, or Angular. But what if you want reactive state without committing to a full framework?

Enter Jotai Vanilla — a minimal, atomic state management library that doesn’t require React and can even run directly in a plain HTML + JavaScript environment. With v2, Jotai offers a vanilla export that you can use with or without any frontend framework.

In this article, we’ll explore how to use Jotai Vanilla via a CDN, step-by-step, with an increment & decrement counter example.


Why Jotai Vanilla?

While Jotai is often associated with React, its vanilla mode makes it perfect for:

  • Framework-agnostic development (no React needed)
  • Small projects where installing npm packages isn’t worth it
  • Embedding in CMS templates (WordPress, Laravel Blade, etc.)
  • Lightweight widgets that only need a reactive store

Key benefits:

  • Atomic state — each piece of state is isolated and subscribable
  • No boilerplate — no reducers, actions, or complex setup
  • Reactivity — changes trigger updates automatically for subscribed elements

Getting Started via CDN

Unlike React or Vue, Jotai doesn’t ship a UMD file like jotai.min.js. Instead, we can import it as an ES module from a CDN such as:

We’ll lock the version for stability. For example:

import { atom } from "https://esm.sh/[email protected]/vanilla";
import { createStore } from "https://esm.sh/[email protected]/vanilla";

Locking the version prevents unexpected breaking changes when new Jotai versions are released.


Example: Increment & Decrement Counter

Here’s the full working example:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Jotai Vanilla Example</title>
</head>
<body>
  <div id="counter" style="font-size: 2em; margin-bottom: 10px;">0</div>
  <button id="decrement">Decrement</button>
  <button id="increment">Increment</button>

  <script type="module">
    import { atom } from "https://esm.sh/[email protected]/vanilla";
    import { createStore } from "https://esm.sh/[email protected]/vanilla";

    // 1. Create a store
    const store = createStore();

    // 2. Create an atom to hold our count
    const countAtom = atom(0);

    // 3. UI update function
    const updateUI = () => {
      document.getElementById("counter").textContent = store.get(countAtom);
    };

    // 4. Subscribe to atom changes
    store.sub(countAtom, updateUI);

    // 5. Button event listeners
    document.getElementById("increment").addEventListener("click", () => {
      store.set(countAtom, (c) => c + 1);
    });

    document.getElementById("decrement").addEventListener("click", () => {
      store.set(countAtom, (c) => c - 1);
    });

    // 6. Initial render
    updateUI();
  </script>
</body>
</html>
👨‍💻
Demo here.

How It Works

  1. createStore() — creates an isolated Jotai store to hold atoms.
  2. atom(0) — creates an atom with an initial value of 0.
  3. store.get(atom) — retrieves the current atom value.
  4. store.set(atom, updater) — updates the atom value.
  5. store.sub(atom, listener) — subscribes to changes so the UI updates automatically.

Additional Considerations

1. Version Locking

Always lock the Jotai version in your CDN URL. This prevents issues if a future version introduces breaking changes.

2. Performance

For small apps, Jotai Vanilla is extremely lightweight. But if your state grows complex:

  • Use multiple atoms instead of one big state object.
  • Subscribe only where needed to avoid unnecessary re-renders.

3. Persistence

To keep the state across page reloads, integrate with localStorage:

store.sub(countAtom, () => {
  localStorage.setItem("count", store.get(countAtom));
});

// Restore on page load
const saved = localStorage.getItem("count");
if (saved !== null) store.set(countAtom, parseInt(saved, 10));

4. Integration with Frameworks

Even in a CDN setup, you can use Jotai Vanilla with:

  • React
  • Preact
  • Svelte
  • Vue (via wrappers)

This makes it easy to migrate from a pure HTML setup to a full app later.

5. Event Handling

You can manage multiple buttons, inputs, or UI parts from the same atom. Jotai’s subscription model ensures only the subscribed parts update.


When Should You Use Jotai Vanilla via CDN?

  • Quick prototypes — no npm install, no bundler setup.
  • Embeddable widgets — can be dropped into existing sites.
  • Learning purposes — great for understanding atomic state before diving into a full framework.

Finally

Jotai Vanilla is an elegant, minimalistic state management solution that works seamlessly even without a build system.
Using it via CDN keeps things simple and lightweight, perfect for small projects or embedded scripts. With atoms as your building blocks, you can start small (like our counter) and scale up to more complex UIs — all without the overhead of a large framework.

If you’ve been looking for a reactive, framework-free state management option, Jotai Vanilla is absolutely worth exploring.