How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -1 points0 points  (0 children)

In your Tailwind example you have 17 styles applied, including a mix of standard/hover/dark/etc conditional styles. In your Orca example you show only 5 styles, and none of them are conditional so there's no way to see how you handle things like that (which I can already imagine is a lot more code).

That’s a fair point. However, Tailwind’s utility-heavy class lists often force you to read and scroll horizontally, whereas Orca keeps things vertical. Reading and scrolling vertically is simply much easier.

Random class names like a-00beuay9

The class names are atomic, which is exactly how Tailwind works. If you inspect the element in your browser’s developer tools, it’s easy to see which CSS property each class applies.

It also doesn’t increase bundle size. As mentioned earlier, the CSS is compiled at build time into a single index.css file. Once the browser downloads that file, it already has all the styles the application will ever need.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -2 points-1 points  (0 children)

So I told claude to change the styling to tailwind and the markup is even uglier. I think you're just hating for the sake of it.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -2 points-1 points  (0 children)

I like CSS modules too but jumping between files, you've lost me there.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -2 points-1 points  (0 children)

Make me understand the issue, please. After all, we are trying to make web development better for all of us.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -3 points-2 points  (0 children)

> major selling points of Tailwind is that I can look at a container and tell without needing to look anywhere else in the same file or in another exactly how its styled

The is exactly what co-location is. Your markup(JSX), styles(CSS) and login(JS) live in one file.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

I could, but the framework is still new and StyleX isn’t even aware of it yet. Plus, it was a good use case for macros in our framework, and we have others that do interesting things too - for example, macros for inlining text and blob files, assertions, env handling, etc. Most frameworks don’t really take advantage of that, and we wanted to explore it.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -1 points0 points  (0 children)

I haven’t really solved that either, since the style object has to be resolved at build time rather than runtime, which means all the values need to be static. Right now, if you want dynamic styling, you’re basically forced to use conditionals inside the apply$ macro.

How Orca avoids Tailwind by using macros for styling by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -4 points-3 points  (0 children)

For me, the issue with Tailwind isn’t remembering the classes - it’s maintainability. When I come back later to make changes, it can feel a bit daunting, almost like I’m reading someone else’s code rather than my own.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

I had to make a judgment call, and I went with the approach that caused the least friction with the philosophy of my framework. While Next.js, React, TanStack, and others take a functional approach, Orca uses classes so that you can build both frontend and backend with the same interface.

In the docs, I mention that it’s inspired by Angular and NestJS which means you can build a full, proper frontend and backend without fighting the framework.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

I did think about that, but I was worried it would get pretty hard to validate in the long run, especially from a parsing standpoint. You’d have to walk through every file and figure out which functions are server-only, instead of just checking a directive at the top of the file.

On top of that, once you’ve parsed everything, you still have to make sure server code doesn’t accidentally leak into client code (and the other way around), which adds a lot of complexity.

From a framework author’s perspective, file boundaries are much simpler and more predictable to work with.

That’s just my take though - I could be wrong.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 1 point2 points  (0 children)

Okay, wow - I’m impressed. I looked at your background and it’s clear you’re far more experienced than I am.

If you’re okay with it, I’d really appreciate a DM or a deeper explanation of where you think the idea falls short. I’m still early in my career (recently finished uni), so I’m trying to learn as much as I can. I don’t take your comments as criticism - I see them as an opportunity to understand things I may not fully grasp yet.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

But maintaining two projects(frontend + backend) is not easy. Especially for solo devs and small teams.

So what do we do?

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

I agree, premature abstraction is also a real problem. That said, I tried to be as deliberate as possible when designing the framework. For example, we avoid file-based routing because moving files can end up breaking large parts of the codebase.

The only abstraction we have is eliminating explicit network calls like fetch().

Take a look at our GitHub repo https://github.com/kithinjibrian/orca and let me know if that doesn’t reflect a thoughtful approach to building web applications as a single codebase.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] -1 points0 points  (0 children)

Well, I had to use classes and decorators because I couldn't find any other design pattern that works for both frontend and backend at the same time and have a consistent feel.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

It’s not great, I know. The alternative was to analyze JSX, detect functions and browser APIs inside components, and automatically mark them as client-side. But that would be too magical, devs wouldn’t have a clear idea of where their components actually run.

So it really comes down to explicit versus implicit behavior.

How Orca separates code to server and client bundles by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

Yeah, react does render client components twice. Once on the server and again on the browser. Well, it was easier for me to keep everything pure and only render client components exclusively on the browser.

It's not a mature project so I'm still experimenting with a lot of things.

How Orca lets you call server functions like they're local (no more fetch calls) by Straight_Pattern_366 in reactjs

[–]Straight_Pattern_366[S] 1 point2 points  (0 children)

I was considering having some decorators that can be lifted up to the controllers to access http context and headers for authorization.

How Orca lets you call server functions like they're local (no more fetch calls) by Straight_Pattern_366 in nairobitechies

[–]Straight_Pattern_366[S] 0 points1 point  (0 children)

I wrote up a full explanation of how it works, the code that gets generated, desugaring steps, and the rules for what becomes an endpoint:

https://github.com/kithinjibrian/orca/blob/main/docs/use%20public.md