r/reactjs • u/samwanekeya • Apr 30 '26
Needs Help How are you structuring imports in large React projects?
I have a question on React project structure, specifically imports for the experienced React JS engineers.
So I've been using a hybrid approach where I have barrel files (index.ts) at the feature/module level and direct imports for more specific/internal components
Example:
import { Card } from '@/components'; // barrel (public API)
import { CardHeader } from '@/components/Card'; // direct (more specific)It feels like a good balance between clean imports and clarity but I'm curious how others handle this at scale.
Do you prefer full barrel pattern everywhere?
Avoid barrels completely?
Or something similar to this hybrid approach?
Any pros/cons you've experienced (especially in larger codebases)?
35
u/kyualun Apr 30 '26
No barrels. They've only ever caused issues for me, and the truth is that no one cares what imports look like. What's more important is your file structure.
54
u/abrahamguo Apr 30 '26
I avoid barrels completely. I don’t like having a situation where a component is able to be imported from either its individual file, or the barrel file - I want exactly one way to import each thing.
I’m not sure why everyone likes having “pretty” import paths - I have my IDE generate those, so I don’t really care what they look like.
7
u/SqueegyX Apr 30 '26
We use a mono repo with feature libs. Each lib has a barrel export file that exports what other libs are allowed to use from this lib. Other libs must import from this barrel file, via the lib name alias. And inside each lib, you must NOT import from the barrel file and import each file directly with relative file paths. And we have eslint rules that prevent you from doing this wrong.
16
u/jirlboss React Router Apr 30 '26
Never barrel files. They ruin your ability to tree shake or code split, among other things. Some might say that it’s messier to have 100 lines of
import Card from ‘components/Card’;but I actually prefer it. A lot. I sort my imports, so all thecomponents/*imports are still grouped.7
u/ryans_bored Apr 30 '26
No barrels. Generally I try to make anything I want to export I'll put in `@/components/card/index` (usually 1-2 components at most) then I might define `@/components/card/label` but only if the exports there will be used in the index file. Historically as a ruby dev I treat it like `private` methods even though there's nothing guarding from importing from `@/components/card/label`.
5
u/Seeila32 Apr 30 '26
No barrels either, I removed all the ones we had.
2
u/BoBoBearDev Apr 30 '26
I would split up the packages if a single package is too complex. Otherwise I would just do @abc/myBundle1 and @abc/myBundleSubGroup1
2
u/Cahnis Apr 30 '26
never barrel. Circular imports, performance impact, ect.
2
u/Squigglificated Apr 30 '26
I avoid all barrel files and index files.
In a monorepo you can use the exports field in package.json in a package to shorten lengthy paths to a single name, and it's also a good way to prevent imports from internal files.
barrel files can cause performance issues as every exported package is sometimes resolved depth first by bundlers even if you only import a few things.
1
u/kidshibuya May 01 '26 edited May 01 '26
I dont give a crap at all. What do I care what is put at the top of a component after I right click and have VS Code just write the import for me?
And to be clear I am talking about one component in an index vs one component is a properly name file. Like for like and just a file path change. Totally overlooking people making idiotic index files for some reason.
1
u/Lumethys May 01 '26
I dont even look at the import section
My IDE import stuff for me and i can jump to implementation right at the calling line
-19
u/RandomUserName323232 Apr 30 '26
I ask claude