<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JYC</title>
    <description>The latest articles on DEV Community by JYC (@jycouet).</description>
    <link>https://dev.to/jycouet</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1477573%2F2a3cd23d-c438-42cc-9d5e-77191c808e0c.jpeg</url>
      <title>DEV Community: JYC</title>
      <link>https://dev.to/jycouet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jycouet"/>
    <language>en</language>
    <item>
      <title>The Power of Less: Streamlining Dependencies with Remult</title>
      <dc:creator>JYC</dc:creator>
      <pubDate>Thu, 13 Jun 2024 11:59:04 +0000</pubDate>
      <link>https://dev.to/jycouet/the-power-of-less-streamlining-dependencies-with-remult-55e2</link>
      <guid>https://dev.to/jycouet/the-power-of-less-streamlining-dependencies-with-remult-55e2</guid>
      <description>&lt;p&gt;In my last post, I shared my epic journey switching to Remult, which shrank my codebase by 75% and turbocharged my development power. 💪 If you haven't checked it out, give it a read &lt;a href="https://dev.to/jycouet/less-code-75-more-power-with-remult-325m"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Today, let’s dive deeper into one of the most transformative aspects of my switch: Reducing Dependencies. Streamlining my tech stack not only simplified my workflow but also enhanced my project's maintainability. Let’s break it down:&lt;/p&gt;

&lt;h2&gt;
  
  
  Deps Reduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prisma
&lt;/h3&gt;

&lt;p&gt;I've had a soft spot for Prisma; its DSL is user-friendly and learning it is a breeze. But, here's the catch - while it streamlines some processes, it introduces its own things (DSL, Migrations, File management, Syntax, etc.). Plus, I found myself using Aurora to manage multiple Prisma models, which, again, adds up in the stack. This + this + that... It starts to be a lot!&lt;/p&gt;

&lt;p&gt;
  Disclaimer
  &lt;br&gt;
On the day I write this article, Prisma released this "Schema into Multiple Files". Will I switch back to Prisma? &lt;strong&gt;No&lt;/strong&gt;! I gained so much with Remult that Prisma is not even coming close ;) even with this new preview feature!&lt;br&gt;


&lt;/p&gt;

&lt;p&gt;Switching to Remult, I said goodbye to these additional layers. Remult lets me handle everything from entity definitions to database interactions directly within my usual coding environment, eliminating the need for separate DSLs or configuration files. It’s like getting rid of excess baggage - feels great! It's just TypeScript, no more, no less!&lt;/p&gt;

&lt;p&gt;Some things I gained that were not possible with Prisma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Views: Easily create and manage views in your database.&lt;/li&gt;
&lt;li&gt;Calculated Fields: Simplify your data manipulations by defining fields that are calculated on the fly. You have two flavors of that: &lt;code&gt;serverExpression&lt;/code&gt; or &lt;code&gt;sqlExpression&lt;/code&gt;, both are so convenient!&lt;/li&gt;
&lt;li&gt;Stored Procedures: Incorporate complex business logic and operations directly into your database, with migration management included!&lt;/li&gt;
&lt;li&gt;Admin dashboard: A built-in admin dashboard to manage your data and entities. (Working with your authorization system!!! So it's not something that you use only in development, but also in production if you want)
&lt;iframe class="tweet-embed" id="tweet-1757736965762351227-798" src="https://platform.twitter.com/embed/Tweet.html?id=1757736965762351227"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1757736965762351227-798');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1757736965762351227&amp;amp;theme=dark"
  }



&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note also that AI is REALLLLLLLLY good at raw SQL. And here, we can mix and match raw SQL (in &lt;code&gt;sqlExpression&lt;/code&gt;) and Remult. &lt;/p&gt;

&lt;p&gt;👉 It's a perfect match 🥳&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;p&gt;As a longtime GraphQL enthusiast (shoutout to &lt;a href="https://the-guild.dev/"&gt;The Guild&lt;/a&gt; 👋), it was hard for me to put this part of my stack into question.&lt;/p&gt;

&lt;p&gt;I even built &lt;a href="https://www.kitql.dev/"&gt;KitQL&lt;/a&gt;, a library to help with client and server for GraphQL! Being so much in it you don't realize all the ceremonies you go through anymore to add a functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: KitQL shape changed a lot during the past months. Now, &lt;strong&gt;KitQL&lt;/strong&gt; itself is not a library, &lt;strong&gt;it’s “nothing”&lt;/strong&gt; but a collection of standalone libraries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For GraphQL server, simply use &lt;a href="https://the-guild.dev/graphql/yoga-server"&gt;graphql yoga&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For GraphQL client, simply use &lt;a href="https://houdinigraphql.com/"&gt;houdini&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But now, I realize that GraphQL, eventually, is an implementation detail, mainly focusing on the network layer. The second key part of GraphQL is fragments, but also focusing only on network data. And it's here that Remult shines so much: taking advantage of metadata.&lt;/p&gt;

&lt;p&gt;I give you 2 examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;metadata. When I was designing a Grid, I had to define columns with headers, then populate the Grid with data coming from the network (GraphQL). So you have to define headers on one side and network data on the other side. With Remult, you define on fields of your entities a property called &lt;code&gt;caption&lt;/code&gt;. And that's it! Now, I just define columns, and it will bring data &amp;amp; headers, all in one. Also, when the field is used in another place, you can get its &lt;code&gt;caption&lt;/code&gt;. So you have a single source of truth for your entire application.&lt;/li&gt;
&lt;li&gt;enums. With GraphQL, you have to define your enums in your schema, and then, you have to define them in your client code. I mean that you will have to have a &lt;code&gt;caption&lt;/code&gt; displayed for your users instead of the enum value. So it's some code to add somewhere... to organize, to centralize, ... With Remult, you define your enums in your entities field by field, and you can use them everywhere in your application. And you can get the caption of the enum value. So you have a single source of truth for your entire application. &lt;strong&gt;Bonus&lt;/strong&gt;: You can have a lot more than just &lt;code&gt;caption&lt;/code&gt;!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 So for now, I just removed GraphQL from my stack! &lt;em&gt;(it's a big statement for me!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt;: Remult can enable GraphQL in a few lines of code (check it out &lt;a href="https://remult.dev/docs/adding-graphql#adding-graphql"&gt;here&lt;/a&gt;). So if you really need it, you can have it 😉 &lt;em&gt;(it was my first contribution btw)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: I'm sure that one day I'll develop a &lt;a href="https://houdinigraphql.com/api/client-plugins"&gt;Houdini Plugin&lt;/a&gt;, to take advantage of all metadata that Remult can provide + optimize the network layer with this internal detail: GraphQL! &lt;em&gt;(In my "work work", it's premature optimization)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Felte, Vest, Zod
&lt;/h3&gt;

&lt;p&gt;Before Remult, integrating validations into my projects required additional libraries like Felte and/or Vest and/or Zod. Now, validations are an integral part of my entities. This integration reduces the number of dependencies and aligns validation logic tightly with the rest of my application logic.&lt;/p&gt;

&lt;p&gt;What else to say? Nothing much! It's again a single source of truth for your entire application, validation frontend and backend in a single place 😍.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meta Frameworks and Remult
&lt;/h2&gt;

&lt;p&gt;In the JavaScript world, you have frameworks and meta frameworks...! you might wonder if Remult still has its place? My answer? &lt;strong&gt;An absolute YES&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Meta Frameworks like SvelteKit, Next.js, and others tend to fragment your code. It's easy to fetch a list of users in one spot, but what about maintaining a single source of truth? With this approach, your business logic starts to be spread across routes and components. Remult, in contrast, keeps this business logic consistent and centralized, significantly tidying up your codebase.&lt;/p&gt;

&lt;p&gt;For instance, imagine you are with Prisma and NextJs. Every time you fetch users, you must remember to exclude the disabled ones. Prisma focuses &lt;strong&gt;ONLY&lt;/strong&gt; on data retrieval, and the meta framework &lt;strong&gt;ONLY&lt;/strong&gt; on serving data, and no one is responsible for the business logic, so you add this logic in a route, in a component, ... somewhere... and everywhere! With Remult, business logic remains consistent and centralized: in the entity definition. So you can be sure that every time you fetch users, the disabled ones are excluded for example!&lt;/p&gt;

&lt;p&gt;Meta Frameworks give you tools to build an app, but you still need to do a lot around to have clean and maintainable code. Take validation for example, with Meta Frameworks you have "nothing"... So you can validate data in Actions, but it's your own concern, you have to do it yourself... You will probably add a dependency to help you, you will fragment your code to have frontend and backend validation, ... With Remult, you have it all in one place, and it's so easy to use!&lt;/p&gt;




&lt;p&gt;Stay tuned for more deep dives into Remult's features and how you can leverage them to supercharge your development process. Next time, we’ll explore advanced features like lifecycle hooks and backend methods which can further refine your coding experience.&lt;/p&gt;

&lt;p&gt;Feel free to drop by &lt;a href="https://github.com/remult/remult"&gt;⭐️ Remult&lt;/a&gt; and join our growing community. &lt;br&gt;
👉 Let's code smarter, not harder!&lt;/p&gt;

&lt;p&gt;If you have a question or suggestion, do not hesitate to write here or DM me.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fullstack</category>
      <category>orm</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Less Code (-75%) &amp; More Power (💪) with Remult</title>
      <dc:creator>JYC</dc:creator>
      <pubDate>Wed, 08 May 2024 13:37:17 +0000</pubDate>
      <link>https://dev.to/jycouet/less-code-75-more-power-with-remult-325m</link>
      <guid>https://dev.to/jycouet/less-code-75-more-power-with-remult-325m</guid>
      <description>&lt;p&gt;I've been using &lt;a href="https://remult.dev"&gt;Remult&lt;/a&gt; for a while now and I'm really happy with it.&lt;br&gt;
Let me walk you through why I made the switch and how it went.&lt;br&gt;

  Spoiler PR Stats 🧐
  &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvfghhbvkymbgakpn5ck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvfghhbvkymbgakpn5ck.png" alt="Switch to remult PR" width="237" height="80"&gt;&lt;/a&gt;&lt;br&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;First off, what is "Remult"? It's a library that lets you build applications entirely in TypeScript. The main concept here is SSoT—Single Source of Truth. This means you can define everything just once and use it everywhere (client, server, db, validation, etc.). As someone who appreciates efficiency &lt;em&gt;(OK, I'm lazy)&lt;/em&gt;, I love not having to write &lt;strong&gt;and maintain&lt;/strong&gt; the same code twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Discovery
&lt;/h2&gt;

&lt;p&gt;Back in February 2023, I attended &lt;a href="https://viennajs.org"&gt;ViennaJS&lt;/a&gt; where &lt;a href="https://twitter.com/noamhonig"&gt;Noam Honig&lt;/a&gt;, the creator of Remult, was speaking. His presentation was eye-opening. In just 30 minutes, he transformed a client-only application into a full-stack application complete with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database integration&lt;/li&gt;
&lt;li&gt;Access control&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Even deployment !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I thought to myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why am I spending more time then him doing similar things? I need to try this asap!!!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At &lt;a href="https://twitter.com/confrontjs"&gt;confrontjs&lt;/a&gt; this year:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1778777683452694637-897" src="https://platform.twitter.com/embed/Tweet.html?id=1778777683452694637"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1778777683452694637-897');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1778777683452694637&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  The Decision
&lt;/h2&gt;

&lt;p&gt;We all have our preferred tech stacks, and it's tough to see a demo like that and believe that one tool can solve all your problems. So you need a step back, breath, and assess your current stack and be open to letting go some parts.&lt;/p&gt;

&lt;p&gt;=&amp;gt; Be open to good changes. Change your habits for the better! ;)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You know what is the best part? It's not an all-or-nothing decision, you can add remult step-by-step 🎉&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initial Glimpse
&lt;/h3&gt;

&lt;p&gt;The cool thing is that you can simply add Remult to your project and start enjoying its benefits. So, where do you start? Where to set up your source of truth? How to create your first entity? &lt;em&gt;it can be overwhelming to start, but no worries.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since I have a PostgreSQL database, I used &lt;code&gt;remult-cli&lt;/code&gt; to generate all my entities in one go, so I didn't have to start from scratch. Just like that, with one line of code, I had 48 entities in my project, ready to be used. From this point, I could already query my database. It became my ORM without needing to learn a new DSL or syntax.&lt;/p&gt;

&lt;p&gt;In my backend, I can now do things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remult&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$shared/entities/user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isSale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can also work with relations, like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isSale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All this, just from this one shot generator reading from my db schema!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think that it's important to mention that it's a one shot generator, as after my SSoT are my entities, and everything will be derived from it (including migrations!)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My project was using Prisma, and no I didn't remove Prisma in one afternoon! In real life projects, things take time... You have complex queries, you want to make sure everything still works, etc., etc. So I had Prisma &amp;amp; Remult running in parallel for a few weeks, and it's fine, it's the backend. Like this I'm confident to move step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's take more advantage
&lt;/h2&gt;

&lt;p&gt;Now, let's also use Remult in the frontend! On my side, I'm using Svelte, &lt;em&gt;(the thing is that Remult works with all frontends, so pick yours! 🧡)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's say, I want to have a list of sales on my page, I will do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remult&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$shared/entities/user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isSale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait what? It's the same code as before?! &lt;strong&gt;Yes!&lt;/strong&gt;&lt;br&gt;
But here, it will do: &lt;code&gt;page -&amp;gt; API call -&amp;gt; backend -&amp;gt; db&lt;/code&gt;. And all this... typed!&lt;/p&gt;

&lt;p&gt;🤯 🤯 🤯&lt;/p&gt;

&lt;p&gt;So all new features for my app, I start to use this technique... enhance my entities to give more and more knowledge to the SSoT.&lt;/p&gt;

&lt;p&gt;Field caption for example! How many times have you had to display the label of a field and you write over and over again "Name of the user"? With Remult, you can define it once and use it everywhere!&lt;/p&gt;

&lt;p&gt;Same things for validation, you probably want the name to be required, so in the field name, you can add &lt;code&gt;required: true&lt;/code&gt; and that's it! You can use it in the backend and in the frontend! &lt;em&gt;(Validation will run in both places)&lt;/em&gt;. As required is very common, it's a property, but you can also define your own validation function! Like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jyc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can't start with j !!! (it's only for me 😉)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do this; in my app, in reality, I use only already powerful built-in validation. My favorite is probably:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one will run only in the backend, to check if the email is unique in the db. Soooo handy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive into Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Admin UI
&lt;/h3&gt;

&lt;p&gt;This feature was not present when I started, but now it's a game-changer! It's a full admin UI that you can use to manage your entities. It's like a CMS for your entities. You can create, update, delete, search, filter, ... It's a real time saver! &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1757736965762351227-772" src="https://platform.twitter.com/embed/Tweet.html?id=1757736965762351227"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1757736965762351227-772');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1757736965762351227&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;It's also a perfect way to browse your data &lt;strong&gt;and its relations&lt;/strong&gt; with the context &lt;em&gt;thx to nested tables&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As it's using the normal remult api, all security is fully functional.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;salaries&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// All users authenticated can see salaries&lt;/span&gt;
  &lt;span class="na"&gt;allowApiRead&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Allow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authenticated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// SUPER_ADMIN can edit salaries (so better be friend with SUPER_ADMIN!)&lt;/span&gt;
  &lt;span class="na"&gt;allowApiCrud&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUPER_ADMIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Salary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lifecycle hooks
&lt;/h3&gt;

&lt;p&gt;It's so handy to have hooks in your entities &amp;amp; fields! You can do things before or after a save, a delete, a find...&lt;br&gt;
for example, making sure the email is in lowercase and trimmed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a few lines of code, I also implemented ChangeLogs in my app. So I can see who did what and when! Ask me if you want to know more about it ;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend methods
&lt;/h3&gt;

&lt;p&gt;Sometimes, you need to have a very specific data "out of nowhere"; here, you can use backend methods. You just call this function from the frontend, and it will do the front -&amp;gt; back API call for you. It's so flexible!&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits Realized
&lt;/h2&gt;

&lt;p&gt;The main benefit is really this SSoT, as it improves my efficiency, maintenance, and scalability for all my projects.&lt;/p&gt;

&lt;p&gt;Yesterday, I finished my migration; everything is now running on Remult 🥳. And I did a small exercise, a PR to compare &lt;code&gt;now&lt;/code&gt; vs &lt;code&gt;before Remult&lt;/code&gt;:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvfghhbvkymbgakpn5ck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvfghhbvkymbgakpn5ck.png" alt="Switch to remult PR" width="237" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;Yes, there is 4 times less code 🥳 🥳 🥳 !!!&lt;/center&gt;

&lt;p&gt;&lt;em&gt;(With all the features of before, and some new developed along the way!)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you couldn't tell, I'm more than just a bit excited about my switch to Remult. I'm absolutely thrilled! The way it improved my projects by cutting down unnecessary complexity and reducing code bloat is just phenomenal. And guess what? My adventure didn't stop at just using Remult; I've dived deeper and am now actively contributing.&lt;/p&gt;

&lt;p&gt;I’m really pumped to see where we can take Remult next, and I’d love for you to join us on this journey. Whether you're tweaking your current projects or kickstarting new ones, Remult has something to offer. Come and see how it can transform your development experience—let’s code better, faster, and smarter, together!&lt;/p&gt;

&lt;p&gt;Come and say hi &lt;a href="https://github.com/remult/remult"&gt;⭐️ Remult&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fullstack</category>
      <category>orm</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
