mikuru
v1.0.40
Published
A compile-first JavaScript framework with Vue-like authoring and Svelte-like generated DOM updates.
Maintainers
Readme
Mikuru
Mikuru is a compile-first JavaScript framework for Vue-like single-file components that generate direct DOM update code instead of using a virtual DOM.
It is intentionally small. Mikuru v1 is a practical validation release for writing .mikuru components in Vite apps, not a Vue compatibility layer.
Requirements
- Node.js 22 or newer
- Vite 8 or newer for app development
Create a New App
The fastest way to try Mikuru is the package CLI:
npx mikuru create my-app
cd my-app
npm install
npm run typecheck
npm run devThe generated starter includes Vite, TypeScript, the package-provided .mikuru module declaration, and a welcome component at src/App.mikuru.
Use the basic template when you want a small component composition example:
npx mikuru create my-basic-app -t basicUse the video-player template when you want a Vite app that imports the package-provided MikuruVideoPlayer component:
npx mikuru create my-video-app -t video-playerList available templates:
npx mikuru --list-templates
starter - minimal Vite app
basic - component composition example
video-player - MikuruVideoPlayer media appRun a dry-run to preview the target, template, and files without writing them:
npx mikuru create my-app -t basic --dry-runWhen run in a terminal, mikuru create asks for a project name and template if they are omitted. Use --yes / -y to skip interactive prompts and accept defaults. mikuru create also accepts --force for non-empty directories.
Generated apps include npm run typecheck for a quick TypeScript validation pass before running or building.
Add Mikuru to a Vite App
Install Mikuru and the Vite tooling:
npm install mikuru
npm install -D vite typescriptConfigure Vite:
import { defineConfig } from "vite";
import { mikuru } from "mikuru/vite";
export default defineConfig({
plugins: [mikuru()]
});Use mikuru({ batchedUpdates: true }) to opt into queued generated DOM effects. In that mode, DOM updates triggered by refs flush through the runtime job queue and can be awaited with nextTick().
Create a .mikuru component:
<template>
<button @click="increment">count: {{ count }}</button>
</template>
<script>
import { ref } from "mikuru";
const count = ref(0);
function increment() {
count.value += 1;
}
</script>
<style>
button {
font: inherit;
}
</style>Mount it from your app entry:
import { mount } from "./App.mikuru";
const app = document.querySelector("#app");
if (!app) {
throw new Error("Missing #app");
}
mount(app);TypeScript Declarations
For TypeScript projects, add a local declaration file such as src/mikuru-env.d.ts that imports Mikuru's package-provided .mikuru module declaration:
import "mikuru/env";You can use the exported component types for typed wrappers or hand-written integrations:
import type { MikuruComponent } from "mikuru/env";
type GreetingProps = {
name: string;
};
declare const Greeting: MikuruComponent<GreetingProps>;Supported v1 Surface
.mikuruSFCs with<template>,<script>, and<style>- Vite plugin support through
mikuru/vite - Template interpolation with
{{ value }} - DOM events with
@click,m-on:click, inline handlers, object-form option modifiers,.prevent,.stop,.self,.once,.capture,.passive, key, mouse button, system, and.exactmodifiers - Component events with
@selectand.once - Attribute bindings with normalized
:classand:style, boolean/form property sync, direct/objectm-bindmodifiers like.prop,.attr, and.camel, plus dynamic arguments like:[name]and@[event] m-if,m-else-if,m-else,m-show,m-for,m-html,m-text,m-pre,m-cloak,m-once, andm-memom-modelfor common form controls, checkbox arrays, radio groups, multiple selects, modifiers, and named child component modelsv-*directive spellings remain available as compatibility aliases for existing components and Vue-oriented migrations- Component props, events, DOM attribute fallthrough,
useAttrs, template refs, dynamic<component :is>,defineProps,defineEmits, default slots, named/dynamic slots, and slot props with simple defaults - CSS class transitions with built-in
<Transition name="fade">,m-ifchains, dynamic components, class overrides,appear,mode="out-in", and<TransitionGroup>for keyed lists - Built-in
<Teleport to="#target">for rendering content outside the current DOM position - Built-in
<AsyncBoundary :loading :fallback :delay :timeout>for grouped async loading, delayed loading UI, boundary timeouts, and retryable async failures with aggregated fallback errors - Built-in
<ErrorBoundary :fallback>for local component mount, descendant event handler, lifecycle, and cleanup fallbacks, witherrorInfo,retry,reset, and:reset-keyrecovery - Built-in
<KeepAlive>for caching one dynamic child component withinclude,exclude, andmaxcontrols - Runtime helpers including
ref,isRef,unref,toRef,toRefs,reactive,readonly, lazy cached read-only and writablecomputed,effectwith optional scheduling,queueJob/flushJobs,watch,watchEffectwith cleanup callbacks,nextTick, lifecycle callbacks including KeepAlive activation hooks,provide,inject, anddefineAsyncComponentwith ErrorBoundary handoff and SSR loader resolution - Routing through
mikuru/routerwith route matching, history/hash/memory histories, guards, router context helpers, andRouterView/RouterLinkacross mount, SSR, and hydration - SSR through
compileSsr()andmikuru/server, covering escaped text, static and bound attributes, content directives,m-pre,m-cloak,m-ifchains,m-for, async child components, props, named/default slots, scoped slot props, component tree context, Teleport collection, string and async iterable stream rendering, and router route rendering with context propagation - Hydration through
compileHydration()andhydrateRoute(), reusing existing SSR DOM while attaching events, syncing text/attributes, recovering structural mismatches with an opt-out remount fallback, hydrating component context/lifecycle hooks,m-show, DOM and componentm-model,m-pre,m-cloak, initialm-if/m-forDOM, Teleport target and disabled inline content, delegating child and route components tohydrate()when available, and optionally starting router history listening after route hydration - Style injection and
<style scoped>selector rewriting for common selectors, native CSS nesting,:global(...),:deep(...), nested at-rules, and malformed CSS diagnostics - Vite-routed component CSS for CSS Modules with
<style module>, preprocessor languages such as<style lang="scss">, and project-level CSS transforms such as PostCSS when usingmikuru/vite - Content-keyed Vite style requests so
.mikuruscoped CSS updates reload reliably during development instead of reusing stale virtual style modules - Optional TypeScript template type checking with
typeCheckTemplate(),compile(..., { templateTypeCheck: true }), andmikuru({ templateTypeCheck: true }), including script bindings,defineProps()constructor inference, ref unwrapping, andm-foritem/index scopes - Compile errors with filenames, line/column information, code frames, and typo suggestions for built-in attributes, directives, and modifiers
- Stable devtools diagnostics with optional generated
sourceURL,v-*compatibility warnings, versioned metadata/events, component tree snapshots, compiler/style diagnostic locations and frames, and hydration warnings that include phase, component, and filename context
Package Exports
Application code usually imports from mikuru:
import { computed, ref } from "mikuru";The Vite plugin is available from mikuru/vite:
import { mikuru } from "mikuru/vite";The router is available from mikuru/router:
import { createRouter, createWebHashHistory, provideRouter, RouterLink, RouterView, useRoute, useRouter } from "mikuru/router";The .mikuru TypeScript declaration is available from mikuru/env:
import "mikuru/env";Compiler, runtime, and server entries are public for lower-level integrations:
import { compile, compileHydration, compileSsr, compileStyle } from "mikuru/compiler";
import { effect, isRef, nextTick, reactive, readonly, ref, toRef, toRefs, unref, unwrap, watch } from "mikuru/runtime";
import { hydrateRoute, renderComponentToString, renderRouteToString, renderToStream, renderToString } from "mikuru/server";
import type { MikuruAsyncBoundaryFallbackProps, MikuruErrorBoundaryFallbackProps, MikuruErrorInfo, MikuruErrorPhase } from "mikuru/runtime";compileStyle() returns scoped CSS code plus non-throwing diagnostics. Malformed scoped CSS diagnostics include offset, line, column, and a one-line frame, and debug builds emit the same fields in compiler:warning style diagnostic events.
The package also provides the mikuru binary:
npx mikuru create my-app
npx mikuru create my-basic-app -t basic
npx mikuru create my-video-app -t video-player
npx mikuru --list-templatesTransition Example
<template>
<button @click="open = !open">Toggle</button>
<Transition name="fade">
<p m-if="open">Saved changes</p>
<p m-else>Waiting for edits</p>
</Transition>
</template>
<script>
const open = ref(false);
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 120ms ease, transform 120ms ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateY(-4px);
}
</style>Not Included in v1
- Full Vue compatibility.
Repository Development
For local framework development:
npm install
npm run ciUseful targeted checks:
npm run typecheck
npm test
npm run build
npm run test:create
npm run test:package
npm run test:pack
npm run test:e2e
npm run test:e2e:router-ssr-hydration
npm run test:e2e:ssr-hydrationExamples can be run from the repository root:
npm run dev:basic
npm run dev:realworld
npm run dev:dogfood
npm run dev:router-ssr-hydration
npm run dev:ssr-hydration
npm run dev:mikuru-sample
npm run dev:mikuru-vue-likeThe package also includes original Mikuru components:
MikuruVideoPlayer.mikuru: overlay video controls, configurable sizing, configurable control visibility, live mode, settings menu, div-based seeking, volume/mute, playback rate, and fullscreen controls.MikuruAudioPlayer.mikuru: audio playback with configurable control visibility, live mode, seeking, skip controls, volume, and mute.MikuruImageViewer.mikuru: image zoom, pan, rotate, reset, and fullscreen controls.MikuruModal.mikuru: accessible modal shell with backdrop, Escape close, slots, and close events.MikuruCarousel.mikuru: image carousel with arrows, dots, keyboard navigation, optional autoplay, and optional thumbnail navigation.MikuruToast.mikuru: fixed notification stack with timed auto-dismiss, dismiss events, and tone variants.MikuruDropdown.mikuru: menu button with outside-click close, Escape handling, and select events.MikuruToolTip.mikuru: hover/focus tooltip with configurable placement.MikuruProgress.mikuru: determinate and indeterminate progress indicator.MikuruCodeBlock.mikuru: code display with language label, line numbers, and copy action.MikuruTabs.mikuru: accessible tab list with controlledm-model, keyboard navigation, and slot/fallback panels.MikuruAccordion.mikuru: single or multiple disclosure panels with controlledm-modeland slot/fallback content.MikuruTextInput.mikuru,MikuruTextarea.mikuru, andMikuruCheckbox.mikuru: form controls that emitupdate:modelValue.MikuruSelect.mikuru: labeled select control with normalized string/object options.MikuruCombobox.mikuru: searchable single-select combobox with outside-click and Escape close.MikuruHeader.mikuru,MikuruFooter.mikuru, andMikuruSideMenu.mikuru: app shell layout primitives with normalized navigation items and selection events.
They can be imported from the package:
<script>
import MikuruVideoPlayer from "mikuru/components/MikuruVideoPlayer";
import MikuruAudioPlayer from "mikuru/components/MikuruAudioPlayer";
import MikuruImageViewer from "mikuru/components/MikuruImageViewer";
import MikuruModal from "mikuru/components/MikuruModal";
import MikuruCarousel from "mikuru/components/MikuruCarousel";
import MikuruToast from "mikuru/components/MikuruToast";
import MikuruDropdown from "mikuru/components/MikuruDropdown";
import MikuruToolTip from "mikuru/components/MikuruToolTip";
import MikuruProgress from "mikuru/components/MikuruProgress";
import MikuruCodeBlock from "mikuru/components/MikuruCodeBlock";
import MikuruTabs from "mikuru/components/MikuruTabs";
import MikuruAccordion from "mikuru/components/MikuruAccordion";
import MikuruTextInput from "mikuru/components/MikuruTextInput";
import MikuruTextarea from "mikuru/components/MikuruTextarea";
import MikuruCheckbox from "mikuru/components/MikuruCheckbox";
import MikuruSelect from "mikuru/components/MikuruSelect";
import MikuruCombobox from "mikuru/components/MikuruCombobox";
import MikuruHeader from "mikuru/components/MikuruHeader";
import MikuruFooter from "mikuru/components/MikuruFooter";
import MikuruSideMenu from "mikuru/components/MikuruSideMenu";
</script>Documentation
CHANGELOG.mdlists published package changes.docs/npm-usage.mdshows a manual Vite setup for package consumers.docs/mikuru-components.mdshows usage examples for package-exported Mikuru components.docs/app-architecture.mddescribes how to keep larger Mikuru apps split across components, API modules, stores, forms, auth, and tests.docs/router.mddocuments the runtime router.docs/production-readiness.mdsummarizes debugging, parser, package, SSR, and hydration caveats.docs/v1-api-contract.mddescribes the v1 compatibility boundary used by this repository.
