<?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: Rivier Grullon</title>
    <description>The latest articles on DEV Community by Rivier Grullon (@riviergrullon).</description>
    <link>https://dev.to/riviergrullon</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F372697%2Faa12be3e-8f3c-4908-ae95-c94d9be2a1bb.JPG</url>
      <title>DEV Community: Rivier Grullon</title>
      <link>https://dev.to/riviergrullon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/riviergrullon"/>
    <language>en</language>
    <item>
      <title>Email validation in JavaScript: test your signup rules with mailrules</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Tue, 27 Oct 2026 03:00:39 +0000</pubDate>
      <link>https://dev.to/riviergrullon/email-validation-in-javascript-test-your-signup-rules-with-mailrules-2fd2</link>
      <guid>https://dev.to/riviergrullon/email-validation-in-javascript-test-your-signup-rules-with-mailrules-2fd2</guid>
      <description>&lt;p&gt;I was asked to add stronger email validation to our forms at work. Honestly, I thought we were overcomplicating it at first.&lt;/p&gt;

&lt;p&gt;Then I started looking into the details.&lt;/p&gt;

&lt;p&gt;An email can have valid syntax and still come from a disposable provider. A signup form might need to reject certain domains, restrict access to a company, or flag shared addresses like &lt;code&gt;support@&lt;/code&gt;. Someone typing &lt;code&gt;gmial.com&lt;/code&gt; probably needs a helpful suggestion.&lt;/p&gt;

&lt;p&gt;Those decisions depend on the application. I wanted a way to define them once, inspect the result, and reuse the same policy across projects.&lt;/p&gt;

&lt;p&gt;That is what I have been building with &lt;a href="https://github.com/RivierGrullon/mailrules" rel="noopener noreferrer"&gt;mailrules&lt;/a&gt;, an MIT-licensed email validation library for JavaScript and TypeScript.&lt;/p&gt;

&lt;p&gt;The latest addition is a &lt;a href="https://riviergrullon.github.io/mailrules/" rel="noopener noreferrer"&gt;live playground&lt;/a&gt;. You can enter an address, change the rules, see the decision, and copy the configuration into your project before installing anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with a small signup policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;mailrules uses &lt;a href="https://github.com/validatorjs/validator.js" rel="noopener noreferrer"&gt;validator.js&lt;/a&gt; for syntax checks and &lt;a href="https://github.com/Manas1820/fakeout" rel="noopener noreferrer"&gt;fakeout&lt;/a&gt; for its default disposable-domain data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;mailrules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a policy that rejects known disposable domains and a custom blocked domain, suggests possible typos, and warns about role addresses:&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;createEmailValidator&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="s1"&gt;mailrules&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;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEmailValidator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blocklist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spam.example&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="na"&gt;suggestions&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;roleAccounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&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;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello@mailinator.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ['disposable']&lt;/span&gt;

&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person@spam.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ['blocked']&lt;/span&gt;

&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;support@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 'role_account' — a warning; the address is still accepted&lt;/span&gt;

&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alex@gmial.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;suggestion&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 'alex@gmail.com'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suggestions are advisory. They never replace the submitted address or change whether it passes validation. A result can contain both a rejection and a suggestion; for example, the installed disposable dataset also flags &lt;code&gt;gmial.com&lt;/code&gt;. If someone chooses the suggested address, validate that new value too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See why an address was rejected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A boolean is useful for a form, but it does not explain which configuration entry caused a rejection. For that, there is &lt;code&gt;explain()&lt;/code&gt;:&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person@sub.spam.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 'blocked'&lt;/span&gt;

&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchedRule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// {&lt;/span&gt;
&lt;span class="c1"&gt;//   source: 'blocklist',&lt;/span&gt;
&lt;span class="c1"&gt;//   type: 'domain',&lt;/span&gt;
&lt;span class="c1"&gt;//   value: 'spam.example',&lt;/span&gt;
&lt;span class="c1"&gt;//   matchedSubdomain: true&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Domain rules include subdomains by default. You can turn that off with &lt;code&gt;includeSubdomains: false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Allowlists also need predictable behavior: an explicit block always wins in mailrules. An allowlist can exempt an address from disposable rejection, but it does not override a blocklist entry. For an invitation-only or company-only form, &lt;code&gt;allowlistMode: 'only'&lt;/code&gt; requires an allowlist match.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try the policy before wiring it into a form&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://riviergrullon.github.io/mailrules/" rel="noopener noreferrer"&gt;playground&lt;/a&gt;, you can edit domain and mailbox lists, switch role-address and free-provider policies, inspect the result, and copy JavaScript or React examples.&lt;/p&gt;

&lt;p&gt;Role addresses and free providers each support classification, warnings, or blocking. Both checks are off by default. A provider-list non-match does not prove an address belongs to a business, and a Gmail address is not inherently a bad signup.&lt;/p&gt;

&lt;p&gt;The playground also has a working React Hook Form + Zod example, so you can see how a policy affects field errors and normalized output. Validation happens locally in your browser; the playground does not send the entered address to a validation service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reuse it with Zod and React Hook Form&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The optional Zod 4 adapter turns the same validator into a schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;mailrules zod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;z&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="s1"&gt;zod&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;zodEmail&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="s1"&gt;mailrules/zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Reuse the validator from the first example.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signupSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;zodEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;signupSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; Alice@EXAMPLE.COM &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// { email: 'Alice@example.com' }&lt;/span&gt;

&lt;span class="nx"&gt;signupSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello@mailinator.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can pass that schema to React Hook Form through &lt;code&gt;zodResolver&lt;/code&gt;. The &lt;a href="https://github.com/RivierGrullon/mailrules/blob/main/docs/integrations.md" rel="noopener noreferrer"&gt;integration guide&lt;/a&gt; includes the full form example and a Standard Schema adapter for tools that support it.&lt;/p&gt;

&lt;p&gt;Warnings remain successful schema results. Use &lt;code&gt;check()&lt;/code&gt; or &lt;code&gt;explain()&lt;/code&gt; when you want to display those warnings separately. Apply the policy on the backend accepting submissions as well, since browser checks can be bypassed.&lt;/p&gt;

&lt;p&gt;React, Zod, and the playground are not required downloads for a normal mailrules installation. Install Zod when you use its adapter. The playground lives in the same repository but is excluded from the npm package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is also a CSV command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For reviewing an existing list with an &lt;code&gt;email&lt;/code&gt; column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mailrules &lt;span class="nt"&gt;--input&lt;/span&gt; contacts.csv &lt;span class="nt"&gt;--status&lt;/span&gt; rejected &lt;span class="nt"&gt;--output&lt;/span&gt; rejected.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This exports rejected rows with validation reasons. You can also export accepted rows or supply a JSON rules configuration. The CLI runs on Node.js 22.12 or newer and processes bounded files in memory; the guide documents its limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What “accepted” means here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;mailrules checks syntax and your configured application rules locally, in a browser bundle or Node.js. It does not check DNS, MX records, or SMTP, and an accepted result does not establish that a mailbox exists or that the person submitting it owns it.&lt;/p&gt;

&lt;p&gt;There are tools with a broader verification scope, including &lt;a href="https://github.com/email-check-app/email-validator-js" rel="noopener noreferrer"&gt;email-validator-js&lt;/a&gt;, which documents MX and SMTP checks and a hosted API. For this project, I wanted reusable local policies with clear explanations.&lt;/p&gt;

&lt;p&gt;If you have dealt with messy signup forms, I would love to hear about a rule that was harder to get right than you expected. Especially cases where a strict rule ended up rejecting legitimate users.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://riviergrullon.github.io/mailrules/" rel="noopener noreferrer"&gt;Try the playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/RivierGrullon/mailrules" rel="noopener noreferrer"&gt;Source code and documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/mailrules" rel="noopener noreferrer"&gt;Install from npm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Email validation with disposable detection, blocklists and allowlists in TypeScript</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Tue, 27 Oct 2026 00:25:01 +0000</pubDate>
      <link>https://dev.to/riviergrullon/email-validation-with-disposable-detection-blocklists-and-allowlists-in-typescript-1php</link>
      <guid>https://dev.to/riviergrullon/email-validation-with-disposable-detection-blocklists-and-allowlists-in-typescript-1php</guid>
      <description>&lt;p&gt;An email can have valid syntax and still fail your application's signup rules. You might want to reject disposable providers, block a specific mailbox, or accept only addresses from a company's domain.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/RivierGrullon/mailrules" rel="noopener noreferrer"&gt;mailrules&lt;/a&gt; to bring those decisions into one configurable TypeScript/JavaScript API. Version 0.1.0 is available on &lt;a href="https://www.npmjs.com/package/mailrules" rel="noopener noreferrer"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a reusable validator
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;mailrules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;createEmailValidator&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="s1"&gt;mailrules&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;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEmailValidator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blocklist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spam.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abuse@example.com&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="na"&gt;allowlist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trusted@mailinator.com&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person@mailinator.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['disposable']&lt;/span&gt;
&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person@spam.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['blocked']&lt;/span&gt;
&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trusted@mailinator.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['invalid_format']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the validator once and reuse it. Lists are copied, normalized and indexed during construction. Validation is synchronous and makes no network requests.&lt;/p&gt;

&lt;p&gt;The default entry uses &lt;code&gt;validator.js&lt;/code&gt; for syntax and &lt;code&gt;fakeout&lt;/code&gt; for disposable domains. The underlying dataset comes from the &lt;code&gt;disposable-email-domains&lt;/code&gt; project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the policy explicit
&lt;/h2&gt;

&lt;p&gt;An allowlist entry normally creates an exception to disposable-email rejection. To restrict access to specific domains or addresses, use &lt;code&gt;allowlistMode: 'only'&lt;/code&gt;:&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;teamOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEmailValidator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;allowlistMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;allowlist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;company.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contractor@partner.example&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;teamOnly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;staff@company.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;teamOnly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;staff@eu.company.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;teamOnly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;someone@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['not_allowed']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Domain rules include subdomains by default. Set &lt;code&gt;includeSubdomains: false&lt;/code&gt; to require exact domain matches.&lt;/p&gt;

&lt;p&gt;Rejection checks run in a defined order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Invalid email syntax.&lt;/li&gt;
&lt;li&gt;Explicit blocklist match.&lt;/li&gt;
&lt;li&gt;Missing allowlist match in &lt;code&gt;'only'&lt;/code&gt; mode.&lt;/li&gt;
&lt;li&gt;Disposable domain without an allowed exception.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An explicit block always wins over an allowlist exception. The result includes a stable reason code so the application can decide what feedback to show.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bring your own disposable-domain data
&lt;/h2&gt;

&lt;p&gt;Use the core entry when you want to manage that data yourself:&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;createEmailValidator&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="s1"&gt;mailrules/core&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;customValidator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEmailValidator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;disposableDomains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;burner.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;temporary.example&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;customValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@burner.example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['disposable']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;mailrules/core&lt;/code&gt; defaults to an empty disposable dataset and does not import &lt;code&gt;fakeout&lt;/code&gt;. The npm package still declares &lt;code&gt;fakeout&lt;/code&gt; as a dependency. A supplied dataset replaces the default dataset.&lt;/p&gt;

&lt;p&gt;Installed data does not refresh automatically. Update dependencies and redeploy to pick up changes, or supply updated data and construct a new validator.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the result tells you
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;valid: true&lt;/code&gt; means the address passed syntax checks and your configured rules. It does not establish that the mailbox exists or belongs to the person submitting it. There are no DNS, MX or SMTP checks; ownership still requires a confirmation flow.&lt;/p&gt;

&lt;p&gt;Domain names are normalized, while local-part case and plus tags are preserved. Exact mailbox rules therefore distinguish &lt;code&gt;User@example.com&lt;/code&gt; from &lt;code&gt;user@example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The package supports ESM, CommonJS, Node.js 22.12+ and modern browser bundlers. Apply the same policy on the server when accepting form submissions.&lt;/p&gt;

&lt;p&gt;I'd appreciate feedback on the rule precedence and API, especially from developers who have had to handle exceptions to disposable-email blocking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/RivierGrullon/mailrules" rel="noopener noreferrer"&gt;Source and documentation&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/mailrules" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Rate Forge: Calculate the Exact Hourly Rate You Need as a Freelancer</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:24:40 +0000</pubDate>
      <link>https://dev.to/riviergrullon/rate-forge-calculate-the-exact-hourly-rate-you-need-as-a-freelancer-caa</link>
      <guid>https://dev.to/riviergrullon/rate-forge-calculate-the-exact-hourly-rate-you-need-as-a-freelancer-caa</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Calculate your real minimum freelance rate — self-employment taxes, healthcare, overhead, and utilization all factored in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/rate-forge" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/rate-forge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most freelancers set rates by looking at what others charge and picking a competitive-sounding number. This is how you end up working 50 hours a week but taking home far less than expected.&lt;/p&gt;

&lt;p&gt;Freelance rates need to account for things employed workers never think about: self-employment taxes, healthcare, non-billable time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Rate Forge
&lt;/h2&gt;

&lt;p&gt;Rate Forge walks you through every cost factor: target take-home salary, self-employment taxes, healthcare, retirement contributions, overhead, vacation days, and realistic billable utilization. The output is the minimum you must charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate Forge is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Target salary with take-home reverse calculation&lt;/li&gt;
&lt;li&gt;Self-employment tax calculator&lt;/li&gt;
&lt;li&gt;Healthcare premium input&lt;/li&gt;
&lt;li&gt;Retirement contribution planning&lt;/li&gt;
&lt;li&gt;Overhead costs (software, equipment, professional development)&lt;/li&gt;
&lt;li&gt;Billable utilization rate — accounts for non-billable time&lt;/li&gt;
&lt;li&gt;Minimum hourly rate with buffer recommendations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Freelancers of all types — developers, designers, writers, consultants — who want to set rates that actually cover their real costs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/rate-forge" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/rate-forge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>entrepreneur</category>
      <category>business</category>
      <category>selfemployed</category>
    </item>
    <item>
      <title>Clean My Leads: Clean, Normalize, and Deduplicate Messy CRM Lead Lists in One Click</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:22:52 +0000</pubDate>
      <link>https://dev.to/riviergrullon/clean-my-leads-clean-normalize-and-deduplicate-messy-crm-lead-lists-in-one-click-57hn</link>
      <guid>https://dev.to/riviergrullon/clean-my-leads-clean-normalize-and-deduplicate-messy-crm-lead-lists-in-one-click-57hn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Clean, normalize, and deduplicate messy lead lists and CRM exports in one click. Import-ready CSV in seconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/clean-my-leads" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/clean-my-leads&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every sales team eventually ends up with a lead list disaster. Names in ALL CAPS mixed with lowercase, phone numbers in 6 different formats, emails with trailing spaces, duplicates everywhere.&lt;/p&gt;

&lt;p&gt;CRM imports that fail validation are one of the most frustrating sources of wasted time in sales operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Clean My Leads
&lt;/h2&gt;

&lt;p&gt;Clean My Leads applies intelligent normalization in one pass: standardizes phone formats, title-cases names, strips whitespace, deduplicates on email or phone, and produces an import-ready CSV for any CRM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean My Leads is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Normalizes phone numbers to E.164 or local format&lt;/li&gt;
&lt;li&gt;Standardizes email addresses (lowercase, trim whitespace)&lt;/li&gt;
&lt;li&gt;Applies proper name casing (Title Case)&lt;/li&gt;
&lt;li&gt;Deduplicates by email and/or phone number&lt;/li&gt;
&lt;li&gt;Flags missing required fields for manual review&lt;/li&gt;
&lt;li&gt;Exports clean import-ready CSV — works with any CRM&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Sales reps, sales ops teams, SDRs, and marketers working with lead lists from multiple sources.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/clean-my-leads" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/clean-my-leads&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sales</category>
      <category>crm</category>
      <category>marketing</category>
      <category>entrepreneur</category>
    </item>
    <item>
      <title>Thread2Print: Convert Twitter/X Threads into Clean, Printable Documents</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:20:37 +0000</pubDate>
      <link>https://dev.to/riviergrullon/thread2print-convert-twitterx-threads-into-clean-printable-documents-5c3h</link>
      <guid>https://dev.to/riviergrullon/thread2print-convert-twitterx-threads-into-clean-printable-documents-5c3h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Paste any Twitter/X thread or wall of text and get a clean, distraction-free, printable version instantly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/ThreadPrint" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/ThreadPrint&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Twitter/X threads contain some of the best expert knowledge on the internet — but reading them on the platform means fighting infinite scroll, retweet noise, ads, and trending topics.&lt;/p&gt;

&lt;p&gt;Some of the best writing is trapped in thread format.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Thread2Print
&lt;/h2&gt;

&lt;p&gt;Thread2Print converts any thread (or any wall of text) into a clean, readable, printable document. Paste the content, get back a beautifully formatted page you can read, print, or save as PDF — stripped of all platform noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thread2Print is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Paste any thread or text — auto-detects and formats&lt;/li&gt;
&lt;li&gt;Clean typography optimized for long-form reading&lt;/li&gt;
&lt;li&gt;Print-ready layout — save as PDF from browser&lt;/li&gt;
&lt;li&gt;Strips retweet noise and platform clutter&lt;/li&gt;
&lt;li&gt;Preserves links and media captions&lt;/li&gt;
&lt;li&gt;100% browser-based, instant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Thread readers, knowledge workers, students, and anyone who wants to save threads for offline reading.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/ThreadPrint" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/ThreadPrint&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>reading</category>
      <category>tools</category>
      <category>writing</category>
    </item>
    <item>
      <title>Timestamp Ninja: Generate YouTube Chapter Timestamps and Podcast Show Notes Instantly</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:20:03 +0000</pubDate>
      <link>https://dev.to/riviergrullon/timestamp-ninja-generate-youtube-chapter-timestamps-and-podcast-show-notes-instantly-1apj</link>
      <guid>https://dev.to/riviergrullon/timestamp-ninja-generate-youtube-chapter-timestamps-and-podcast-show-notes-instantly-1apj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Generate YouTube chapter timestamps and podcast show notes from your recording notes in seconds. Stop manual time-coding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/TimeStampNinja" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/TimeStampNinja&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;After finishing a 2-hour recording, you have to go back and manually write timestamps for every section. Scrub through the video, note the times, format them into YouTube chapter format, do it again for podcast show notes.&lt;/p&gt;

&lt;p&gt;This can take 30-60 minutes per episode, every single time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Timestamp Ninja
&lt;/h2&gt;

&lt;p&gt;Timestamp Ninja takes your raw recording notes — even rough ones with approximate times — and formats them into publication-ready YouTube chapters and podcast show notes in one pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timestamp Ninja is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Parse rough time notes and auto-format to HH:MM:SS or MM:SS&lt;/li&gt;
&lt;li&gt;Generate YouTube chapter descriptions (correct format)&lt;/li&gt;
&lt;li&gt;Generate podcast show notes (multiple formats supported)&lt;/li&gt;
&lt;li&gt;Batch processing — handle a full episode in one paste&lt;/li&gt;
&lt;li&gt;Export as plain text, Markdown, or formatted HTML&lt;/li&gt;
&lt;li&gt;100% browser-based, instant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;YouTubers, podcasters, content creators, and video editors who produce long-form audio or video.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/TimeStampNinja" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/TimeStampNinja&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>youtube</category>
      <category>podcast</category>
      <category>contentcreation</category>
      <category>creator</category>
    </item>
    <item>
      <title>BatchResize: Resize Images to Every Social Media Format in One Shot</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:19:36 +0000</pubDate>
      <link>https://dev.to/riviergrullon/batchresize-resize-images-to-every-social-media-format-in-one-shot-110d</link>
      <guid>https://dev.to/riviergrullon/batchresize-resize-images-to-every-social-media-format-in-one-shot-110d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Resize your images to every social media format in one shot — Instagram, Twitter/X, LinkedIn, TikTok, and more. Zero uploads.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/batch-resizer" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/batch-resizer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Social media has fragmented image dimensions into a nightmare. Instagram wants 1:1, 4:5, and 16:9. Twitter wants 16:9. LinkedIn has its own sizes. Every piece of content requires resizing the same image 6-8 times.&lt;/p&gt;

&lt;p&gt;For solo creators or small marketing teams, this is hours of repetitive work every week.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing BatchResize
&lt;/h2&gt;

&lt;p&gt;BatchResize processes all your social media formats in one pass. Upload your image, select your target platforms, and download all resized versions in a ZIP — processed entirely in your browser with no upload required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BatchResize is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Covers Instagram (Feed, Story, Reel), Twitter/X, LinkedIn, TikTok, Facebook, YouTube&lt;/li&gt;
&lt;li&gt;Smart crop modes: center, face-aware, manual&lt;/li&gt;
&lt;li&gt;Batch all platforms in one click&lt;/li&gt;
&lt;li&gt;Downloads as ZIP with properly named files&lt;/li&gt;
&lt;li&gt;Zero cloud uploads — processed in your browser&lt;/li&gt;
&lt;li&gt;No watermarks, no account required&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Social media managers, content creators, marketing teams, and solo founders posting across multiple platforms.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/batch-resizer" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/batch-resizer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>socialmedia</category>
      <category>design</category>
      <category>marketing</category>
      <category>contentcreation</category>
    </item>
    <item>
      <title>WebP Cruncher: Batch Convert Images to WebP for Faster Page Loads and Better SEO</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:18:36 +0000</pubDate>
      <link>https://dev.to/riviergrullon/webp-cruncher-batch-convert-images-to-webp-for-faster-page-loads-and-better-seo-5d3e</link>
      <guid>https://dev.to/riviergrullon/webp-cruncher-batch-convert-images-to-webp-for-faster-page-loads-and-better-seo-5d3e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Batch convert and compress images to WebP for faster page loads and better SEO scores. No uploads, no limits, no watermarks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/image-cruncher" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/image-cruncher&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;PageSpeed Insights keeps telling you to serve images in next-gen formats. WebP delivers 25-35% smaller files than JPEG or PNG. But converting your existing image library is tedious.&lt;/p&gt;

&lt;p&gt;Most tools process server-side (a privacy concern), watermark the output, or limit batch size behind a paywall.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing WebP Cruncher
&lt;/h2&gt;

&lt;p&gt;WebP Cruncher converts your entire image library to WebP in a single batch, using the Canvas API directly in your browser. No file size limits, no watermarks, no uploads — drag in your images and download a ZIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebP Cruncher is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Batch convert any number of images to WebP&lt;/li&gt;
&lt;li&gt;Quality slider (0-100) with live file size preview&lt;/li&gt;
&lt;li&gt;Supports PNG, JPEG, GIF (first frame), and BMP input&lt;/li&gt;
&lt;li&gt;Downloads all converted images as a ZIP&lt;/li&gt;
&lt;li&gt;100% browser-based — no server uploads&lt;/li&gt;
&lt;li&gt;No file size limits, no watermarks, completely free&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Web developers, SEO professionals, site owners, and anyone improving page load speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/image-cruncher" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/image-cruncher&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>performance</category>
      <category>tools</category>
    </item>
    <item>
      <title>POC Nexus Pro: Render HTML Proof-of-Concepts in Mobile, Tablet, and Desktop Device Frames</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:18:08 +0000</pubDate>
      <link>https://dev.to/riviergrullon/poc-nexus-pro-render-html-proof-of-concepts-in-mobile-tablet-and-desktop-device-frames-4ooi</link>
      <guid>https://dev.to/riviergrullon/poc-nexus-pro-render-html-proof-of-concepts-in-mobile-tablet-and-desktop-device-frames-4ooi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Render and screenshot any HTML POC inside mobile, tablet, or desktop device frames. Perfect for QA reports and client demos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/pocViewer" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/pocViewer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Presenting an HTML proof-of-concept to clients means either sending a raw HTML file, taking janky screenshots, or spinning up a hosted demo for a 5-minute review.&lt;/p&gt;

&lt;p&gt;None of these are professional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing POC Nexus Pro
&lt;/h2&gt;

&lt;p&gt;POC Nexus Pro renders your HTML file inside realistic device frames — iPhone, iPad, MacBook, desktop monitor — and lets you take clean screenshots without needing real devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POC Nexus Pro is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Renders HTML files inside mobile, tablet, and desktop device frames&lt;/li&gt;
&lt;li&gt;Multiple device choices: iPhone, iPad, Android, MacBook, desktop&lt;/li&gt;
&lt;li&gt;Screenshot export at multiple resolutions&lt;/li&gt;
&lt;li&gt;Responsive preview — test how your layout adapts&lt;/li&gt;
&lt;li&gt;Multiple frame themes (light/dark bezels)&lt;/li&gt;
&lt;li&gt;100% browser-based&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Frontend developers, UI/UX designers, QA engineers, and freelancers presenting work to clients.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/pocViewer" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/pocViewer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>uidesign</category>
      <category>frontend</category>
      <category>qa</category>
    </item>
    <item>
      <title>Bulk Redirect Validator: Validate Hundreds of URL Redirects in Seconds</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:16:45 +0000</pubDate>
      <link>https://dev.to/riviergrullon/bulk-redirect-validator-validate-hundreds-of-url-redirects-in-seconds-564c</link>
      <guid>https://dev.to/riviergrullon/bulk-redirect-validator-validate-hundreds-of-url-redirects-in-seconds-564c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Validate hundreds of URL redirects by generating JS console scripts or cURL bash commands — no server access needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/redirect" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/redirect&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;After a site migration you need to verify hundreds of redirects are working correctly. Doing this manually is impossible at scale, and most tools require uploading your URL list to a third-party service.&lt;/p&gt;

&lt;p&gt;There's a better way that keeps your data private.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Bulk Redirect Validator
&lt;/h2&gt;

&lt;p&gt;Bulk Redirect Validator generates JavaScript console scripts and cURL bash commands you run yourself to test redirect chains. Paste your URL pairs, get a test script, run it — no third-party server sees your URLs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bulk Redirect Validator is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Input source and destination URL pairs in bulk&lt;/li&gt;
&lt;li&gt;Generate JavaScript console test script (run in Chrome DevTools)&lt;/li&gt;
&lt;li&gt;Generate cURL bash script (run in terminal)&lt;/li&gt;
&lt;li&gt;Test for 301, 302, 307, 308 and final destination&lt;/li&gt;
&lt;li&gt;Detect redirect chains and loops&lt;/li&gt;
&lt;li&gt;Export results as CSV for client reporting&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;SEO professionals, web developers, digital agencies, and site admins managing URL migrations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/redirect" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/redirect&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>tools</category>
      <category>webmaster</category>
    </item>
    <item>
      <title>Scope Forge: Build Professional Freelance Estimates That Actually Close Deals</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:15:47 +0000</pubDate>
      <link>https://dev.to/riviergrullon/scope-forge-build-professional-freelance-estimates-that-actually-close-deals-5fm5</link>
      <guid>https://dev.to/riviergrullon/scope-forge-build-professional-freelance-estimates-that-actually-close-deals-5fm5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Build professional project estimates for freelance clients in minutes. Break down scope, set rates, export a polished PDF quote.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/scoopeForge" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/scoopeForge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Freelancers often lose deals not because of price, but because of how they present it. A Google Doc with bullet points and a total number doesn't convey expertise or value.&lt;/p&gt;

&lt;p&gt;Building a detailed, professionally formatted proposal from scratch for every client is time-consuming and inconsistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Scope Forge
&lt;/h2&gt;

&lt;p&gt;Scope Forge is a structured estimate builder: scope breakdown, deliverables, timeline, rates, and terms. The output is a polished PDF proposal that looks like it came from an agency — not a Google Doc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope Forge is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Structured scope builder — deliverables, phases, and milestones&lt;/li&gt;
&lt;li&gt;Hourly or fixed-price estimate modes&lt;/li&gt;
&lt;li&gt;Time estimate breakdown per deliverable&lt;/li&gt;
&lt;li&gt;Payment terms and deposit configuration&lt;/li&gt;
&lt;li&gt;Professional PDF export with your branding&lt;/li&gt;
&lt;li&gt;Save and reuse estimate templates&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Freelancers, consultants, and small agencies who want to present more professional estimates and reduce price negotiation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/scoopeForge" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/scoopeForge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>proposals</category>
      <category>entrepreneur</category>
      <category>consultant</category>
    </item>
    <item>
      <title>Sheet2Mock: Convert Excel/Google Sheets Data to Clean JSON + TypeScript Interfaces</title>
      <dc:creator>Rivier Grullon</dc:creator>
      <pubDate>Thu, 05 Mar 2026 22:14:57 +0000</pubDate>
      <link>https://dev.to/riviergrullon/sheet2mock-convert-excelgoogle-sheets-data-to-clean-json-typescript-interfaces-1n63</link>
      <guid>https://dev.to/riviergrullon/sheet2mock-convert-excelgoogle-sheets-data-to-clean-json-typescript-interfaces-1n63</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Paste your spreadsheet data and instantly get clean JSON mock data plus TypeScript interfaces. Zero config, 100% in-browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔗 Try it free: &lt;a href="https://microsaas-lab.vercel.app/sheet-to-json" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/sheet-to-json&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Frontend developers often wait weeks for real API data before they can build and test UIs. The workaround is writing mock data by hand — creating JSON arrays, TypeScript interfaces, keeping both in sync as the schema evolves.&lt;/p&gt;

&lt;p&gt;This is repetitive, error-prone, and boring.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Sheet2Mock
&lt;/h2&gt;

&lt;p&gt;Sheet2Mock converts your spreadsheet data (pasted from Excel or Google Sheets) into a JSON array and TypeScript interface definition in one step. Paste your data with headers, get production-ready mocks to drop directly into your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sheet2Mock is completely free, requires no account or installation, and runs entirely in your browser. Your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Paste CSV or tabular data from Excel or Google Sheets&lt;/li&gt;
&lt;li&gt;Generates clean JSON array with inferred data types&lt;/li&gt;
&lt;li&gt;Generates TypeScript interface matching the schema&lt;/li&gt;
&lt;li&gt;Type inference: detects strings, numbers, booleans, dates&lt;/li&gt;
&lt;li&gt;One-click copy for JSON and TypeScript separately&lt;/li&gt;
&lt;li&gt;100% in-browser — no API calls, no uploads&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is It For?
&lt;/h2&gt;

&lt;p&gt;Frontend developers who need mock data before the backend is ready, and anyone who receives data requirements in spreadsheet format.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Free
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://microsaas-lab.vercel.app/sheet-to-json" rel="noopener noreferrer"&gt;https://microsaas-lab.vercel.app/sheet-to-json&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No install. Open it and start immediately.&lt;/p&gt;

&lt;p&gt;If you find it useful, share it with someone who could benefit. I'm building more free tools at &lt;a href="https://microsaas-lab.vercel.app" rel="noopener noreferrer"&gt;The Lab&lt;/a&gt; — explore the whole collection.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have feedback or a feature request? Drop a comment below — I read everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>developertools</category>
    </item>
  </channel>
</rss>
