Kemal Yılmaz front-end developer

JavaScript Frameworks - Notes

Notes on JavaScript frameworks.

ℹ️ This is a "notes collection" item. I use notes collection to compile practical information for myself in an unpolished way. It's probably best not to rely on this information without verifying it against up-to-date sources. Also, it is not a good place to use as reference, as the content is subject to frequent updates without warning.

  1. General Notes:
    1. Frameworks offer many features. If you try to utilize everything a framework provides, you’ll easily get lost. It’s better to focus on your specific problem set!
    2. Client-side rendering with components and states is only available with a renderer on client-side. Otherwise, traditional JavaScript and manual DOM manipulation are the only options.
    3. Client-side interactions are not possible without JavaScript enabled. The only client-side interaction available in such cases is the <form> element’s GET and POST actions.
    4. Do not confuse pre-rendering and/or client-side rendering with conditions where JavaScript is disabled.
    5. The first time you consider polyfilling a framework limitation is the moment you should rethink or change your framework and/or architecture! (At least in my experience.) However, almost every framework will have some limitations eventually.
    6. Rendering the same HTML on both the server and client using a single module is only possible when the same language is used on both the server and client.
      1. Consider a form submission with validation errors. Validating input and displaying validation errors to the user requires both server-side (no-JS) rendering and separate client-side rendering. (If we are handling both, which we should.). This is only possible with the modern JavaScript frameworks.
    7. As you explore and interact with various frameworks, you’ll notice that they don’t offer much beyond basic web application components like Routing, Server-side rendering, and Data fetching.
    8. Modern web framework communities often lag behind the frameworks themselves… believe it or not. Sadly, they aren’t like Linux, Eclipse, Inkscape, or Wikipedia communities…
    9. Platform adapters are a mess. While having it’s own flaws, sometimes it is better to have complete separation in between client and server responsibilities.
    10. In my experience, having an idea about more than one framework gives you a bosst on learning stuff. Because these frameworks are most of the time trying to find a solution for the sme web development problems that had have been around for years. You’ll start to see the real problem clearly when you have experience more of them.
  2. https://astro.build/
    1. Astro is my favorite tool when I need more than static site generation, but not a full-fledged client-side framework.
    2. Sharing state between islands requires a third-party library. The official recommendation is Nano Stores.
    3. This is a detail I usually forget about Astro components. 😀 From the official docs: “The most important thing to know about Astro components is that they don’t render on the client. They render to HTML either at build-time or on-demand.
    4. Astro server islands are not a solution for client-side rendering; they are about changing the load priority of partial HTML on a page.
    5. There is no concept of data binding or client-side state in Astro. Nano Stores doesn’t solve this; it just provides a global object to store values accessible across islands.
    6. Without built-in reactivity or binding, framework components are not sufficient to build complex, dashboard-like experiences—if that’s what you’re aiming for.
    7. Great built-in Markdown content support.
  3. https://nextjs.org/
    1. While it is completely possible, a third-party library is required to self-host Next.js across different platforms. OpenNext is one such solution.
    2. I used to criticize platform lock-ins heavily, but when it comes to connecting your data, business, and presentation layers, or adapting an unsupported provider to a modern web framework, … That’s the moment you’ll feel completely alone. It’s important to remember that platforms often solve these problems on your behalf. So, don’t worry too much about platform lock-in if you truly need a feature. In the end, you’ll likely pay the same amount either in developer effort or maintenance cost.
    3. Layouts preserve state, remain interactive, and do not rerender on navigation.
    4. The primary way to navigate between routes is the <Link /> component.
    5. Provides built-in React components <Font />, <Form />, <Image />, <Link />, <Script /> mostly for optimizations.
    6. Built-in font optimization module next/font module for both local and remote fonts.
    7. Layouts and pages are Server Components by default. (Data fetching and rendering happens on the server by default.)
      1. See the next.js explanation about How do Server and Client Components work in Next.js?
      2. In React it’s similar. All components are assumed to be Server Components by default. A Client Component requires an explicit use client directive.
      3. Server Components renders only on the server. Client components can render on both client and server.
      4. In practice, use client annotation is needed for Sever to Client entry points. (Client Components that are imported from Server Components.)
      5. Components without the directive are treated as Shared.
    8. React context is not supported in Server Components.
    9. For data fetching in Server Components use fetch or your custom database connection. In the Client Components use hook or any other data fetching library will do. use hook helps with data streaming from server to client. (No need to await incoming data.)
    10. loading.js file and <Suspense> can be used for data streaming.
    11. By default, layouts and pages are rendered in parallel.
    12. Similar to SvelteKit, Next.js has expected errors and uncaught exceptions. For expected errors, avoid try...catch blocks. Use useActionState helper for error handling on expected errors.
    13. <Form /> component is a helper to switch the form behavior based on action attribute. When action is a string, the <Form> is acts close to HTML native form as implemented by Next.js. When it is a function it implements Server Action feature of React with the React’s <form> component.
    14. No direct access to the POST requests from a page as we did in Astro or SvelteKit. It is required to use the useActionState hook with a use client marked <form> component.
    15. use server is implied on every component in Next.js, so don’t worry about the React components out of app directory unless you explicitly use use client directive in those modules. Otherwise they’re still server components as the continuum of the parent server component. Not sure, from React docs: Note that a single module may be evaluated on the server when imported from server code and on the client when imported from client code. When a component module contains a ‘use client’ directive, any usage of that component is guaranteed to be a Client Component. However, a component can still be evaluated on the client even if it does not have a ‘use client’ directive. A component usage is considered a Client Component if it is defined in module with ‘use client’ directive or when it is a transitive dependency of a module that contains a ‘use client’ directive. Otherwise, it is a Server Component. For apps that use React Server Components, the app is server-rendered by default. See here: https://react.dev/reference/rsc/use-client#how-is-fancytext-both-a-server-and-a-client-component
    16. Resetting the state returned from the useActionState has no straightforward solution.
  4. https://svelte.dev/
    1. SvelteKit is the only framework I felt truly comfortable with for a long time. (Until I hit the need to manage load functions. 😀)
    2. Reactive code is compiled at build time.
    3. From time to time, it puts you in a situation where you think, “It’ll probably work that way.” Especially when you’re dealing with hooks, load functions, actions, etc.
    4. By default, SvelteKit uses SSR on the first navigation and CSR for subsequent navigations.
    5. Built-in automatic event delegation (v5). (For example, adding an onclick event in a loop will only attach a single listener using delegation.)
    6. SvelteKit’s base config overrides the Vite base config. (They’re likely the same in many aspects.)
    7. Authentication integration was the most challenging task for me in SvelteKit. This wasn’t only due to SvelteKit’s design but also because provider documentation was lacking.
    8. The loading data documentation is still unclear to me—especially around reruns.
      1. Rerunning is documented for all server files, but as far as I understand, this only applies to layout loads, not page loads.
      2. The untrack() method is also not well explained.
    9. Does invalidate() run immediately or on the next client-side navigation?
    10. invalidateAll() is only available on the client side; you can’t call it from the server side.
    11. Page-level data loading can be a limitation from time to time. (A new concept of async Svelte on component-level is planned though.)
  5. https://qwik.dev/
    1. Qwik is, I believe, the only framework that offers a notably different approach, featuring no hydration and support for resumability.
    2. I used to be a fan of AngularJS (not the current Angular project), which was created by the same developer.
  6. https://angular.dev/
    1. A typical large-company mindset: one product to fit all needs. I’m not sure it’s the right choice for small-scale projects.
  7. https://react.dev/
    1. In my experience, the “Escape Hatches” section of the docs is the most-read part when I’m dealing with real-world problems.
    2. It’s the mindset behind React that has reshaped modern development workflows. It’s probably the most criticized as well.
    3. It has solved more problems around the human resources aspect of software delopment than it has solved for deleopment itself.
    4. From an engineering perspective, having a declarative technical foundation is great. However the departments we’re working with, sales, product, marketing, … has an imperative mindset. So, applying their requirements into the technical layer always requires extra effort due to the imperative nature of the requests.
    5. server-only and client-only packages help with accidental module leaks. (Accidentanlly importing server-only code into the client.) Packages just help with throwing a build-time error on such conditions.
    6. With fetch, Request object’s cache: 'force-cache' option can help with duplicate requests on multiple render passes. For other methods, React’s built-in cache function can help.
    7. use server directive (Called inside a function body.) is for Server Side Functions, not for Server Components. use client lets you mark what code runs on the client. (Called on top of a module as the first line.)
      1. use server directive can be used at the top of a file to indicate that all functions in the file are server-side. In order to create a Server Function from a Server Component you need to include the directive into the function body not to the module.
    8. use client sets boundary for the imported modules in the same client module. Bundlers follow imports not React component tree.
    9. Server Functions can be invoked by <forms> in server and client or event handlers in the client. If so it is also called as Server Actions. useActionState is the helper to control actions.
    10. Client Components can only import other Client Components.
    11. Errors boundaries are markers to help with more granular error handling through the application hierarchy.
    12. Server Functions can’t be defined in Client Components. It is required to have a separate module with the use server directive at the top of it.
    13. useFormStatus will only return status information for a parent <form>. It’s meant to be used withing the components inside a <form>.
    14. The use hook is to await promises on the client since async components are not supported on the client.
  8. https://www.11ty.dev/
    1. Probably the best static site generator on the internet right now.
  9. https://www.gatsbyjs.com/
    1. Provides a good developer experience.
    2. Features a powerful GraphQL data layer.