Jskalc

Jskalc

LiveVue - v1.0 released with igniter installer, forms support and more!

LiveVue v1.0 released

After four release candidates and a lot of community feedback, LiveVue 1.0 is stable :tada:

I’ve built a dedicated website with interactive examples: livevue.skalecki.dev

And wrote the full story behind the library: The Story of LiveVue

What Changed

New Composables

useLiveForm — Server-side validation with Ecto changesets, nested objects, dynamic arrays. Fully typed:

<script setup lang="ts">
import { useLiveForm, type Form } from 'live_vue'

type UserForm = {
  name: string
  profile: { bio: string; skills: string[] }
}

const props = defineProps<{ form: Form<UserForm> }>()

const form = useLiveForm(() => props.form, {
  changeEvent: 'validate',
  submitEvent: 'submit'
})

// Type-safe field access — typos caught at compile time
const nameField = form.field('name')
const bioField = form.field('profile.bio')
const skillsArray = form.fieldArray('profile.skills')
</script>

<template>
  <input v-bind="nameField.inputAttrs.value" />
  <span v-if="nameField.errorMessage.value">{{ nameField.errorMessage.value }}</span>

  <div v-for="(skill, i) in skillsArray.fields.value" :key="i">
    <input v-bind="skill.inputAttrs.value" />
    <button @click="skillsArray.remove(i)">Remove</button>
  </div>
  <button @click="skillsArray.add('')">Add Skill</button>

  <button @click="form.submit()" :disabled="!form.isValid.value">Submit</button>
</template>

LiveView side stays exactly as you’d expect:

def handle_event("validate", %{"user" => params}, socket) do
  changeset = User.changeset(%User{}, params) |> Map.put(:action, :validate)
  {:noreply, assign(socket, form: to_form(changeset, as: :user))}
end

useLiveUpload — File uploads with progress tracking and drag-and-drop:

<script setup>
import { useLiveUpload } from 'live_vue'

const { entries, showFilePicker, addFiles, progress } = useLiveUpload(
  () => props.upload,
  { submitEvent: 'save' }
)
</script>

<template>
  <div @drop.prevent="e => addFiles(e.dataTransfer.files)" @dragover.prevent>
    Drop files or <button @click="showFilePicker">browse</button>
    <div v-for="entry in entries" :key="entry.ref">
      {{ entry.client_name }} — {{ entry.progress }}%
    </div>
  </div>
</template>

useLiveConnection — Reactive WebSocket status for offline indicators:

<script setup>
import { useLiveConnection } from 'live_vue'
const { isConnected, connectionState } = useLiveConnection()
</script>

<template>
  <div :class="isConnected ? 'text-green-500' : 'text-red-500'">
    {{ connectionState }}
  </div>
</template>

useEventReply — Bi-directional events with server responses:

<script setup>
import { useEventReply } from 'live_vue'

const { data, isLoading, execute } = useEventReply('fetch_user')
</script>

<template>
  <button @click="execute({ id: 123 })" :disabled="isLoading">
    {{ isLoading ? 'Loading...' : 'Fetch User' }}
  </button>
  <div v-if="data">{{ data.name }}</div>
</template>

Performance: JSON Patch Diffs

Props now use RFC 6902 JSON Patch. Only differences are sent:

[{"op": "replace", "path": "/users/1/name", "value": "Robert"}]

Inserting at the beginning of a 100-item list? One operation, not 100 — thanks to ID-based matching.

Phoenix Streams

Streams work transparently as reactive arrays:

<.vue messages={@streams.messages} v-component="Chat" v-socket={@socket} />
<script setup>
// messages is a reactive array — streams handled automatically
const props = defineProps<{ messages: Message[] }>()
</script>

Developer Experience

  • One-command install: mix igniter.install live_vue
  • No JS build step — TypeScript source exported directly, Vite handles it
  • VS Code extension for ~VUE sigil syntax highlighting

Breaking Changes

  • shared_props removed — pass props explicitly
  • nillify_not_loadednilify_not_loaded (typo fix)

Links

Discuss and upvote also on Hacker News.

Happy New Year!

First 5 of 5 Posts Switch mode

mikehostetler

mikehostetler

Great work! I’ve been mostly a React guy, but I haven’t been able to find a good flow when using React with LiveView, so this may convert me!

Jskalc

Jskalc OP

I would like to eventually port that work to LiveReact / LiveSvelte, since most of it should be easily transferrable. But for now I have to focus on other priorities :smiley:

sezaru

sezaru

Does useLiveForm also works with Ash.Changeset forms?

I’m considering using LiveVue in a new project but that project will use Ash instead of Ecto directly.

Normally, when creating a form in LV for Ash, you will use AshPhoenix.Form — ash_phoenix v2.3.23 which will wrap around Phoenix forms, not sure if it can be used with LiveVue too.

sezaru

sezaru

Another question, do you have some sample project examples of using LiveVue for the full project? In your post you mention postline.ai, but AFAIK, the code of that site is not open, so I can’t use as reference.

Jskalc

Jskalc OP

Hi @sezaru, sorry for a late response. Ash is not yet officialy supported, but I have a working version in my own project - just, not yet migrated to live vue. Since it’s important to you, I can prioritize it!

About examples - the best one currently is a github repo of https://livevue.skalecki.dev/, you can find it here.

I’m thinking about creating another example showing exactly how a simple intertia-style SaaS could be created with live_vue (exactly what I’m doing in Postline) - one component per page. Maybe it could be part of live vue website as well.

Thanks for being interested in live vue!

— All posts loaded —

Where Next?

Trending in News & Updates Top

bartblast
After building Hologram and sharing updates across various places, I’ve realized there’s a lot happening that doesn’t always make it to t...
New
kip
I’m a bit excited to announce that Localize and friends are now at release 1.0. Even though it’s a 1.0 release, it stands on 8 years of w...
New
nseaSeb
Just published search_ash 0.5.0 (with search_core 0.4.0) on Hex. What’s new: synonyms You can now declare a synonym dictionary per lang...
New
mudasobwa
After years of struggling I made StreamData dependency optional. Finitomata.ExUnit got testing primitives for Persistence. Full back co...
New
polvalente
We have released v0.13 of nx, exla and torchx, along with a recently released emlx v0.4. Nx This is where the bulk of the updates happen...
New
sullyMusty
ActiveMemory 0.8.0 is on Hex. It’s an in-memory store built on ETS and Mnesia: typed records you query by **any attribute**, not just a ...
New
bartblast
Hologram v0.11 is out! Two headline features this release. First, Elixir regexes now run in the browser. They were server-only until now,...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement