I've always considered myself a "frontend" developer. Lately this started to change ๐ค
With React 19 and Effect the gap between "front/back" is getting slimmer.
With Server components as the main culprit, "full-stack" developers are more real than ever.
This is how from my perspective ๐
What frontend is all about (when done right)
Frontend development is a state management problem.
- You get some data from somewhere ("API")
- You show this data to the user ("UI")
- You allow the user to interact with the data ("State")
- You send the data back to the server ("API")
That's it.
In the process you must take care of:
- Performance
- Accessibility
- Bundle size
- User experience
- (and more ๐ฅต)
Things like data storage ("database"), file system (read/write files), observability (traces), these were all handled somewhere else for you.
Now this may not be the case anymore.
Closing the gap: Server components
With server components the game changes.
From the docs:
Server components can run at build time to read from the filesystem or fetch static content [...]
Meaning: you do some "backend" stuff that you then pass on to the "frontend".
The new frontend
Here is a concrete example I worked on recently: MDX.
With some magic (aka @EffectTS_ + @mdx_js) convert files to a step by step code tutorials ๐ช ๐ Effect platform `FileSystem` ๐ Compile mdx to html ๐ Shiki to add code highlight
Here is how it works:
- I have some files locally that I read using Node's file system API (using Effect's
FileSystem
) - I use the mdx compiler (
@mdx-js/mdx
) to covert MDX to javascript - I apply styles to code blocks using shiki
- I send all the data to the "frontend" using a server component
const ContentLayer = Content.Content.Live({
contentDir: Config.string("CONTENT_DIR"),
});
export const main = Content.Content.pipe(
/// Compute the data (aka "backend") ๐๐ผโโ๏ธ
Effect.provide(ContentLayer)
);
export default async function Page() {
const contentOption = await main.pipe(Effect.runPromise);
return Option.match(contentOption, {
onNone: () => <span>Invalid content</span>,
onSome: ({ content, step }) => (
<div className="max-w-4xl mx-auto">
<Nav step={step} />
<Tutorial content={content} />
</div>
),
});
}
All of this is backend. What's more, this is the "core" of the app ๐๐ผโโ๏ธ
The frontend is only responsible to display this data in the UI and manage users interactions.
Added files navigation with highlight on file+lines ๐ช No major roadblocks for now, keep working on it ๐จโ๐ป #stepbystepcodetutorials
Result: this is more "backend" than "frontend", even when using React ๐ฒ
I wrote an article highlighting all the details of how to use MDX with React ๐
There is more ๐คฉ
Timeless coding principles, practices, and tools that make a difference, regardless of your language or framework, delivered in your inbox every week.
The finishing blow: Local first
This distinction becomes even slimmer to the point of disappearing with local first.
Super excited for @localfirstconf in Berlin this week! So many amazing talks and fascinating people coming! And still can't believe we sold out the conference in just over a week. ๐คฏ
With local first the client becomes your server ๐ก
All the data is stored locally on the user device, so no need to interact with any "API" both inbound and outbound.
I am flying to Berlin this week for localfirstconf โ๏ธ
Be ready for some cool updates on this next week ๐
React 19 stable will be released soon, and with it many new frameworks will start to support server components.
Now it's the time to adapt and start closing the gap. Furthermore, Effect is here to help, and to make everything more interesting and fun ๐
See you next ๐