DEV Community

Cover image for Single-File Components in React: Genius or Garbage?
Samir Tahiri
Samir Tahiri

Posted on

Single-File Components in React: Genius or Garbage?

Let’s start a fight (respectfully) 🥊

Recently, I came across a few React projects where the entire component was written in one file — logic, styles, markup, all jammed together.

Example:

// Button.jsx
import './Button.css';

function Button({ label }) {
  const handleClick = () => {
    alert('Clicked!');
  };

  return <button onClick={handleClick}>{label}</button>;
}

export default Button;
Enter fullscreen mode Exit fullscreen mode

They call this "Single-File Components (SFC)". The idea? Keep everything together: no more .js, .css, .test.js, etc.

But here's where it gets spicy 🔥


🧠 The Argument For SFCs

  • 🪄 Easier to read and understand in one glance
  • 🚀 Less context switching between files
  • 📦 More portable (copy one file, done)
  • 🧼 Cleaner when using CSS-in-JS or Tailwind

😤 The Argument Against SFCs

  • 🤯 Can get bloated fast (200+ lines easy)
  • 🧪 Tests get ignored or written elsewhere
  • 💣 Harder to scale in large teams
  • 📁 Violates Separation of Concerns (SoC)

💬 What Do You Think?

Do you love the simplicity, or do you miss the old-school modularity?

👇 Comment below:

  • Do you use SFCs in React?
  • What are the pros and cons you’ve experienced?
  • Would you recommend it to your team?

Let's debate 👇


🗳️ Bonus: React devs — should we embrace single-file components like Vue? Or stick to separation?

React #WebDev #Frontend #DevOpinion

Top comments (17)

Collapse
 
xwero profile image
david duymelinck •

Not a React dev. As I see it, a single file component in Vue or Svelte is closer to a web component.

Vue example

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>
Enter fullscreen mode Exit fullscreen mode

Here the separation between markup and logic is more visible.
In React it is a function with logic and markup.

Collapse
 
ivanjrmc profile image
Ivan Jeremic •

That's not how web-component definition looks like. Read on MDN on how to create and define custom elements and you will see.

Collapse
 
xwero profile image
david duymelinck •

I mentioned it is closer, not that it is a web-component definition. I added the link to MDN, that would be stupid if i didn't read it first.

Thread Thread
 
ivanjrmc profile image
Ivan Jeremic •

not even closer, makes no sense. A web-component is defined by doing. class MyComp extends HTMLElement

Thread Thread
 
xwero profile image
david duymelinck •

From MDM:

<template id="custom-paragraph">
  <style>
    p {
      color: white;
      background-color: #666666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>
Enter fullscreen mode Exit fullscreen mode

Doesn't that look a lot like a Vue or Svelte component?

Thread Thread
 
ivanjrmc profile image
Ivan Jeremic • • Edited

That is not a web-component. Your link just shows an example of how the template tag can be used with web-components but this is not a web-component.

Thread Thread
 
xwero profile image
david duymelinck • • Edited

If a template is used by a web component, how is that not web component syntax?

What you think a web component is, class MyComp extends HTMLElement, is a custom element. This also can be created by using <my-comp></my-comp>, .
Web component is not a strict definition. It is a set of features in HTML, CSS and javascript that work together. And HTML is the most import part because it is the base.

This is a declarative web component.

<my-comp>
 <template>
  <style>
    p {
      color: white;
      background-color: #666666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>
</my-comp>
Enter fullscreen mode Exit fullscreen mode

Javascript is not a requirement.

Collapse
 
samirtahiri profile image
Samir Tahiri •

Thanks David, great point!
You're right – Vue and Svelte with SFCs definitely highlight that clear separation of markup and logic. In React, the JSX + hooks combo can feel more “blended” since everything lives in one function. That’s exactly what I was touching on in the post – how different frameworks structure and think about components.

Both approaches have pros depending on the mindset and team habits. Appreciate the Vue example!

Collapse
 
dotallio profile image
Dotallio •

I've tried SFCs for quick MVPs and they do speed me up, but I always end up splitting things out as the project grows. Have you found a sweet spot where SFCs still work for big apps?

Collapse
 
samirtahiri profile image
Samir Tahiri •

Totally relate. SFCs are great for fast iteration and MVPs, but yeah — as the app grows, keeping everything in one file can feel cramped. I’ve found that the sweet spot is using SFCs for atomic components or isolated logic/UI pieces, and gradually splitting concerns (like store, styles, or templates) only when complexity demands it.

So basically: start simple, scale structure as needed. You?

Collapse
 
johanpiquet profile image
Johan PIQUET •

I'm a React dev and I love having one file per component and one CSS per component. It makes it much easier for CSS management.

Collapse
 
samirtahiri profile image
Samir Tahiri •

Yea 100%, i am with you here. It makes life easier and more structured fr

Collapse
 
9opsec profile image
9opsec •

This would be two files with the "Button.css" but I am ok with this for simple web sites.

Collapse
 
parag_nandy_roy profile image
Parag Nandy Roy •

SFCs feel like React’s version of a one-pot meal ..quick, satisfying, but maybe not for a five-course app 😄 Great convo starter..

Collapse
 
samirtahiri profile image
Samir Tahiri •

Yea 100%, thanks tho💪🏼

Collapse
 
parag_nandy_roy profile image
Parag Nandy Roy •

SFCs are like pineapple on pizza ...weirdly good in the right context

Collapse
 
dariomannu profile image
Dario Mannu •

If SFCs are like pineapple, custard, or strawberry-banana sandwiches on pizza, then yeah, you said everything about SFCs

Some comments may only be visible to logged-in visitors. Sign in to view all comments.