Mastro 👨‍🍳
GitHub   Bluesky

Installing Reactive Mastro

There are basically two ways to install Reactive Mastro. Using a package manager, or using the pre-bundled file from the CDN.

Using a package manager

If your project uses Node.js and a bundler, you can add the mastro package as a dependency. For example using npm/npx and JSR’s npm compatibility layer:

npx jsr add @mastrojs/mastro

Or with any of the following package managers:

pnpm add jsr:@mastrojs/mastro
yarn add jsr:@mastrojs/mastro
deno add jsr:@mastrojs/mastro

Then, for example using the Astro web framework, you can use Reactive Mastro in a .astro component like:

<my-counter>
  Count is <span data-bind="count">0</span>
  <button data-onclick="inc">+</button>
</my-counter>

<script>
  import { ReactiveElement, signal } from "@mastrojs/mastro/reactive"

  customElements.define("my-counter", class extends ReactiveElement {
    count = signal(0)
    inc () {
      this.count.set(c => c + 1)
    }
  })
</script>
Copied!

(This will usually bundle Reactive Mastro together with your own JavaScript. That means one http request less, but it also means that every time you change your JavaScript, the whole bundle changes and its cache is invalidated.)

Using the file from the CDN

If you don’t want to deal with the complexities of a bundler, you can use the version pre-bundled and minified by esm.sh. Import it as a JavaScript module, for example:

<script type="module">
  import { ReactiveElement, signal } from "https://esm.sh/jsr/@mastrojs/mastro@0.1.0/reactive?bundle"
Copied!

Instead of referencing the esm.sh CDN directly, you can of course also download Reactive Mastro and host it together with your other static assets.

Either way, we recommend using an import map so that you can refer to the file in all your own JavaScript modules using the shorthand mastro/reactive. That way, there is only one place to update the version number, and changing it will not change your own JavaScript files, which would invalidate their cache.

Here’s a complete example that you can save as a .html file and open it in your browser by double clicking:

<!doctype html>
<html lang="en">
  <head>
    <title>Counter</title>
    <script type="importmap">
      {
        "imports": {
          "mastro/reactive": "https://esm.sh/jsr/@mastrojs/mastro@0.1.0/reactive?bundle"
        }
      }
    </script>
  </head>
  <body>
    <my-counter>
      Count is <span data-bind="count">0</span>
      <button data-onclick="inc">+</button>
    </my-counter>

    <script type="module">
      import { ReactiveElement, signal } from "mastro/reactive"

      customElements.define("my-counter", class extends ReactiveElement {
        count = signal(0)
        inc () {
          this.count.set(c => c + 1)
        }
      })
    </script>
  </body>
</html>
Copied!