npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jacare/vite-plugin

v0.1.17

Published

Vite plugin for Jacaré .jcr files

Readme

@jacare/vite-plugin

npm downloads license CI peer

Vite plugin that compiles .jcr files during development and production builds.

When you import a .jcr module, this plugin runs @jacare/compiler and returns optimized JavaScript with source maps. It also validates template contracts against imported children so misuse fails at transform time. No extra build step is required — Vite handles everything.


Table of contents


Install

npm install @jacare/vite-plugin @jacare/compiler @jacare/core
npm install -D vite

For the Jacaré CLI (scaffold / jacare dev / jacare build):

npm install -g @jacare/cli

Peer dependency: Vite ^5 or ^6.

npm: https://www.npmjs.com/package/@jacare/vite-plugin


Quick start

Option A — manual config

// vite.config.js
import { defineConfig } from 'vite'
import jacare from '@jacare/vite-plugin'

export default defineConfig({
  plugins: [jacare()],
})

Option B — helper config

import { createJacareViteConfig } from '@jacare/vite-plugin'

export default createJacareViteConfig({
  title: 'My App',
  port: 3000,
  base: '/',
})

The helper pre-configures the Jacaré plugin, default port, and optimizeDeps exclusions.


Project setup

A typical Jacaré + Vite project looks like this:

my-app/
  src/
    app.jcr          # UI component
    boot.js          # entry — mounts the app
  index.html         # HTML shell
  public/            # static assets
  jacare.config.js   # app config (optional)
  jacare.d.ts        # TypeScript types for .jcr
  vite.config.js     # Vite config (optional if using @jacare/cli)

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/boot.js"></script>
  </body>
</html>

boot.js

import App from './app.jcr'

const root = document.getElementById('app')
App(root)

app.jcr

import { pulse, view } from '@jacare/core'

const count = pulse(0)

export default view`
  <button on-click=${() => count.update((n) => n + 1)}>
    Count: ${count}
  </button>
`

Run with npx vite or jacare dev (from @jacare/cli).


Configuration

jacare.config.js

Place this file in the project root. The plugin reads it automatically:

export default {
  title: 'My App',   // injected into <title> in index.html
  port: 3000,        // dev server port (used by @jacare/cli)
  base: '/',         // Vite base path (e.g. '/my-app/' for GitHub Pages)
}

vite.config.js

import { defineConfig } from 'vite'
import jacare from '@jacare/vite-plugin'

export default defineConfig({
  base: '/my-app/',
  plugins: [
    jacare({
      inspect: true,        // write compiled output to .jacare/compiled/
      emit: 'client',       // client | server | full | auto
      runtimeImport: '@jacare/core',
      configFile: 'jacare.config.js',
    }),
  ],
})

Plugin options

| Option | Type | Default | Description | |--------|------|---------|-------------| | emit | 'auto' \| 'client' \| 'server' \| 'full' | 'auto' | Which functions to emit from each .jcr file | | inspect | boolean | false | Write compiled JS to .jacare/compiled/ for debugging | | runtimeImport | string | '@jacare/core' | Import path for runtime helpers | | configFile | string | 'jacare.config.js' | Path to app config file |

Emit modes

| Mode | Behavior | |------|----------| | auto | client for browser builds, server for SSR transforms | | client | Emits mount() and resume() only | | server | Emits render() only | | full | Emits all three functions |


How it works

  1. Vite encounters an import like import App from './app.jcr'
  2. The plugin's transform hook runs @jacare/compiler on the source
  3. Compiled JavaScript is returned with a source map pointing back to .jcr
  4. Vite bundles the result like any other module

The plugin runs with enforce: 'pre' so .jcr files are compiled before other transforms.

optimizeDeps

@jacare/core is excluded from Vite's dependency pre-bundling because it uses fine-grained reactivity that must not be duplicated across chunks.

HTML title injection

If jacare.config.js sets title, the plugin updates <title> in index.html during dev and build.


SSR

When Vite runs in SSR mode (transformOptions.ssr === true), the plugin automatically compiles .jcr files with mode: 'server' (when emit is 'auto').

// server entry
import { renderToString } from '@jacare/core'
import { render } from './app.jcr'

const { html, state } = render()
const page = renderToString(() => html)

On the client, call resume(root, state) to hydrate.


Inspect mode

Enable compiled output inspection:

jacare({ inspect: true })

Compiled files are written to:

.jacare/compiled/
  app.js
  Field.js
  ...

Useful when debugging what the compiler emits for a specific .jcr file.


TypeScript

Jacaré is JS-first. Optional TypeScript:

Sibling *.jcr.ts

Place typed logic next to the view. The Vite plugin watches the sibling and the compiler merges it automatically:

// src/Counter.jcr.ts
import { pulse } from '@jacare/core'
export const count = pulse(0)
// src/Counter.jcr
export <view>
  <p>${count}</p>
</view>

Pragma // @jacare-ts

// @jacare-ts
const title: string = 'Hi'
export <view>
  <h1>${title}</h1>
</view>

Typing .jcr imports

Add jacare.d.ts to your project:

declare module '*.jcr' {
  export function mount(
    target: HTMLElement,
    props?: Record<string, unknown>,
  ): () => void
  export function render(
    props?: Record<string, unknown>,
  ): { html: string; state: unknown }
  export function resume(
    target: HTMLElement,
    state: unknown,
    props?: Record<string, unknown>,
  ): () => void
  const _default: typeof mount
  export default _default
}

See docs/syntax.md § TypeScript.


Troubleshooting

"Failed to resolve import .jcr"

Make sure @jacare/vite-plugin is in your Vite plugins array and runs before other plugins that might intercept unknown extensions.

Stale compiled output in dev

Clear Vite's cache:

rm -rf node_modules/.vite

Compile errors in the browser overlay

The plugin maps JacareCompileError to Vite's error overlay with file, line, column, and a source snippet. Fix the .jcr source — the overlay points to the original file, not generated JS.

GitHub Pages / subpath deployment

Set base in jacare.config.js or vite.config.js:

export default { base: '/my-repo/' }

Links

License

MIT