DEV Community

Cover image for Multiple Vue Components in a Single File with Vue Vine
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Multiple Vue Components in a Single File with Vue Vine

Modern Vue applications are built from many small, closely related components. In practice, this often leads to artificial file splitting: separate files for list items, wrappers, helpers, and tiny UI pieces that only make sense together.

Vue Vine proposes a different authoring model. Instead of splitting logic across multiple Single File Components, Vine lets you define multiple Vue components in a single file, using plain TypeScript functions, while still compiling to standard Vue render functions.

In this article, we’ll explore:

  • What Vue Vine is and why it exists
  • How Vine changes the way you author Vue components
  • How to define multiple components in one file using vine
  • A practical example with a list and list item
  • When Vine makes sense and when it doesn’t

Enjoy!

🤔 What Is Vue Vine?

Vue Vine is an experimental authoring syntax for Vue that allows you to define components as pure functions, without <template>, <script setup>, or SFC boundaries.

Key ideas behind Vine:

  • Components are plain TypeScript functions
  • Props are declared explicitly using VineProp
  • Multiple components can live in one file
  • No SFC mental overhead
  • Compiles to standard Vue render functions

Importantly, Vue Vine is not a runtime abstraction.
It is a compile-time tool that transforms Vine code into regular Vue component code.

This means:
✔ No runtime cost
✔ No magic behavior
✔ Full compatibility with Vue’s reactivity system

🟢 Creating Multiple Components in a Single File with Vue Vine

The main reason to use Vue Vine is not JSX alone — it’s the ability to keep logically related components together without artificial separation.

A classic example: a List component and a List Item component.

With Vine, both can live in the same file.

import { vine, vineProp } from 'vue-vine'
import { ref } from 'vue'

type User = {
  id: number
  name: string
}

/**
 * List Item Component
 */
const UserListItem = vine(() => {
  const id = vineProp<number>()
  const name = vineProp<string>()

  return vine`
    <li>
      <strong>{{ name }}</strong>
      <span> (ID: {{ id }})</span>
    </li>
  `
})

/**
 * List Component
 */
export const UserList = vine(() => {
  const list = vineProp<User[]>()

  return vine`
    <ul>
      <UserListItem
        v-for="user in list"
        :key="user.id"
        :id="user.id"
        :name="user.name"
      />
    </ul>
  `
})
Enter fullscreen mode Exit fullscreen mode

This example demonstrates exactly what Vine is good at:

  • One file
  • Two components
  • Clear ownership and boundaries
  • No unnecessary exports
  • No SFC boilerplate
  • Strong TypeScript inference

This would normally require:
• two .vue files
• duplicated imports
• extra mental context switching

With Vine, everything stays local, explicit, and readable.

If you want a deeper look at the motivation and future of Vue Vine, Alex Lichter explains the idea and tradeoffs in detail in this video

If you’re considering Vine seriously, this video is highly recommended.

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers the most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

🧪 Advance skills

A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.

Check out Certificates.dev by clicking this link or by clicking the image below:

Certificates.dev Link

Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!

✅ Summary

Vue Vine is not meant to replace SFCs everywhere — but for small, tightly coupled components, it offers a clean, expressive, and powerful alternative.

If you value locality, explicitness, and TypeScript-first authoring, Vue Vine is absolutely worth exploring.

Take care!
And happy coding as always 🖥️

Top comments (0)