Use Template-First-Design for Vue SFCs

Since Vue 3 the common way to order Single File Components is <script>, <template>, <style> instead of <template>, <script>, <style> which was common before. The

closer alignment of related elements (the template is now adjacent to both script and style) and defining the visuals at the end is how most other frameworks do it (i.e. React).
For me, this feels alien. I am a visual thinker and if you see the developer as a user as well, the idea of displaying what a component looks like first is only natural. The user does not need to know how it works and if they want to, they can inspect the corresponding logic by i.e. clicking on it in the template.

The Template Order Tradeoff

The template-first approach prioritizes human comprehension over technical dependency order, reflecting a user-centered design philosophy. However, placing templates second allows logic and style to exist as siblings to the template, which maintains technical correctness at the cost of less intuitive readability.

Visual Processing Advantage

Visual thinking provides

to comprehension. HTML is still text-based but compared to JavaScript . This should result in templates with minimal logic to be the easiest component to understand in web development.

Interactive Logic Exploration

Most IDEs allow for interactive elements to be clicked on for logical components to reveal their JavaScript implementation, thus creating a natural progression from visual structure to functional behavior. This pattern resembles modern component inspection tools that let developers explore code hierarchically in a top-down way. As in a Personal Knowledge Management system, creation should be preferred to be bottom-up but exploring top-down.

Style and Script Placement

CSS styling is often secondary to structure (and optional too) and can logically be placed at the bottom of component files. Since JavaScript is optional as well, placing the HTML template first creates a more semantically meaningful organization.

While technical correctness would suggest an order of imports → JavaScript → HTML -> CSS (as dependencies should precede their usage), this contradicts the semantic importance of the template itself.

Tailwind

Bonus: Tailwind and similar CSS tools gain popularity and are based on inline styling. This makes the CSS block even more obsolete.

Code Examples

templateFirst.vue
<template>
  <!-- Immediately see what the component renders and does -->
  <!-- Visual comprehension first - you understand the purpose at a glance -->
  <
div
class
="counter">
<
h2
>{{
count
}}</
h2
>
<!-- Interactive elements reveal their purpose visually --> <
button
@
click
="
increment
">+1</
button
>
</
div
>
</template> <script setup> // Logic follows visual structure - you already know what this supports // In Nuxt this is also omitted import {
ref
} from 'vue';
// After seeing the template, these variables make immediate sense const
count
=
ref
(0);
const
increment
= () =>
count
.
value
++;
// Understanding the implementation is easier after seeing its purpose </script> <style scoped> /* Styling comes last as it's enhancement, not core functionality */ .counter { padding: 10px; border: 1px solid #ccc; } </style>
scriptFirst.vue
<script setup>
// Dependencies and logic defined before use - technically correct order
// In Nuxt this is also omitted
import { 
ref
} from 'vue';
// Variables defined before they appear in template const
count
=
ref
(0);
const
increment
= () =>
count
.
value
++;
</script> <template> <!-- Template appears after its dependencies are defined --> <!-- Must read through logic before seeing what component does --> <
div
class
="counter">
<
h2
>{{
count
}}</
h2
>
<
button
@
click
="
increment
">+1</
button
>
</
div
>
</template> <style scoped> /* Styling at the end is now closer to the template */ .counter { padding: 10px; border: 1px solid #ccc; } </style>