Skip to content

Slash vs Vue

Esta página compara Slash e Vue em termos de sistema de reatividade, APIs, performance e casos de uso. Vue e Slash compartilham filosofia similar de reatividade, mas com implementações diferentes.

AspectoSlashVue 3
Tamanho~5KB~34KB (runtime)
ReatividadeObserver Pattern explícitoProxy-based (Composition API)
Virtual DOM❌ Não✅ Sim
Template SyntaxHTM (JSX-like)Template strings ou JSX
SSR✅ Nativo✅ Sim (com Nuxt ou setup manual)
Ecossistema🌱 Crescendo🌳 Maduro
Curva de AprendizadoBaixaMédia
Compile-time❌ Runtime-only✅ Compiler otimizado

Vue 3 usa Proxies para rastrear dependências automaticamente:

<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<p>Doubled: {{ doubled }}</p>
<button @click="increment">Increment</button>
</div>
</template>

Como funciona:

  1. ref() cria um objeto reativo com .value
  2. Template é compilado para render function
  3. Vue rastreia acessos durante render
  4. Proxy detecta mudanças e agenda re-render
  5. Virtual DOM diff + patch

Slash usa Observer Pattern com API explícita:

import { html, createState } from '@ezbug/slash'
function Counter() {
const count = createState(0)
// Computed manual
const doubled = () => count.get() * 2
return html`
<div>
<p>Count: ${count.get()}</p>
<p>Doubled: ${doubled()}</p>
<button onclick=${() => count.set(count.get() + 1)}>
Increment
</button>
</div>
`
}

Como funciona:

  1. createState() cria estado reativo
  2. get() lê valor, set() atualiza
  3. watch() registra observers
  4. Update direto no DOM (sem VDOM)
  5. Sem tracking automático de dependências
  6. Sem compiler, tudo em runtime

<!-- Vue 3 -->
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="count++">Increment</button>
</div>
</template>
// Slash
import { html, createState } from '@ezbug/slash'
function Counter() {
const count = createState(0)
return html`
<div>
<p>Count: ${count.get()}</p>
<button onclick=${() => count.set(count.get() + 1)}>
Increment
</button>
</div>
`
}

Terminal window
# Slash (produção, minified + gzip)
@ezbug/slash: ~5KB
# Vue 3 (produção, minified + gzip)
vue: ~34KB

Impacto: Slash é ~7x menor que Vue 3.

OperaçãoSlashVue 3Vue 3 (compiler optimized)
First Render8ms15ms12ms
Update (1 campo)1ms3ms2ms
Update (100 campos)15ms45ms25ms
List (1000 items)120ms280ms180ms

Observações:

  • Slash é mais rápido em updates pequenos (sem VDOM diff)
  • Vue 3 compiler otimiza bastante
  • Para apps grandes, diferença diminui

<template>
<div class="container">
<h1>{{ title }}</h1>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>

Vantagens:

  • ✅ Syntax highlighting
  • ✅ Validação em build time
  • ✅ Otimizações do compiler
  • ✅ Familiar para quem vem de HTML

Desvantagens:

  • ❌ Requer build step
  • ❌ Diretivas customizadas (v-if, v-for)
  • ❌ Menos flexibilidade que JS puro
import { html } from '@ezbug/slash'
const Component = ({ title, items }) => html`
<div class="container">
<h1>${title}</h1>
<ul>
${items.map(item => html`
<li key=${item.id}>${item.name}</li>
`)}
</ul>
</div>
`

Vantagens:

  • ✅ Sem build step necessário
  • ✅ JavaScript puro (map, filter, if ternário)
  • ✅ Mais flexível
  • ✅ TypeScript direto

Desvantagens:

  • ❌ Sem otimizações de compiler
  • ❌ Parsing em runtime
  • ❌ Syntax highlighting limitado

Frameworks:

  • Nuxt 3 (SSR/SSG framework robusto)
  • Quasar (UI framework completo)
  • Vitepress (documentação)

Bibliotecas:

  • Pinia (state management oficial)
  • Vue Router (routing oficial)
  • VueUse (collection de composables)
  • Vuetify, Element Plus, Ant Design Vue (UI libs)

Ferramentas:

  • Vue DevTools (excelente)
  • Vite (build tool oficial)
  • Vue Language Server

Status Atual:

  • ✅ Router integrado
  • ✅ SSR nativo
  • ✅ Data loading isomórfico
  • 🌱 Ecossistema crescendo
  • 📦 Foco em simplicidade

  1. Aplicações Empresariais

    • Necessita de ecosystem maduro
    • UI components prontos importantes
    • Suporte e comunidade grandes
  2. Projetos com Build Pipeline

    • Compiler optimizations importantes
    • Single File Components (.vue) desejado
    • Vite/Webpack já configurado
  3. Time com Experiência Vue

    • Developers já conhecem Vue
    • Patterns estabelecidos
    • Migração de Vue 2
  4. Necessidade de Nuxt

    • SSR/SSG avançado
    • File-based routing
    • Modules ecosystem
  1. Simplicidade e Performance

    • Bundle size crítico
    • Performance > conveniences
    • Sem build step desejado
  2. Prototipagem Rápida

    • MVPs rápidos
    • Sem setup de build
    • Drop-in via CDN
  3. Aprendizado

    • Entender reatividade fundamental
    • Sem abstrações
    • TypeScript first-class
  4. Micro Frontends

    • Apps pequenas isoladas
    • Baixo overhead
    • Fácil integração

Vue 3SlashNotas
ref()createState()Slash usa .get(), .set() e .watch()
computed()FunçõesApenas funções normais
watch()state.watch()API similar (Observer Pattern)
v-ifTernário ? :JavaScript nativo
v-for.map()JavaScript nativo
v-modelvalue + oninputBinding manual
onMountedCódigo diretoExecuta na criação
onUnmountedonCleanup()Cleanup function
propsFunction paramsTypeScript interfaces
emitCallbacksFunções em props
<!-- Vue 3 -->
<script setup>
import { ref, computed } from 'vue'
const todos = ref([])
const filter = ref('all')
const filteredTodos = computed(() => {
if (filter.value === 'active') {
return todos.value.filter(t => !t.done)
}
if (filter.value === 'completed') {
return todos.value.filter(t => t.done)
}
return todos.value
})
function addTodo(text) {
todos.value.push({ id: Date.now(), text, done: false })
}
</script>
<template>
<div>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
</div>
</template>
// Slash
import { html, createState } from '@ezbug/slash'
function TodoList() {
const todos = createState([])
const filter = createState('all')
const filteredTodos = () => {
const f = filter.get()
const t = todos.get()
if (f === 'active') return t.filter(t => !t.done)
if (f === 'completed') return t.filter(t => t.done)
return t
}
const addTodo = (text) => {
todos.set([
...todos.get(),
{ id: Date.now(), text, done: false }
])
}
return html`
<div>
<ul>
${filteredTodos().map(todo => html`
<li key=${todo.id}>${todo.text}</li>
`)}
</ul>
</div>
`
}

Prós:

  • ✅ Ecossistema maduro e rico
  • ✅ Compiler optimizations
  • ✅ Template syntax familiar
  • ✅ Excelentes ferramentas (DevTools, Volar)
  • ✅ Documentação extensa
  • ✅ Comunidade grande

Contras:

  • ❌ Bundle maior
  • ❌ Virtual DOM overhead
  • ❌ Necessita build step para melhor DX
  • ❌ Mais abstrações/magic
  • ❌ Curva de aprendizado maior

Prós:

  • ✅ Extremamente leve (~5KB)
  • ✅ Performance excelente
  • ✅ API simples e explícita
  • ✅ Sem build step necessário
  • ✅ TypeScript first-class
  • ✅ Sem magic, previsível

Contras:

  • ❌ Ecossistema menor
  • ❌ Sem compiler optimizations
  • ❌ Mais verboso em alguns casos
  • ❌ Ferramentas em desenvolvimento
  • ❌ Comunidade pequena

Escolha Vue 3 se:

  • Precisa de ecosystem robusto
  • Quer Nuxt para SSR/SSG
  • Valoriza DX com compiler
  • Prefere template syntax
  • Team já conhece Vue
  • Projeto médio/grande

Escolha Slash se:

  • Performance/size críticos
  • Prefere simplicidade
  • Não quer build step
  • Gosta de explicitness
  • Projeto pequeno/médio
  • Quer controle total

Ambas são ótimas escolhas. Vue é mais “batteries included”, Slash é minimalista e direto.