npm package: @junojs/core
Description: JunoJS Core Engine
Author: JunoJS Team
Latest version: 0.4.2

# 🪐 JunoJS Core

<div align="center">
  <p align="center">
    <strong>The AI-Native Reactive Engine for the Modern Web.</strong><br />
    Native Web Components • Proxy Reactivity • Hybrid Island Architecture • Signal Power
  </p>
  <p align="center">
    <img src="https://img.shields.io/npm/v/@junojs/core?style=flat-square&color=emerald" alt="npm version" />
    <img src="https://img.shields.io/npm/l/@junojs/core?style=flat-square&color=blue" alt="license" />
    <img src="https://img.shields.io/bundlephobia/minzip/@junojs/core?style=flat-square&color=orange" alt="bundle size" />
  </p>
</div>

---

## ⚡ Features

- ⚛️ **Native Web Components**: Future-proof, standard-based components that work natively in the browser.
- 🏝️ **Island & Performance Architecture**: Zero-JS server components (`"use server"`) alongside highly-interactive client islands (`"use client"`).
- 🕹️ **Vibe Coding**: Clean, expressive HTML-First templates with powerful structural directives and zero runtime tension.
- ⚡ **Signal Reactivity**: Fine-grained, auto-tracking reactive primitives — `signal()`, `computed()`, and `effect()`.
- 🛠️ **Decorator-driven TypeScript**: Build features intuitively using `@Component`, `@State`, and Dependency Injection.
- 🧩 **Zero Virtual DOM**: Hyper-fast, targeted reconciliation directly on the Light DOM for maximum speed.
- 🛣️ **Slot-Based Routing**: Robust client-side navigation with the native `<router-outlet>` and automatic parameter synchronization.
- 🚀 **Built-in SSG & SSR**: Automatic routing and static generation out of the box with the Juno CLI.
- 🤖 **AI-Native Context**: Optimized for modern LLMs with dedicated system prompts for seamless code generation.

---

## 📦 Quick Start

Get a high-performance app running in seconds:

```bash
npx juno new my-app --tailwind --ui
cd my-app && npm run dev
```

### 🕹️ The "Vibe"
JunoJS components feel like standard HTML, but with superpowers.

```typescript
"use client";
import { Component, State, Action, bootstrap } from "@junojs/core";

@Component({
  tag: "juno-counter",
  template: `
    <div class="p-6 bg-zinc-900 rounded-2xl border border-white/10">
      <h1 class="text-3xl font-bold bg-gradient-to-r from-emerald-400 to-cyan-400 bg-clip-text text-transparent">
        Count: {count}
      </h1>
      <button @click="count++" class="mt-4 px-6 py-2 bg-emerald-500 hover:bg-emerald-400 transition-colors rounded-xl text-black font-medium">
        Increment
      </button>
    </div>
  `,
})
export class CounterComponent {
  @State() count = 0; 
}

bootstrap(CounterComponent);

### 🔍 Key Concepts
- **`@Component`**: Registers a standard Custom Element.
- **`@State()`**: A Proxy-based reactive variable. Mutating it (e.g., `this.count++`) triggers a microtask-batched DOM update.
- **`@click`**: Declarative event binding. Support for modifiers like `@click.stop` or `@keyup.enter` is built-in.
- **Interpolation**: `{count}` is live-bound. No manual DOM manipulation needed.
```

---

## 🏝️ Hybrid Rendering (Islands)

JunoJS allows you to mix static server-side content with interactive client islands seamlessly using the `"use server"` and `"use client"` directives.

- **`"use server"`**: Zero-JS. Executed at build time. Ideal for layout and data fetching.
- **`"use client"`**: Interactive. Hydrated on the client with full reactivity.

```typescript
"use server";
@Component({
  tag: "home-page",
  static: true, 
  route: "/", 
  template: `
    <main>
      <h1>Static Header</h1>
      <ui-client-island></ui-client-island> <!-- Only this part loads JS -->
    </main>
  `
})
export class HomePage {}

### 📂 How it works
1. **Build Time**: The Juno CLI discovers `static: true` and runs a headless render.
2. **Hydration**: On the client, `"use client"` components are resurrected with full state, while `"use server"` parts remain static HTML.
3. **Zero-JS**: If a page only contains server components, **0KB of JunoJS** is shipped to the browser.
```

---

## 🛣️ Slot-Based Routing

JunoJS v0.4.0 introduces a robust, component-first routing system using the `<router-outlet>`. This replaces manual conditional rendering with a declarative slot-based architecture.

### 1. Register Routes
Register your routes in your application root using the `component` property (which refers to the component's `tag` name).

```typescript
// main.ts
onInit() {
  const router = RouterService.instance;
  router.register([
    { path: '/', component: 'home-page', title: 'Home' },
    { path: '/profile/:id', component: 'profile-page', title: 'User Profile' }
  ]);
}
```

### 2. Define the Outlet
Place the `<router-outlet></router-outlet>` anywhere in your template. It will automatically listen to route changes and inject the matched component.

```html
<!-- app.html -->
<nav>
  <button @click="Router.navigate('/')">Home</button>
  <button @click="Router.navigate('/profile/123')">Profile</button>
</nav>

<main>
  <router-outlet></router-outlet> <!-- Dynamic components are injected here -->
</main>
```

### 3. Parameters Synchronization
Route parameters (like `:id`) are automatically passed to your component as both **Properties** (camelCase) and **Attributes** (kebab-case).

```typescript
@Component({ tag: 'profile-page' })
export class ProfilePage {
  @Input() id!: string; // Automatically populated from the route
}
```

### 4. Programmatic Navigation
The cleanest way to navigate programmatically is to inject the `RouterService` using the `@Use` decorator. This automatically resolves to the framework's singleton instance.

```typescript
import { Component, Use, RouterService } from "@junojs/core";

@Component({ tag: 'user-list' })
export class UserList {
  @Use(RouterService) router!: RouterService;

  goToUser(id: string) {
    this.router.navigate(`/profile/${id}`); // Adds to history
  }

  forceGoToUser(id: string) {
    this.router.replace(`/profile/${id}`); // Replaces current history entry
  }

  goBack() {
    this.router.back();
  }
}
```

### 5. Route Guards
Protect routes using the `canActivate()` lifecycle hook or by passing guards in the route configuration.

```typescript
export class AdminPage {
  async canActivate() {
    return AuthService.instance.isAdmin(); // Returns boolean or new path string
  }
}
```

---

## 🧬 The Reactivity Engine

JunoJS offers two ways to handle state. Choose the one that fits your architectural needs.

### Quick Comparison

| Feature | `@State()` Decorator | `signal()` Primitive |
| :--- | :--- | :--- |
| **Best For** | Component-local UI state | Shared logic, Services, Global state |
| **Mechanism** | Proxy-based (Class properties) | Atom-based (Functional) |
| **Syntax** | `this.count++` | `count.value++` |
| **Tracking** | Manual property binding | Automatic via `.value` access |

---

### 🟢 Local Reactivity (`@State`)
Perfect for internal component variables. Simple, class-based, and intuitive.

```typescript
@State() name = "Juno";
// Mutate directly: this.name = "New Name";
```

### 🔵 Global Reactivity (Signals)
The powerhouse for services and cross-component communication. 

<details>
<summary><b>View Signal Details & Examples</b></summary>

Signals are fine-grained, auto-tracking reactive primitives.

#### 1. Writable Signals
```typescript
const count = signal(0);
count.value = 5; // Triggers subscribers
```

#### 2. Computed Signals (Derivatives)
```typescript
const total = computed(() => price.value * quantity.value);
```

#### 3. Effects & Batching
```typescript
effect(() => console.log(count.value)); // Runs on change

batch(() => {
  a.value = 10;
  b.value = 20; 
}); // Notifies once
```

#### 4. Service Pattern (Cart Example)
Signals are ideal for global state. Here's how a Service and Component interact:

```typescript
// cart.service.ts
export class CartService {
  items = signal<Product[]>([]);
  itemCount = computed(() => this.items.value.length);

  add(p: Product) {
    this.items.update(prev => [...prev, p]); // Immutable update triggers reactivity
  }
}

// cart-icon.component.ts
@Component({
  tag: "cart-icon",
  template: `<span>🛒 {cart.itemCount.value}</span>`
})
export class CartIcon {
  @Use(CartService) cart!: CartService;
}
```
</details>

---

## 🛠️ Core Decorators API

Power up your components with built-in decorators:

- **`@Component`**: Register your Custom Web Component.
- **`@Input`**: Two-way bindable props from HTML attributes.
- **`@Use`**: Easy Dependency Injection for singleton services.
- **`@Event`**: Custom bubbling events with `EventEmitter`.
- **`@Validate`**: Built-in reactive validation logic.
- **`@HostElement`**: Access the native `HTMLElement` directly.

### 🧩 Putting it all together
A robust component using the full power of JunoJS decorators:

```typescript
@Component({
  tag: "user-profile",
  template: `
    <div class="card">
      <img src="{avatar}" />
      <h2>{username}</h2>
      <button @click="notify">Follow</button>
      <if condition="{isVerified}">
        <span class="badge">Verified</span>
      </if>
    </div>
  `
})
export class UserProfile {
  @Input() username = "Guest";
  @Input() avatar = "/default.png";
  @Input() isVerified = false;

  @Event("follow") followEvent!: EventEmitter<string>;
  @Use(LoggerService) logger!: LoggerService;

  notify() {
    this.logger.log(`Following ${this.username}`);
    this.followEvent.emit(this.username);
  }
}
```

---

## 🏗️ Template Logic

JunoJS uses an AST-based template parser for high-performance structural directives.

### Conditional Rendering
```html
<if condition="{isLoggedIn}">
  <user-dashboard></user-dashboard>
<else>
  <login-form></login-form>
</if>
```

### List Rendering
Always provide a `key` for optimal DOM reconciliation.
```html
<ul>
  <for each="{(item, i) in items}">
    <li key="{item.id}">{i}: {item.title}</li>
  </for>
</ul>
```

---

## 🔄 Lifecycle Hooks

Control your component's behavior at every stage:

| Hook | Timing | Best For |
| :--- | :--- | :--- |
| `canActivate()` | Before mount (Async) | Route guards, Auth checks. |
| `onInit()` | Before first render (Async) | Data fetching, API calls. |
| `onRender(el)` | After DOM sync | 3rd party libs (Chart.js, D3). |
| `onDestroy()` | Unmount | Cleaning up timers/subscriptions. |

---

## 🤖 AI-Native Development

JunoJS is designed to be the best framework for AI-assisted coding. We provide specialized **System Prompts** to turn your LLM into a JunoJS expert.

- 💎 **[Gemini.md](https://unpkg.com/@junojs/core/Gemini.md)**: Optimized for Gemini 2.0/3.0 Pro.
- ⚡ **[Claude.md](https://unpkg.com/@junojs/core/Claude.md)**: Optimized for Claude 3.5/4.5 Sonnet.

> [!TIP]
> Copy these files into your project root as `.cursorrules` or `.clauderules` to give your AI full framework context.

---

## 🔌 Tooling & Ecosystem

- **[Juno CLI](https://www.npmjs.com/package/@junojs/cli)**: Scaffolding, Dev Server (Vite), and SSG Builder.
- **[Juno UI](https://www.npmjs.com/package/@junojs/ui)**: Tailwind-powered, interactive component library.
- **[VS Code Plugin](https://unpkg.com/@junojs/core/junojs-0.2.14.vsix)**: Syntax highlighting and template intellisense.

---

## 📜 License

MIT © [Norbi Szobszlai & JunoJS Contributors](LICENSE)