Métricas de servicios —
$state + $derivedClientes activos
38
▲ +4 este mes
Tareas IA en curso
127
▲ +12 hoy
Créditos consumidos
8.4K
▼ 68% del límite
Tasa de entrega
99.1%
▲ SLA cumplido
Runes de Svelte 5 — Referencia rápida
v5.0
| Rune | Propósito | Svelte 4 equivalente |
|---|---|---|
| $state() | Estado reactivo profundo | let x = 0 |
| $state.raw() | Estado shallow (reasignación) | let arr = [] |
| $derived() | Valor computado reactivo | $: doubled = x * 2 |
| $derived.by() | Computed con lógica compleja | $: { ... } |
| $effect() | Side-effect + cleanup | $: sideEffect() |
| $props() | Props del componente | export let prop |
| $bindable() | Binding bidireccional | bind:value |
| $inspect() | Debug reactivo (dev only) | console.log() |
Tareas de agentes activos
$state + $derived
Generar contenido SEO para TiendaOrgánica
Análisis competidores SaaS B2B — NutriPaw
Emails onboarding secuencia × 5 — FitStudio
Liquid section hero Shopify — LaFlorería
Dashboard analytics Svelte — CULTIVA IA
Componente Svelte 5 — CULTIVA Dashboard
DashboardMetrics.svelte
Svelte 5
<script lang="ts">
// $state — estado reactivo profundo
let metrics = $state({
clients: 38,
tasks: 127,
credits: 8400,
sla: 99.1,
});
// $derived — computed automático
let creditPct = $derived(
(metrics.credits / 12000 * 100).toFixed(1)
);
// $derived.by — lógica compleja
let summary = $derived.by(() => ({
status: metrics.sla >= 99 ? 'OK' : 'WARN',
load: metrics.tasks > 100 ? 'high' : 'normal',
}));
// $effect — sincronizar con backend
$effect(() => {
const id = setInterval(async () => {
const res = await fetch('/api/metrics');
const data = await res.json();
// mutación directa — reactivo
metrics.tasks = data.tasks;
}, 30_000);
return () => clearInterval(id); // cleanup
});
// $props — interfaz del componente
let { workspace = $bindable('cultiva-ia') } = $props();
</script>
<section class="dashboard">
<MetricCard
label="Créditos"
value={metrics.credits}
pct={creditPct}
status={summary.status}
/>
</section>
state/agentes.svelte.ts
Store Svelte 5
// Store global con runes en .svelte.ts
let tasks = $state<Task[]>([]);
let done = $derived(tasks.filter(t => t.done));
let pending = $derived(tasks.filter(t => !t.done));
export function useAgentStore() {
return {
get tasks() { return tasks; },
get done() { return done; },
get pending() { return pending; },
addTask(t: Task) { tasks.push(t); },
toggle(id: string) {
const t = tasks.find(x => x.id === id);
if (t) t.done = !t.done;
},
};
}
Sistema de notificaciones
Store writable
Skill SEO completada — TiendaOrgánica +340 keywords
hace 2 min
Nuevo cliente onboarding: NutriPaw SaaS
hace 15 min
Créditos API al 68% — revisar límite mensual
hace 1h
Agente-research desplegado (v2.1.0)
hace 3h
Workspace activo
$bindable
CULTIVA IA — Interno
cultiva-ia.com
NutriPaw SaaS
nutripaw.io
FitStudio Pro
fitstudio.es
LaFlorería E-commerce
lafloria.com
SvelteKit 2 — Estructura de rutas y convenciones
src/routes/+page.svelte
Componente de página. Recibe
data via $props() desde load function.src/routes/+page.ts
Load function. Ejecuta en servidor (SSR) y cliente. Retorna objeto
data.src/routes/+layout.svelte
Layout compartido. Usa
{@render children()} en Svelte 5 (reemplaza slot).src/routes/api/+server.ts
Endpoint API. Exporta handlers
GET, POST, PATCH.src/lib/state/*.svelte.ts
Stores globales con runes. Importar con alias
$lib desde cualquier componente.svelte.config.js
Adaptadores:
node, vercel, static, cloudflare. Bundle mínimo ~6KB.Tabla de migración — Svelte 4 a Svelte 5
| Svelte 4 | Svelte 5 | Notas | |
|---|---|---|---|
| let count = 0 | → | let count = $state(0) | Estado reactivo explícito |
| $: doubled = count * 2 | → | let doubled = $derived(count * 2) | Más claro, type-safe |
| $: { sideEffect() } | → | $effect(() => { sideEffect() }) | Con cleanup vía return |
| export let prop = "default" | → | let { prop = "default" } = $props() | Destructuring estándar JS |
| <slot /> | → | {@render children()} | Snippets tipados |
| <slot name="header" /> | → | {@render header?.()} | Named snippets opcionales |
| import { writable } from 'svelte/store' | → | $state en .svelte.ts | Sin boilerplate de stores |
Snippets — sustituto de slots tipados
AgentList.svelte
Snippets
<script>
let { agents, row, footer } = $props();
</script>
<ul class="agent-list">
{#each agents as agent}
<li>{@render row(agent)}</li>
{/each}
</ul>
{@render footer?.()}
<!-- Uso en padre -->
<AgentList {agents}>
{#snippet row(agent)}
<strong>{agent.name}</strong>
<span>{agent.status}</span>
{/snippet}
{#snippet footer()}
<p>Total: {agents.length} agentes</p>
{/snippet}
</AgentList>
Transiciones y animaciones nativas
TaskQueue.svelte
Transitions
<script>
import { fade, fly, slide }
from 'svelte/transition';
import { flip } from 'svelte/animate';
let tasks = $state([
{ id: 1, name: 'SEO audit' },
{ id: 2, name: 'Copy email' },
]);
function remove(id) {
tasks = tasks.filter(t => t.id !== id);
}
</script>
{#each tasks as task (task.id)}
<div
animate:flip={{ duration: 300 }}
transition:fly={{ y: -20, duration: 200 }}
onclick={() => remove(task.id)}
>
{task.name}
</div>
{/each}