<?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: Pawan Bisht</title>
    <description>The latest articles on DEV Community by Pawan Bisht (@pawan_bisht_3aa0838e302b2).</description>
    <link>https://dev.to/pawan_bisht_3aa0838e302b2</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%2F2027359%2F1af53520-120f-47c0-9b2e-770f3825a213.jpg</url>
      <title>DEV Community: Pawan Bisht</title>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pawan_bisht_3aa0838e302b2"/>
    <language>en</language>
    <item>
      <title>Your Database Backup Exists. But Can You Actually Restore It?</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Mon, 14 Sep 2026 06:55:53 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/your-database-backup-exists-but-can-you-actually-restore-it-647</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/your-database-backup-exists-but-can-you-actually-restore-it-647</guid>
      <description>&lt;h1&gt;
  
  
  Your Database Backup Exists. But Can You Actually Restore It?
&lt;/h1&gt;

&lt;p&gt;Most teams have database backups.&lt;/p&gt;

&lt;p&gt;They run on a schedule. They complete successfully. They are stored in S3, RDS, or another backup system. Monitoring tells you that the backup job is green.&lt;/p&gt;

&lt;p&gt;Then one day, something goes wrong.&lt;/p&gt;

&lt;p&gt;A database is corrupted.&lt;br&gt;
A production deployment deletes important data.&lt;br&gt;
An infrastructure failure takes down the database.&lt;br&gt;
Someone needs to recover yesterday's state.&lt;/p&gt;

&lt;p&gt;And suddenly, the important question isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did the backup complete?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Can we actually restore it?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction is easy to overlook.&lt;/p&gt;

&lt;p&gt;A successful backup job proves that data was copied somewhere. It does not necessarily prove that the backup is usable.&lt;/p&gt;
&lt;h2&gt;
  
  
  The backup paradox
&lt;/h2&gt;

&lt;p&gt;Imagine a team with this setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL runs in production.&lt;/li&gt;
&lt;li&gt;Automated backups run every night.&lt;/li&gt;
&lt;li&gt;AWS RDS manages the snapshots.&lt;/li&gt;
&lt;li&gt;The team receives an alert if a backup fails.&lt;/li&gt;
&lt;li&gt;Everything has been green for the last six months.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From an operational dashboard, things look great.&lt;/p&gt;

&lt;p&gt;But what happens if the team discovers that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a required table wasn't included,&lt;/li&gt;
&lt;li&gt;permissions are incorrect after restoration,&lt;/li&gt;
&lt;li&gt;an application expects an index that isn't present,&lt;/li&gt;
&lt;li&gt;foreign-key relationships are broken,&lt;/li&gt;
&lt;li&gt;critical data is missing,&lt;/li&gt;
&lt;li&gt;or restoring the snapshot takes significantly longer than the team's RTO?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backup technically exists.&lt;/p&gt;

&lt;p&gt;But the recovery process is broken.&lt;/p&gt;

&lt;p&gt;This is why &lt;strong&gt;backup testing and restore testing are two different things&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  A backup is not a recovery plan
&lt;/h2&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backup&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We have a copy of the data."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Restore&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We can turn that copy back into a working database."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Recovery validation&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The restored database contains the data and structure our application actually needs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That third step is where many systems stop short.&lt;/p&gt;

&lt;p&gt;You don't necessarily need to run the entire application to validate a database restore.&lt;/p&gt;

&lt;p&gt;You can test the database itself.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;connect&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;schema&lt;/span&gt;
    &lt;span class="na"&gt;expect_tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;customers&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;orders&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;row_count&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foreign_key&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;references&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customers&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;golden_query&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;count(*)&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;FROM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;orders"&lt;/span&gt;
    &lt;span class="na"&gt;expect_min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These checks answer practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can we connect?&lt;/li&gt;
&lt;li&gt;Are the important tables there?&lt;/li&gt;
&lt;li&gt;Is the expected data present?&lt;/li&gt;
&lt;li&gt;Are relationships intact?&lt;/li&gt;
&lt;li&gt;Does a critical query still work?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact checks will depend on the application, but the principle is the same:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't just verify that a backup exists. Verify that the restored state satisfies known invariants.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why manual restore testing doesn't happen often
&lt;/h2&gt;

&lt;p&gt;At this point, someone usually says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We already know we should test restores."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;True.&lt;/p&gt;

&lt;p&gt;The problem is that actually doing it manually is inconvenient.&lt;/p&gt;

&lt;p&gt;A realistic restore test might require someone to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the correct snapshot.&lt;/li&gt;
&lt;li&gt;Restore it into a temporary database.&lt;/li&gt;
&lt;li&gt;Wait for the database to become available.&lt;/li&gt;
&lt;li&gt;Configure credentials.&lt;/li&gt;
&lt;li&gt;Connect to it.&lt;/li&gt;
&lt;li&gt;Run validation queries.&lt;/li&gt;
&lt;li&gt;Check the results.&lt;/li&gt;
&lt;li&gt;Record how long recovery took.&lt;/li&gt;
&lt;li&gt;Delete the temporary database.&lt;/li&gt;
&lt;li&gt;Repeat the process periodically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nobody wants to spend their Friday afternoon doing this.&lt;/p&gt;

&lt;p&gt;So the restore test gets postponed.&lt;/p&gt;

&lt;p&gt;Then postponed again.&lt;/p&gt;

&lt;p&gt;Eventually the team has a backup strategy that has never been seriously exercised.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery time is part of the test
&lt;/h2&gt;

&lt;p&gt;There is another problem with only checking whether a restore succeeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long did it take?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose your recovery objective is one hour.&lt;/p&gt;

&lt;p&gt;Your backup restores successfully, but it takes three hours.&lt;/p&gt;

&lt;p&gt;Technically, the backup works.&lt;/p&gt;

&lt;p&gt;Operationally, it fails your recovery requirement.&lt;/p&gt;

&lt;p&gt;That's why restore validation should measure recovery time as well.&lt;/p&gt;

&lt;p&gt;A useful report might look conceptually like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restore Validation: PASS

Snapshot: latest
Restore time: 18m 42s

Checks:
✓ customers table exists
✓ orders table exists
✓ orders row count &amp;gt;= 1
✓ foreign key orders -&amp;gt; customers intact
✓ golden query passed

Recovery objective: 60m
Result: PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have evidence rather than an assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you test?
&lt;/h2&gt;

&lt;p&gt;You don't need to test every possible database property.&lt;/p&gt;

&lt;p&gt;Start with the things that matter to your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Connectivity
&lt;/h3&gt;

&lt;p&gt;Can you connect to the restored database?&lt;/p&gt;

&lt;p&gt;This sounds obvious, but it establishes the basic recovery path.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Schema
&lt;/h3&gt;

&lt;p&gt;Are critical tables present?&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users
orders
payments
subscriptions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A restore that is missing an important table shouldn't be considered healthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Data volume
&lt;/h3&gt;

&lt;p&gt;Row counts can provide a simple sanity check.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;row_count&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
  &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't a replacement for deep data validation, but it can detect obvious failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Relationships
&lt;/h3&gt;

&lt;p&gt;Database relationships are important.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;orders.customer_id&lt;/code&gt; references &lt;code&gt;customers.id&lt;/code&gt;, you want to know that the restored data doesn't contain orphaned records.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Critical queries
&lt;/h3&gt;

&lt;p&gt;Every application has queries that represent important business functionality.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or something more meaningful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These can become "golden queries" that must continue to work after recovery.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Data freshness
&lt;/h3&gt;

&lt;p&gt;For systems that depend on continuously updated data, freshness can matter as much as row count.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;freshness&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
  &lt;span class="na"&gt;column&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;created_at&lt;/span&gt;
  &lt;span class="na"&gt;max_age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;24h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A database containing millions of rows isn't necessarily healthy if the newest data is several days old.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Indexes and other structural requirements
&lt;/h3&gt;

&lt;p&gt;Sometimes the data is present but the database isn't operationally equivalent to what the application expects.&lt;/p&gt;

&lt;p&gt;Critical indexes can also be validated as part of recovery testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The important part: automate the boring work
&lt;/h2&gt;

&lt;p&gt;This is the idea behind &lt;strong&gt;Revenant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Revenant is a small CLI designed around one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can this database backup actually be restored and validated?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It connects to PostgreSQL and runs checks defined in a &lt;code&gt;revenant.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;For a local database, the workflow can be as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'postgres://user:pass@localhost:5432/mydb?sslmode=disable'&lt;/span&gt;

revenant init &lt;span class="nt"&gt;--plan&lt;/span&gt; my-app &lt;span class="nt"&gt;--force&lt;/span&gt;
revenant verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;init&lt;/code&gt; can inspect an existing PostgreSQL database and generate a starting configuration.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;verify&lt;/code&gt; then runs the defined validation checks.&lt;/p&gt;

&lt;p&gt;For AWS RDS, the workflow can go further.&lt;/p&gt;

&lt;p&gt;Revenant can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the latest RDS snapshot.&lt;/li&gt;
&lt;li&gt;Restore it into a temporary sandbox.&lt;/li&gt;
&lt;li&gt;Run the configured checks.&lt;/li&gt;
&lt;li&gt;Measure recovery time.&lt;/li&gt;
&lt;li&gt;Generate a report.&lt;/li&gt;
&lt;li&gt;Delete the sandbox.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal isn't to replace your backup system.&lt;/p&gt;

&lt;p&gt;AWS RDS, PostgreSQL, cloud providers, and backup tools already do the actual backup work.&lt;/p&gt;

&lt;p&gt;The missing layer is often &lt;strong&gt;proof that recovery works&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat recovery testing like CI
&lt;/h2&gt;

&lt;p&gt;One of the most useful ways to think about restore testing is to treat it like a test suite.&lt;/p&gt;

&lt;p&gt;You already test application code.&lt;/p&gt;

&lt;p&gt;You might run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;before merging code.&lt;/p&gt;

&lt;p&gt;You probably test deployments.&lt;/p&gt;

&lt;p&gt;You may run infrastructure checks.&lt;/p&gt;

&lt;p&gt;But your backup system can also have tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backup
   ↓
Restore
   ↓
Connect
   ↓
Validate schema
   ↓
Validate data
   ↓
Validate relationships
   ↓
Measure recovery time
   ↓
Generate evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this process can run periodically in CI.&lt;/p&gt;

&lt;p&gt;For example, a weekly GitHub Actions workflow can restore a recent snapshot, execute the validation suite, and upload the resulting report.&lt;/p&gt;

&lt;p&gt;Now recovery isn't something you hope works during an incident.&lt;/p&gt;

&lt;p&gt;It's something you've exercised recently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the application out of the restore test
&lt;/h2&gt;

&lt;p&gt;One design choice is particularly useful here.&lt;/p&gt;

&lt;p&gt;Database recovery validation doesn't necessarily need to understand your application code.&lt;/p&gt;

&lt;p&gt;Your application could be written in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Rails&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;or something else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database doesn't care.&lt;/p&gt;

&lt;p&gt;A database-focused recovery tool can validate the database directly through PostgreSQL.&lt;/p&gt;

&lt;p&gt;This makes the approach language-agnostic.&lt;/p&gt;

&lt;p&gt;You define what matters in configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;connect&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;schema&lt;/span&gt;
    &lt;span class="na"&gt;expect_tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;customers&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;orders&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;row_count&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foreign_key&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;references&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool doesn't need to inspect your models or application source code.&lt;/p&gt;

&lt;p&gt;That separation makes the recovery test easier to run independently from the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget cleanup
&lt;/h2&gt;

&lt;p&gt;Automated restore testing introduces another problem: temporary infrastructure.&lt;/p&gt;

&lt;p&gt;If every restore creates an RDS instance and something goes wrong before cleanup, you can end up with abandoned resources.&lt;/p&gt;

&lt;p&gt;That's particularly painful with cloud infrastructure because forgotten resources can become forgotten bills.&lt;/p&gt;

&lt;p&gt;A recovery-testing system therefore needs cleanup as part of the workflow, not as an afterthought.&lt;/p&gt;

&lt;p&gt;For example, a safety-net command can look for Revenant-managed sandbox instances older than a configured age and remove them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;revenant reap &lt;span class="nt"&gt;--max-age&lt;/span&gt; 4h &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And CI workflows can run cleanup even when the validation job fails.&lt;/p&gt;

&lt;p&gt;The rule should be simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the restore test creates infrastructure, the restore test owns the cleanup.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence matters
&lt;/h2&gt;

&lt;p&gt;Another advantage of automated restore testing is that every run can produce evidence.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;report.json
report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON report can be consumed by automation.&lt;/p&gt;

&lt;p&gt;The Markdown report can be attached to a CI run, reviewed by engineers, or retained as operational evidence.&lt;/p&gt;

&lt;p&gt;Instead of saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We think our backups work."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The latest snapshot was restored on September 14. Recovery took 19 minutes, all six validation checks passed, and the sandbox was successfully destroyed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much stronger statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start small
&lt;/h2&gt;

&lt;p&gt;You don't need a huge disaster-recovery testing platform on day one.&lt;/p&gt;

&lt;p&gt;Start with three questions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I connect?
&lt;/h3&gt;

&lt;p&gt;If not, recovery has already failed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the important data there?
&lt;/h3&gt;

&lt;p&gt;Check critical tables, approximate row counts, and a few important queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I recover within my target?
&lt;/h3&gt;

&lt;p&gt;Measure the actual restore time.&lt;/p&gt;

&lt;p&gt;Then expand the test suite as you discover more failure modes.&lt;/p&gt;

&lt;p&gt;The goal isn't to create a perfect replica of production.&lt;/p&gt;

&lt;p&gt;The goal is to eliminate dangerous assumptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The uncomfortable question
&lt;/h2&gt;

&lt;p&gt;Every engineering team should eventually be able to answer this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If our production database disappeared right now, when was the last time we proved that our backup could become a working database?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is "we've never tested it," your backup system isn't necessarily broken.&lt;/p&gt;

&lt;p&gt;But your confidence in it is an assumption.&lt;/p&gt;

&lt;p&gt;And assumptions are exactly what disaster recovery is supposed to eliminate.&lt;/p&gt;

&lt;p&gt;Backups are important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restores are the proof.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  About Revenant
&lt;/h3&gt;

&lt;p&gt;Revenant is an open-source CLI for PostgreSQL backup recovery validation. It supports local PostgreSQL databases and AWS RDS restore workflows, with YAML-based validation checks and JSON/Markdown reports.&lt;/p&gt;

&lt;p&gt;The project is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/277pawan/revenant-cli?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Revenant CLI on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For teams using GitHub Actions, there is also a dedicated action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/277pawan/revenant-action?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Revenant GitHub Action&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>cicd</category>
      <category>javascript</category>
      <category>database</category>
    </item>
    <item>
      <title>PostgreSQL Backup Isn’t Enough: How We Automated Restore Testing</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Mon, 07 Sep 2026 06:31:53 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/postgresql-backup-isnt-enough-how-we-automated-restore-testing-53gc</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/postgresql-backup-isnt-enough-how-we-automated-restore-testing-53gc</guid>
      <description>&lt;p&gt;I Automated the Database Restore Drill Nobody Runs Until 3 AM&lt;/p&gt;

&lt;p&gt;There’s a ritual almost every Postgres team knows.&lt;/p&gt;

&lt;p&gt;Backups are configured.&lt;/p&gt;

&lt;p&gt;Alerts are in place.&lt;/p&gt;

&lt;p&gt;Someone has probably written a disaster recovery document.&lt;/p&gt;

&lt;p&gt;And somewhere in that document is a sentence that says:&lt;/p&gt;

&lt;p&gt;“We test restores regularly.”&lt;/p&gt;

&lt;p&gt;Except “regularly” usually means “when we get around to it.”&lt;/p&gt;

&lt;p&gt;That’s the problem we wanted to solve with Revenant.&lt;/p&gt;

&lt;p&gt;Instead of asking someone to remember to run a restore drill every quarter, we wanted the infrastructure to ask the question itself:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can this database actually be recovered?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we built a way to run that check every week, directly from CI.&lt;/p&gt;

&lt;p&gt;No Go installation.&lt;/p&gt;

&lt;p&gt;No application code.&lt;/p&gt;

&lt;p&gt;No ORM integration.&lt;/p&gt;

&lt;p&gt;No special framework plugin.&lt;/p&gt;

&lt;p&gt;Just PostgreSQL, a small YAML file, and a GitHub Action.&lt;/p&gt;

&lt;p&gt;Here’s what the setup looks like.&lt;/p&gt;

&lt;p&gt;First, define what a healthy restored database means for your application.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;revenant.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production-sanity&lt;/span&gt;

&lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${DATABASE_URL}&lt;/span&gt;

&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;connect&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;schema&lt;/span&gt;
    &lt;span class="na"&gt;expect_tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;users&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;row_count&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foreign_key&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;references&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;users&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;golden_query&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;count(*)&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;FROM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;orders&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;WHERE&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;created_at&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;interval&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'7&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;days'"&lt;/span&gt;
    &lt;span class="na"&gt;expect_min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;freshness&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;column&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;created_at&lt;/span&gt;
    &lt;span class="na"&gt;max_age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;48h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can write the checks yourself, or start from an existing database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'postgres://...'&lt;/span&gt;

revenant init &lt;span class="nt"&gt;--plan&lt;/span&gt; production-sanity &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revenant looks at the live schema and generates a starting configuration.&lt;/p&gt;

&lt;p&gt;You review it.&lt;/p&gt;

&lt;p&gt;You change the checks that matter to your application.&lt;/p&gt;

&lt;p&gt;Then commit it to the repository.&lt;/p&gt;

&lt;p&gt;The important part is that Revenant doesn't need to understand your application.&lt;/p&gt;

&lt;p&gt;It doesn't care whether you're running Next.js, Django, Rails, or a ten-year-old monolith.&lt;/p&gt;

&lt;p&gt;It only needs to know what a healthy PostgreSQL database looks like.&lt;/p&gt;

&lt;p&gt;Then comes the part that makes this useful.&lt;/p&gt;

&lt;p&gt;Put the validation into GitHub Actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Weekly restore validation&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;4&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;

  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;277pawan/revenant-action@v1.0.3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v0.1.1&lt;/span&gt;
          &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;revenant.yaml&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DATABASE_URL }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restore-validation-report&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;report.json&lt;/span&gt;
            &lt;span class="s"&gt;report.md&lt;/span&gt;
          &lt;span class="na"&gt;if-no-files-found&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;DATABASE_URL&lt;/code&gt; as a GitHub secret.&lt;/p&gt;

&lt;p&gt;Run it once manually.&lt;/p&gt;

&lt;p&gt;After that, your repository has a weekly restore validation running automatically.&lt;/p&gt;

&lt;p&gt;The output is deliberately boring.&lt;/p&gt;

&lt;p&gt;And that's a good thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restore Validation: PASS

Wrote report.json
Wrote report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something is wrong, you don't just get “backup failed.”&lt;/p&gt;

&lt;p&gt;You get the reason.&lt;/p&gt;

&lt;p&gt;A table is missing.&lt;/p&gt;

&lt;p&gt;A critical table is empty.&lt;/p&gt;

&lt;p&gt;A foreign key is broken.&lt;/p&gt;

&lt;p&gt;A business query returns unexpected results.&lt;/p&gt;

&lt;p&gt;The restored data is stale.&lt;/p&gt;

&lt;p&gt;That's much more useful than discovering the problem at 3 AM.&lt;/p&gt;

&lt;p&gt;And there's another level.&lt;/p&gt;

&lt;p&gt;If you're using AWS RDS, you can validate an actual snapshot rather than simply validating the live database.&lt;/p&gt;

&lt;p&gt;Revenant can restore the latest snapshot into a temporary sandbox, run the same validation checks against it, record the recovery time, and then tear the sandbox down.&lt;/p&gt;

&lt;p&gt;The workflow is essentially:&lt;/p&gt;

&lt;p&gt;Restore.&lt;/p&gt;

&lt;p&gt;Validate.&lt;/p&gt;

&lt;p&gt;Measure.&lt;/p&gt;

&lt;p&gt;Delete.&lt;/p&gt;

&lt;p&gt;If something goes wrong halfway through, &lt;code&gt;revenant reap&lt;/code&gt; acts as the safety net and cleans up orphaned sandboxes.&lt;/p&gt;

&lt;p&gt;You're not maintaining a second production database.&lt;/p&gt;

&lt;p&gt;You're renting proof for a short period and then deleting it.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;Because disaster recovery isn't really about having a backup.&lt;/p&gt;

&lt;p&gt;It's about knowing what happens after you click:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restore.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We also wanted the tool to be easy to debug before throwing it into CI.&lt;/p&gt;

&lt;p&gt;So there's a &lt;code&gt;doctor&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;revenant doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It checks configuration, environment variables, and connectivity before you start wondering why your GitHub Action isn't working.&lt;/p&gt;

&lt;p&gt;And the GitHub Action itself is intentionally simple.&lt;/p&gt;

&lt;p&gt;It downloads a pre-built Revenant binary from GitHub Releases and runs it.&lt;/p&gt;

&lt;p&gt;Your CI environment doesn't need Go.&lt;/p&gt;

&lt;p&gt;Your application doesn't need to change.&lt;/p&gt;

&lt;p&gt;It's just another CLI running as part of your workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where we are today
&lt;/h3&gt;

&lt;p&gt;Revenant is open source and Apache-2.0 licensed.&lt;/p&gt;

&lt;p&gt;The current releases include:&lt;/p&gt;

&lt;p&gt;CLI v0.1.1&lt;/p&gt;

&lt;p&gt;GitHub Action v1.0.3&lt;/p&gt;

&lt;p&gt;PostgreSQL validation checks&lt;/p&gt;

&lt;p&gt;JSON and Markdown reports&lt;/p&gt;

&lt;p&gt;AWS RDS snapshot restore validation&lt;/p&gt;

&lt;p&gt;Commands for &lt;code&gt;doctor&lt;/code&gt;, &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;verify&lt;/code&gt;, &lt;code&gt;snapshot&lt;/code&gt;, and &lt;code&gt;reap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;CLI:&lt;br&gt;
&lt;a href="https://github.com/277pawan/revenant-cli" rel="noopener noreferrer"&gt;https://github.com/277pawan/revenant-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Action:&lt;br&gt;
&lt;a href="https://github.com/277pawan/revenant-action" rel="noopener noreferrer"&gt;https://github.com/277pawan/revenant-action&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example workflows:&lt;br&gt;
&lt;a href="https://github.com/277pawan/revenant-cli/tree/main/examples/workflows" rel="noopener noreferrer"&gt;https://github.com/277pawan/revenant-cli/tree/main/examples/workflows&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But honestly, this is still early.&lt;/p&gt;

&lt;p&gt;There is a lot more we want Revenant to become.&lt;/p&gt;

&lt;p&gt;We're thinking about fleet-wide restore drills, scheduled recovery testing across many databases, centralized evidence, signed reports, audit workflows, recovery-time tracking, and eventually a hosted control plane for teams that have outgrown a single YAML file.&lt;/p&gt;

&lt;p&gt;We don't want to build all of that in isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's where I'm asking for your help.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Revenant is open source, and we're actively looking for people who want to contribute.&lt;/p&gt;

&lt;p&gt;You don't have to build a huge feature.&lt;/p&gt;

&lt;p&gt;Try it against your own PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Tell us where the workflow doesn't make sense.&lt;/p&gt;

&lt;p&gt;Open an issue.&lt;/p&gt;

&lt;p&gt;Suggest a check you think is missing.&lt;/p&gt;

&lt;p&gt;Improve the documentation.&lt;/p&gt;

&lt;p&gt;Add an example.&lt;/p&gt;

&lt;p&gt;Test it against a setup we haven't thought about.&lt;/p&gt;

&lt;p&gt;Or, if you're interested in the bigger vision, contribute code and help us shape what this becomes.&lt;/p&gt;

&lt;p&gt;The roadmap is intentionally bigger than what's shipping today.&lt;/p&gt;

&lt;p&gt;The more real-world feedback and contributions we get now, the more useful we can make the tool for everyone.&lt;/p&gt;

&lt;p&gt;Because I don't think “we have backups” should be the end of the conversation.&lt;/p&gt;

&lt;p&gt;It should be the beginning.&lt;/p&gt;

&lt;p&gt;**Backups prove you copied the data.&lt;/p&gt;

&lt;p&gt;Revenant proves you can recover it.**&lt;/p&gt;

&lt;p&gt;If that's a problem your team has been putting off, try it this week.&lt;/p&gt;

&lt;p&gt;And if you have an idea for what Revenant should become, I'd genuinely like to hear it.&lt;/p&gt;

&lt;p&gt;The project is open source.&lt;/p&gt;

&lt;p&gt;Come build it with us.&lt;/p&gt;

&lt;h1&gt;
  
  
  PostgreSQL #OpenSource #DevOps #SRE #DisasterRecovery #GitHubActions #AWS #RDS #Database #CI #Infrastructure #Backup
&lt;/h1&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>cicd</category>
      <category>postgres</category>
    </item>
    <item>
      <title>I built Revenant to prove PostgreSQL backups actually restore — in CI, on AWS, without touching your app code.</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Mon, 07 Sep 2026 06:27:47 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/i-built-revenant-to-prove-postgresql-backups-actually-restore-in-ci-on-aws-without-touching-474m</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/i-built-revenant-to-prove-postgresql-backups-actually-restore-in-ci-on-aws-without-touching-474m</guid>
      <description>&lt;p&gt;A team I know had green backup alerts for six months straight.&lt;/p&gt;

&lt;p&gt;Every day, the backups completed.&lt;/p&gt;

&lt;p&gt;Snapshots were being created on schedule. Retention was configured. Monitoring was quiet.&lt;/p&gt;

&lt;p&gt;As far as everyone could tell, the database was protected.&lt;/p&gt;

&lt;p&gt;Then one day, they needed to restore it.&lt;/p&gt;

&lt;p&gt;The snapshot restored successfully.&lt;/p&gt;

&lt;p&gt;The database started.&lt;/p&gt;

&lt;p&gt;And then the application broke.&lt;/p&gt;

&lt;p&gt;A migration that should have been there had never been applied to the restored instance. A critical table was empty. The first real query hit a foreign key constraint and failed.&lt;/p&gt;

&lt;p&gt;Nothing was wrong with the backup.&lt;/p&gt;

&lt;p&gt;The problem was that nobody had ever proved the restore actually worked.&lt;/p&gt;

&lt;p&gt;That distinction sounds obvious, but it's surprisingly easy to miss.&lt;/p&gt;

&lt;p&gt;Most teams have automated checks around whether a backup job completed. They know a snapshot exists. They know how long it's retained. They know the storage is healthy.&lt;/p&gt;

&lt;p&gt;But a successful backup only tells you that you copied some bits somewhere.&lt;/p&gt;

&lt;p&gt;It doesn't tell you whether those bits can become a working database again.&lt;/p&gt;

&lt;p&gt;And that's the gap I wanted to solve.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Revenant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Revenant is an open-source CLI that validates PostgreSQL restores.&lt;/p&gt;

&lt;p&gt;The idea is deliberately simple.&lt;/p&gt;

&lt;p&gt;You tell Revenant what a healthy database looks like in a &lt;code&gt;revenant.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Maybe your &lt;code&gt;customers&lt;/code&gt; and &lt;code&gt;orders&lt;/code&gt; tables need to exist.&lt;/p&gt;

&lt;p&gt;Maybe &lt;code&gt;orders&lt;/code&gt; should never be empty.&lt;/p&gt;

&lt;p&gt;Maybe the foreign key between &lt;code&gt;orders&lt;/code&gt; and &lt;code&gt;customers&lt;/code&gt; must remain intact.&lt;/p&gt;

&lt;p&gt;Maybe there is a query that should always return data.&lt;/p&gt;

&lt;p&gt;Maybe the newest order shouldn't be more than 24 hours old.&lt;/p&gt;

&lt;p&gt;Those rules are specific to your business, so Revenant doesn't try to guess them.&lt;/p&gt;

&lt;p&gt;You define them once.&lt;/p&gt;

&lt;p&gt;Then Revenant runs them every time you validate a database.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app-validation&lt;/span&gt;

&lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${DATABASE_URL}&lt;/span&gt;

&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;connect&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;schema&lt;/span&gt;
    &lt;span class="na"&gt;expect_tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customers&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;row_count&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foreign_key&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;references&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customers&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;golden_query&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;count(*)&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;FROM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;orders&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;WHERE&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'paid'"&lt;/span&gt;
    &lt;span class="na"&gt;expect_min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;freshness&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orders&lt;/span&gt;
    &lt;span class="na"&gt;column&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;created_at&lt;/span&gt;
    &lt;span class="na"&gt;max_age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;24h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;revenant verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result isn't just "command succeeded."&lt;/p&gt;

&lt;p&gt;You get evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ customers table exists
✓ orders row count 42 &amp;gt;= 1
✓ foreign key orders -&amp;gt; customers intact

Restore Validation: PASS

Wrote report.json
Wrote report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That report is useful because it answers a much more important question than "did the backup job run?"&lt;/p&gt;

&lt;p&gt;It answers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can we actually use this database?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And because Revenant only talks to PostgreSQL, it doesn't care what your application is written in.&lt;/p&gt;

&lt;p&gt;Node. Python. Go. Rails. Java.&lt;/p&gt;

&lt;p&gt;It doesn't need to read your source code or understand your application architecture.&lt;/p&gt;

&lt;p&gt;You can run it locally, in CI, or on a schedule.&lt;/p&gt;

&lt;p&gt;We also built a GitHub Action so teams don't need to install Go or manage another runtime just to run the checks.&lt;/p&gt;

&lt;p&gt;Set your &lt;code&gt;DATABASE_URL&lt;/code&gt;, add the workflow, and let the pipeline periodically prove that your database still passes its restore validation rules.&lt;/p&gt;

&lt;p&gt;The more interesting part is what happens with AWS RDS.&lt;/p&gt;

&lt;p&gt;For RDS, you can take the validation one step further.&lt;/p&gt;

&lt;p&gt;Revenant can find an RDS snapshot, restore it into a temporary sandbox, run your validation plan against the restored database, collect the results, and tear the sandbox down.&lt;/p&gt;

&lt;p&gt;In other words, you're not just checking whether a database looks healthy today.&lt;/p&gt;

&lt;p&gt;You're testing the thing you actually care about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can we recover from the backup we would use during an incident?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The current release includes the CLI, GitHub Action, PostgreSQL validation checks, JSON and Markdown reports, and the AWS RDS restore workflow.&lt;/p&gt;

&lt;p&gt;It's free, open source, and Apache-2.0 licensed.&lt;/p&gt;

&lt;p&gt;We've also started thinking about what comes next.&lt;/p&gt;

&lt;p&gt;A single &lt;code&gt;revenant.yaml&lt;/code&gt; works well when you're validating one application.&lt;/p&gt;

&lt;p&gt;But organizations eventually have dozens or hundreds of databases.&lt;/p&gt;

&lt;p&gt;That's where we're heading with the hosted layer: fleet-wide restore drills, scheduling, signed evidence, and a central place to see whether your databases can actually be recovered.&lt;/p&gt;

&lt;p&gt;But the core idea won't change.&lt;/p&gt;

&lt;p&gt;I've seen too many disaster recovery plans boil down to:&lt;/p&gt;

&lt;p&gt;"We have backups."&lt;/p&gt;

&lt;p&gt;I think the better statement is:&lt;/p&gt;

&lt;p&gt;"We have backups, and we prove that they restore."&lt;/p&gt;

&lt;p&gt;Because the worst time to discover that your backup doesn't actually recover your business is when you're already in the middle of an incident.&lt;/p&gt;

&lt;p&gt;That's why I built Revenant.&lt;/p&gt;

&lt;p&gt;If this problem sounds familiar, give it a try.&lt;/p&gt;

&lt;p&gt;CLI: &lt;a href="https://github.com/277pawan/revenant-cli" rel="noopener noreferrer"&gt;https://github.com/277pawan/revenant-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Action: &lt;a href="https://github.com/277pawan/revenant-action" rel="noopener noreferrer"&gt;https://github.com/277pawan/revenant-action&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you find something that breaks, open an issue.&lt;/p&gt;

&lt;p&gt;We're building this with early users, and those real-world restore failures are exactly what we want to learn from.&lt;/p&gt;

&lt;p&gt;**Don't just back up your database.&lt;/p&gt;

&lt;p&gt;Prove you can recover it.**&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
      <category>go</category>
      <category>postgres</category>
    </item>
    <item>
      <title>React Hook Form vs Formik vs Schema-Driven Forms: Which Approach Should You Use?</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Tue, 01 Sep 2026 06:44:50 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/react-hook-form-vs-formik-vs-schema-driven-forms-which-approach-should-you-use-51a7</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/react-hook-form-vs-formik-vs-schema-driven-forms-which-approach-should-you-use-51a7</guid>
      <description>&lt;p&gt;For Better Clarity Please visit rest you can continue with this article :- &lt;a href="https://react-form-toaster.web.app/" rel="noopener noreferrer"&gt;React-Form-Toaster (Official Doc)&lt;/a&gt; Building a form in React is easy when the fields are fixed.&lt;/p&gt;

&lt;p&gt;Choosing a React form solution can be surprisingly difficult.&lt;/p&gt;

&lt;p&gt;There are popular libraries.&lt;/p&gt;

&lt;p&gt;There are different validation strategies.&lt;/p&gt;

&lt;p&gt;And then there is the question of whether you even need a traditional form library.&lt;/p&gt;

&lt;p&gt;Three approaches you'll frequently encounter are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Hook Form&lt;/li&gt;
&lt;li&gt;Formik&lt;/li&gt;
&lt;li&gt;Schema-driven forms&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They solve overlapping problems, but their design philosophies are different.&lt;/p&gt;

&lt;p&gt;Let's look at how they compare.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Hook Form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;React Hook Form&lt;/a&gt; focuses on performant and flexible form handling.&lt;/p&gt;

&lt;p&gt;A simple example looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;formState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&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;required&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="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Email is required&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Submit
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The developer still explicitly creates the form UI.&lt;/p&gt;

&lt;p&gt;The library helps manage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;registration&lt;/li&gt;
&lt;li&gt;form state&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;errors&lt;/li&gt;
&lt;li&gt;submission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a great model when you want detailed control over your components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formik
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://formik.org/" rel="noopener noreferrer"&gt;Formik&lt;/a&gt; takes another approach to form state and validation.&lt;/p&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formik&lt;/span&gt;
  &lt;span class="na"&gt;initialValues&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&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="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Submit
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Formik&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Formik provides abstractions for managing form state, fields, validation, and submission.&lt;/p&gt;

&lt;p&gt;Again, though, your React component generally defines the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Schema-driven forms
&lt;/h2&gt;

&lt;p&gt;Schema-driven forms move the abstraction one step further.&lt;/p&gt;

&lt;p&gt;Instead of primarily describing how the form should be rendered in JSX, you describe the form as data.&lt;/p&gt;

&lt;p&gt;For 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&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;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;country&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;select&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Country&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;India&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IN&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;United States&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;US&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="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;The rendering system interprets that configuration.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schema
  ↓
Renderer
  ↓
Form UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful when forms are dynamic.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's the difference?
&lt;/h2&gt;

&lt;p&gt;A simplified way to think about the approaches is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Main abstraction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;React Hook Form&lt;/td&gt;
&lt;td&gt;Form state and field registration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formik&lt;/td&gt;
&lt;td&gt;Form state and form lifecycle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema-driven&lt;/td&gt;
&lt;td&gt;Form definition and rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This doesn't mean React Hook Form or Formik can't work with schemas.&lt;/p&gt;

&lt;p&gt;They absolutely can.&lt;/p&gt;

&lt;p&gt;The distinction is mainly about &lt;strong&gt;where your application puts the form definition&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When React Hook Form is a great choice
&lt;/h2&gt;

&lt;p&gt;Choose React Hook Form when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you want direct control over JSX&lt;/li&gt;
&lt;li&gt;you have custom UI components&lt;/li&gt;
&lt;li&gt;you need fine-grained form state management&lt;/li&gt;
&lt;li&gt;your forms are mostly developer-defined&lt;/li&gt;
&lt;li&gt;you want a mature ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many applications, this is an excellent default.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Formik makes sense
&lt;/h2&gt;

&lt;p&gt;Formik can be useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your team is already familiar with it&lt;/li&gt;
&lt;li&gt;you prefer its form-state model&lt;/li&gt;
&lt;li&gt;your existing application already uses Formik&lt;/li&gt;
&lt;li&gt;you have established Formik components and patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best library is often the one your team already knows and maintains effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  When schema-driven forms make sense
&lt;/h2&gt;

&lt;p&gt;Schema-driven forms become particularly interesting when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;forms are generated dynamically&lt;/li&gt;
&lt;li&gt;you have many similar forms&lt;/li&gt;
&lt;li&gt;fields come from configuration&lt;/li&gt;
&lt;li&gt;form definitions come from an API&lt;/li&gt;
&lt;li&gt;you need reusable form structures&lt;/li&gt;
&lt;li&gt;you want to separate form configuration from UI rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, imagine an admin system with 100 different forms.&lt;/p&gt;

&lt;p&gt;Writing and maintaining 100 large JSX components can become repetitive.&lt;/p&gt;

&lt;p&gt;A schema-driven renderer can allow those forms to share the same rendering infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  React-Form-Toaster
&lt;/h2&gt;

&lt;p&gt;This is the problem space that &lt;a href="https://www.npmjs.com/package/react-form-toaster" rel="noopener noreferrer"&gt;react-form-toaster&lt;/a&gt; focuses on.&lt;/p&gt;

&lt;p&gt;Instead of replacing every possible form library, it provides a schema-driven approach for building dynamic React forms.&lt;/p&gt;

&lt;p&gt;It can be useful when you want features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dynamic fields&lt;/li&gt;
&lt;li&gt;conditional fields&lt;/li&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;nested structures&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Zod validation&lt;/li&gt;
&lt;li&gt;file uploads&lt;/li&gt;
&lt;li&gt;modal forms&lt;/li&gt;
&lt;li&gt;inline forms&lt;/li&gt;
&lt;li&gt;toast feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important point is that this is not necessarily an "either/or" decision.&lt;/p&gt;

&lt;p&gt;Different projects can benefit from different abstractions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't choose based only on popularity
&lt;/h2&gt;

&lt;p&gt;A common mistake is asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which React form library is the most popular?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What problem does my application actually have?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you have a highly custom form with unique UI requirements, a traditional form-state library may be ideal.&lt;/p&gt;

&lt;p&gt;If you have dozens of forms that follow predictable patterns, schema-driven forms may save significant development time.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical decision guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Choose React Hook Form if:
&lt;/h3&gt;

&lt;p&gt;You want control over the UI and need powerful form-state management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose Formik if:
&lt;/h3&gt;

&lt;p&gt;Your team prefers its architecture or you're maintaining an existing Formik codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose schema-driven forms if:
&lt;/h3&gt;

&lt;p&gt;Your forms themselves need to be configurable and dynamically generated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consider combining approaches if:
&lt;/h3&gt;

&lt;p&gt;You need schema-based definitions but also want a mature form-state or validation engine underneath.&lt;/p&gt;

&lt;p&gt;These approaches aren't mutually exclusive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;There isn't a universal winner.&lt;/p&gt;

&lt;p&gt;React Hook Form, Formik, and schema-driven approaches solve different layers of the form problem.&lt;/p&gt;

&lt;p&gt;The most important question is whether your application's complexity is primarily coming from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;form state&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;form structure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the problem is mostly form state, a library such as React Hook Form can be an excellent choice.&lt;/p&gt;

&lt;p&gt;If the problem is that you have many dynamic form structures, schema-driven forms become much more compelling.&lt;/p&gt;

&lt;p&gt;That's exactly where tools like &lt;strong&gt;react-form-toaster&lt;/strong&gt; can fit into a React application's architecture.&lt;/p&gt;

&lt;p&gt;The goal isn't to use the most popular form library.&lt;/p&gt;

&lt;p&gt;The goal is to choose the abstraction that makes your particular forms easier to build and maintain.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>React Form Toaster 2.0.9: What Changed and Why You Might Want to Try It</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Mon, 24 Aug 2026 10:48:15 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-209-what-changed-and-why-you-might-want-to-try-it-5aln</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-209-what-changed-and-why-you-might-want-to-try-it-5aln</guid>
      <description>&lt;p&gt;If you've built a moderately complex form in React, you probably know how quickly the code grows.&lt;/p&gt;

&lt;p&gt;Validation.&lt;br&gt;
Conditional inputs.&lt;br&gt;
Loading states.&lt;br&gt;
Error messages.&lt;br&gt;
Password toggles.&lt;br&gt;
File inputs.&lt;br&gt;
Repeatable fields.&lt;br&gt;
Notifications.&lt;br&gt;
Styling.&lt;/p&gt;

&lt;p&gt;And eventually, the form component becomes much larger than the feature itself.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;strong&gt;React Form Toaster&lt;/strong&gt; is designed to reduce.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;version 2.0.9&lt;/strong&gt;, I've added and improved several capabilities that make schema-driven forms more practical for real applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 Install React Form Toaster
&lt;/h2&gt;

&lt;p&gt;You can get &lt;strong&gt;React Form Toaster&lt;/strong&gt; from npm:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-form-toaster" rel="noopener noreferrer"&gt;React Form Toaster on npm&lt;/a&gt;&lt;/strong&gt;&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;react-form-toaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then import it into your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Formbox&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;react-form-toaster&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-form-toaster/dist/index.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What makes it different?
&lt;/h2&gt;

&lt;p&gt;Instead of manually creating every field, you describe your form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&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;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation can be handled through Zod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&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="nx"&gt;z&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="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a valid email&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And submission stays simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt;
  &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For toast experiment you can try this!!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt;
  &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;toast&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing data...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Congratulation data saved🥂&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Found Some error!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&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="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="nf"&gt;setTimeout&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="mi"&gt;1500&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part of 2.0.9 is how much more control you have around that basic idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎨 Styling: Tailwind + Inline CSS
&lt;/h2&gt;

&lt;p&gt;You can now approach styling based on what you actually need.&lt;/p&gt;

&lt;p&gt;For utility classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rounded-xl px-4 py-3 font-semibold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For exact custom values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
  &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#12141c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1px solid #252836&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also customize things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;labels&lt;/li&gt;
&lt;li&gt;validation errors&lt;/li&gt;
&lt;li&gt;buttons&lt;/li&gt;
&lt;li&gt;inputs&lt;/li&gt;
&lt;li&gt;focus states&lt;/li&gt;
&lt;li&gt;password toggles&lt;/li&gt;
&lt;li&gt;dropdowns&lt;/li&gt;
&lt;li&gt;containers&lt;/li&gt;
&lt;li&gt;required indicators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives you more control without having to fight the library when building a custom UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔀 Conditional Fields
&lt;/h2&gt;

&lt;p&gt;Dynamic forms are another important part of 2.0.9.&lt;/p&gt;

&lt;p&gt;A field can depend on another field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;companyName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Company Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;showWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accountType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;business&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you build forms where the UI changes according to the user's choices without manually maintaining a separate visibility state for every conditional input.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔁 Repeatable Fields
&lt;/h2&gt;

&lt;p&gt;Array fields are supported for scenarios where users need to add multiple values or groups of inputs.&lt;/p&gt;

&lt;p&gt;This is useful for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple addresses&lt;/li&gt;
&lt;li&gt;team members&lt;/li&gt;
&lt;li&gt;products&lt;/li&gt;
&lt;li&gt;contact information&lt;/li&gt;
&lt;li&gt;dynamic configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to keep these structures inside the schema instead of turning your component into a collection of state-management code.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔔 Bring Your Own Toast Library
&lt;/h2&gt;

&lt;p&gt;You don't have to use the built-in toast system.&lt;/p&gt;

&lt;p&gt;Disable it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt; &lt;span class="na"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use whatever notification solution your application already uses.&lt;/p&gt;

&lt;p&gt;This keeps React Form Toaster focused on forms instead of forcing your entire application's notification architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌓 Inline or Modal
&lt;/h2&gt;

&lt;p&gt;Need a form inside a page?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"inline"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need a popup?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"modal"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same library, different presentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Why I'm Building This
&lt;/h2&gt;

&lt;p&gt;The idea behind React Form Toaster isn't to create another form library with hundreds of abstractions.&lt;/p&gt;

&lt;p&gt;I'm trying to make a common workflow simpler:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Define → Validate → Render → Submit → Notify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;without repeatedly rebuilding the same infrastructure.&lt;/p&gt;

&lt;p&gt;There is still a lot I want to improve, and that's where community feedback becomes important.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Documentation + Interactive Playground Coming Soon
&lt;/h2&gt;

&lt;p&gt;One of the next major things I'm working on is a dedicated documentation website for React Form Toaster.&lt;/p&gt;

&lt;p&gt;The README contains a lot of information, but I don't want developers to have to dig through a giant README to understand the library.&lt;/p&gt;

&lt;p&gt;The new documentation site will make it easier to find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;installation&lt;/li&gt;
&lt;li&gt;field types&lt;/li&gt;
&lt;li&gt;validation examples&lt;/li&gt;
&lt;li&gt;styling options&lt;/li&gt;
&lt;li&gt;conditional fields&lt;/li&gt;
&lt;li&gt;array fields&lt;/li&gt;
&lt;li&gt;toast configuration&lt;/li&gt;
&lt;li&gt;complete examples&lt;/li&gt;
&lt;li&gt;API references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But there's something else I'm especially excited about:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 An Interactive Playground
&lt;/h3&gt;

&lt;p&gt;The documentation will include a &lt;strong&gt;playground where you can actually experiment with React Form Toaster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of only reading about the API, you'll be able to play with the form configuration, try different fields and options, see how the form behaves, and learn by experimenting.&lt;/p&gt;

&lt;p&gt;I think this will make getting started with the library much easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read → Try → Change → Learn.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The documentation website and playground are planned to be released in the next few days. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Contribute to React Form Toaster
&lt;/h2&gt;

&lt;p&gt;React Form Toaster is an open-source project, and contributions are always welcome.&lt;/p&gt;

&lt;p&gt;If you find a bug, have an idea, or want to improve the library, I'd genuinely love to hear from you.&lt;/p&gt;

&lt;p&gt;You can contribute by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐛 Reporting bugs&lt;/li&gt;
&lt;li&gt;💡 Suggesting features&lt;/li&gt;
&lt;li&gt;🔧 Opening pull requests&lt;/li&gt;
&lt;li&gt;📖 Improving documentation&lt;/li&gt;
&lt;li&gt;🧪 Testing new features&lt;/li&gt;
&lt;li&gt;⭐ Sharing the project with other React developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the project and contribute on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/277pawan/form-builder" rel="noopener noreferrer"&gt;React Form Toaster on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also find me on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/277pawan" rel="noopener noreferrer"&gt;277pawan&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have an idea for improving the library, don't hesitate to open an issue or start a discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❤️ Back the Project
&lt;/h2&gt;

&lt;p&gt;Open-source software takes time to build, maintain, document, and improve.&lt;/p&gt;

&lt;p&gt;If React Form Toaster has saved you development time or helped you build something, you can support the project by backing my work.&lt;/p&gt;

&lt;p&gt;Your support helps me spend more time on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 New features&lt;/li&gt;
&lt;li&gt;🐛 Bug fixes&lt;/li&gt;
&lt;li&gt;📚 Better documentation&lt;/li&gt;
&lt;li&gt;🧪 Testing and improvements&lt;/li&gt;
&lt;li&gt;🧪 Improving the interactive playground&lt;/li&gt;
&lt;li&gt;🌐 The upcoming documentation website&lt;/li&gt;
&lt;li&gt;🔮 Future versions of React Form Toaster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd like to support the project financially, you can use the &lt;strong&gt;GitHub Sponsors&lt;/strong&gt; option on my profile.&lt;/p&gt;

&lt;p&gt;Every contribution — whether it's a sponsorship, a ⭐ star, a bug report, a pull request, or simply sharing the project — means a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;React Form Toaster 2.0.9 is another step toward making complex React forms easier to build without sacrificing customization.&lt;/p&gt;

&lt;p&gt;If you're working on a React project with dynamic forms, give it a try.&lt;/p&gt;

&lt;p&gt;📦 &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-form-toaster" rel="noopener noreferrer"&gt;Get React Form Toaster on npm&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;💻 &lt;strong&gt;&lt;a href="https://github.com/277pawan/form-builder" rel="noopener noreferrer"&gt;Explore the source code on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;&lt;a href="https://github.com/277pawan" rel="noopener noreferrer"&gt;Follow me on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If something doesn't work the way you'd expect, let me know. Open an issue, suggest an improvement, or contribute a fix.&lt;/p&gt;

&lt;p&gt;And if you like the idea behind the project, &lt;strong&gt;give the repository a ⭐&lt;/strong&gt; — it genuinely helps the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.0.9 is out. Documentation + Playground are coming next. 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks for checking out React Form Toaster and supporting open source. ❤️&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🚀 React-Form-Toaster 1.1.3 is here. Build powerful forms in React/Next.js with ease, flexibility, and clean UX baked right in.</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Thu, 23 Apr 2026 05:12:54 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-113-is-here-build-powerful-forms-in-reactnextjs-with-ease-flexibility-3f12</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-113-is-here-build-powerful-forms-in-reactnextjs-with-ease-flexibility-3f12</guid>
      <description>&lt;h1&gt;
  
  
  🚀 React-Form-Toaster 1.1.3
&lt;/h1&gt;

&lt;p&gt;Now faster, smarter, and more customizable than ever. Build powerful forms in React/Next.js with ease, flexibility, and clean UX baked right in.&lt;/p&gt;

&lt;p&gt;Say hello to the latest version of &lt;strong&gt;React-Form-Toaster (1.1.3)&lt;/strong&gt;! 🎉&lt;/p&gt;

&lt;p&gt;We've made it even easier, faster, and more powerful with much stability to create dynamic forms in React — without writing repetitive code. Whether you're building a signup form, feedback tool, or a confirmation popup, this library has you covered.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 What's New in 1.1.3?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;File Upload&lt;/strong&gt; — More keys for better file upload with new validation!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password Toggle&lt;/strong&gt; — Beautiful default UI with full customization; use any icon library by just declaring it (Show &amp;amp; Hide).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirmation Modals&lt;/strong&gt; — Easy-to-integrate confirmation messages with flexible buttons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Radio &amp;amp; Checkbox&lt;/strong&gt; — Checkbox for multiselect and radio support too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Super Fast Setup&lt;/strong&gt; — Just plug, play, and render your form!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Quick Installation
&lt;/h2&gt;

&lt;p&gt;Use npm or yarn to install:&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; &lt;span class="nt"&gt;--save&lt;/span&gt; react-form-toaster
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add react-form-toaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧩 How to Use It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Import and Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Formbox&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;react-form-toaster&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-form-toaster/dist/dist/tailwind.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Basic User Form Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Formbox&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;react-form-toaster&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-form-toaster/dist/dist/tailwind.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Formbox&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-gray-200 border-1 max-w-xl border-gray-100 rounded-lg shadow-md&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="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;formtoogle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setfirstform&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validationSchema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;formtitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Form-Builder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;className&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="s2"&gt;text-2xl font-bold text-black &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="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;textfield&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your Firstname...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FirstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your password...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&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;passwordToggle&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;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Eye&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EyeOff&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search your profession...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your age...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&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;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;marritalStatus?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Marital Status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;checklimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&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;options&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Married&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;married&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;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unmarried&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unmarried&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;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;other&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;other&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Upload your Image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;arialabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;maxFiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;selectlabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Select File pdf or image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.pdf, image/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;className&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="s2"&gt;border-2 border-dotted border-gray-400 p-2 rounded-lg bg-gray-100&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="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;buttons&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reset Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;arialabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reset_button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reset Button&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;arialabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit_button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;loader&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="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validationSchema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Submit Handler
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;h3&gt;
  
  
  4. Zod Validation Schema
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validationSchema&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;firstname&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="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First name must be at least 4 characters&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;age&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="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You must be at least 18 years old&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 Overview of Main Component Props
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Formbox&lt;/code&gt; Component
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prop&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;formtoogle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggle function for form visibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;formtitle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Title array for form headings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;textfield&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Array of input field definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;buttons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Submit, reset, or custom button configurations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;message&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Message block for confirmation dialogs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validationSchema&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zod schema for validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;className&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Custom styles for layout and design&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;TextField&lt;/code&gt; Options
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;placeholder&lt;/code&gt;, &lt;code&gt;label&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;arialabel&lt;/code&gt;, &lt;code&gt;passwordToggle&lt;/code&gt;, &lt;code&gt;icon&lt;/code&gt;, &lt;code&gt;checklimit&lt;/code&gt;, &lt;code&gt;options&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  File Upload Support
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;accept&lt;/code&gt;, &lt;code&gt;selectlabel&lt;/code&gt;, &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;maxFiles&lt;/code&gt;, and &lt;code&gt;arialabel&lt;/code&gt; for custom file uploads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buttons
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;label&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;, &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;arialabel&lt;/code&gt;, &lt;code&gt;tooltip&lt;/code&gt;, &lt;code&gt;loader&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Control labels, click behavior, classes, and accessibility with full flexibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  🙌 Join the Community
&lt;/h2&gt;

&lt;p&gt;If you found this helpful, consider giving the GitHub repo a ⭐!&lt;/p&gt;

&lt;p&gt;Contributions are always welcome — feel free to open issues, suggest improvements, or share your feedback to help make it even better.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Form Toaster 1.0.0</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Mon, 28 Apr 2025 07:51:18 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-100-2h85</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-100-2h85</guid>
      <description>&lt;h1&gt;
  
  
  React-Form-Toaster
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/277pawan/form-builder" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8flnbwz97kcr6mc8cvi.png" alt="GitHub Repo" width="32" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zqjyhmkgi51ykhnzx6t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zqjyhmkgi51ykhnzx6t.gif" alt="User-Form" width="640" height="363"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yhrdwkvvn3g51nwxw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yhrdwkvvn3g51nwxw9.png" alt="Confirmation-form" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎊 React-Form-Toaster is a powerful and flexible library designed for creating dynamic forms in React with ease. Users can quickly generate complex forms by simply defining input types, buttons, and other elements, without needing to create each element separately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; react-form-toaster
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add react-form-toaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Easy Setup: Get started in less than 10 seconds! Quickly integrate and begin creating dynamic forms without hassle.😎&lt;/li&gt;
&lt;li&gt;Dynamic Form Creation: Simply define the type of fields, labels, form title, and required attributes, and the library handles the rest.&lt;/li&gt;
&lt;li&gt;Highly Customizable: Customize every aspect of your form, including classes, messages, and more, to fit your specific needs.&lt;/li&gt;
&lt;li&gt;TypeScript Support: Built with TypeScript, ensuring strong typing and safer code development.🤯&lt;/li&gt;
&lt;li&gt;Tailwind CSS Integration: Optimized for Tailwind CSS, allowing for efficient and modern styling right out of the box.&lt;/li&gt;
&lt;li&gt;Default Form UI: Comes with a beautifully designed default form UI that you can use as-is or customize further to match your design requirements.&lt;/li&gt;
&lt;li&gt;Form Validation and Error Handling: Easily define required fields and validate user input with built-in error handling and custom validation functions.🍃&lt;/li&gt;
&lt;li&gt;Responsive Design: Fully responsive, making it easy to create forms that look great on any device.&lt;/li&gt;
&lt;li&gt;Animation and Effects: Easily apply animations, such as click outside the box to close the form.&lt;/li&gt;
&lt;li&gt;Fully Customizable Forms: Provides the flexibility to design forms with custom classes and styles, ensuring they match your application's theme.😱&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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="nx"&gt;ReactDOM&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;react-dom/client&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="nx"&gt;App&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;./App.tsx&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.css&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="nx"&gt;reportWebVitals&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;./reportWebVitals&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.StrictMode&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: It is important to import index.css after App.tsx to ensure that all styles are correctly applied. This ensures that any global styles are loaded after the component has been imported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  User-Forms
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Formbox&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;react-form-toaster&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-form-toaster/dist/dist/tailwind.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Formbox&lt;/span&gt;
  &lt;span class="nx"&gt;formtoogle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setfirstform&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;formtitle&lt;/span&gt;&lt;span class="o"&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Form-Builder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;className&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="s2"&gt;text-2xl font-bold &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;textfield&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your Firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FirstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// type: "text"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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;buttons&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submitbutton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submitbutton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&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="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;h3&gt;
  
  
  Confirmation-Forms
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &amp;lt;Formbox
 &lt;span class="nv"&gt;formtoogle&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;setsecondform&lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="nv"&gt;formtitle&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 title: &lt;span class="s2"&gt;"Confirmation-Form"&lt;/span&gt;,
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 message: &lt;span class="s2"&gt;"This is very important file Are you sure want to delete this file? Please reconfirm it!"&lt;/span&gt;
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 &lt;span class="nv"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 name: &lt;span class="s2"&gt;"Ok"&lt;/span&gt;,
 label: &lt;span class="s2"&gt;"Confirm"&lt;/span&gt;,
 &lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"ok"&lt;/span&gt;,
 &lt;span class="k"&gt;function&lt;/span&gt;: &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handleConfirm&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;,
 className: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"bg-red-600"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="o"&gt;{&lt;/span&gt;
 name: &lt;span class="s2"&gt;"Cancel"&lt;/span&gt;,
 label: &lt;span class="s2"&gt;"Cancel"&lt;/span&gt;,
 &lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"cancel"&lt;/span&gt;,
 &lt;span class="k"&gt;function&lt;/span&gt;: &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handleConfirm&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;,
 className: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"text-red-600 border-1 border-red-600 bg-gray-100 hover:border-red-600 "&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleConfirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;productId&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;confirm&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; We got both of them. Hurrah! 🏆 &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="nf"&gt;setsecondform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;Show your ❤️ and support by giving a ⭐. Any suggestions are welcome! Take a look at the contributing guide.&lt;br&gt;
You can also find me on Github &lt;a href="https://github.com/277pawan" rel="noopener noreferrer"&gt;&lt;strong&gt;277pawan&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;p&gt;MIT&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Library, Happy Coding😎😎!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>REACT FORM TOASTER (1.1.1).</title>
      <dc:creator>Pawan Bisht</dc:creator>
      <pubDate>Wed, 04 Sep 2024 17:06:46 +0000</pubDate>
      <link>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-186k</link>
      <guid>https://dev.to/pawan_bisht_3aa0838e302b2/react-form-toaster-186k</guid>
      <description>&lt;h1&gt;
  
  
  React-Form-Toaster (&lt;strong&gt;1.1.1&lt;/strong&gt;)
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/277pawan/form-builder" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8flnbwz97kcr6mc8cvi.png" alt="GitHub Repo" width="32" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zqjyhmkgi51ykhnzx6t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zqjyhmkgi51ykhnzx6t.gif" alt="User-Form" width="640" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yhrdwkvvn3g51nwxw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yhrdwkvvn3g51nwxw9.png" alt="Confirmation-form" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎊 React-Form-Toaster is a powerful and flexible library designed for creating dynamic forms in React with ease. Users can quickly generate complex forms by simply defining input types, buttons, and other elements, without needing to create each element separately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cure-ten.vercel.app/static/media/ezgif.com-video-to-gif-converter.01200ebb8d2078e8d60e.gif" rel="noopener noreferrer"&gt;https://cure-ten.vercel.app/static/media/ezgif.com-video-to-gif-converter.01200ebb8d2078e8d60e.gif&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; react-form-toaster
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add react-form-toaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Easy Setup: Get started in less than 10 seconds! Quickly integrate and begin creating dynamic forms without hassle.😎&lt;/li&gt;
&lt;li&gt;Dynamic Form Creation: Simply define the type of fields, labels, form title, and required attributes, and the library handles the rest.&lt;/li&gt;
&lt;li&gt;Highly Customizable: Customize every aspect of your form, including classes, messages, and more, to fit your specific needs.&lt;/li&gt;
&lt;li&gt;TypeScript Support: Built with TypeScript, ensuring strong typing and safer code development.🤯&lt;/li&gt;
&lt;li&gt;Tailwind CSS Integration: Optimized for Tailwind CSS, allowing for efficient and modern styling right out of the box.&lt;/li&gt;
&lt;li&gt;Default Form UI: Comes with a beautifully designed default form UI that you can use as-is or customize further to match your design requirements.&lt;/li&gt;
&lt;li&gt;Form Validation and Error Handling: Easily define required fields and validate user input with built-in error handling and custom validation functions.🍃&lt;/li&gt;
&lt;li&gt;Responsive Design: Fully responsive, making it easy to create forms that look great on any device.&lt;/li&gt;
&lt;li&gt;Zod Validation: Easily apply Zod validation in your Form🔐.&lt;/li&gt;
&lt;li&gt;Fully Customizable Forms: Provides the flexibility to design forms with custom classes and styles, ensuring they match your application's theme.😱&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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="nx"&gt;ReactDOM&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;react-dom/client&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="nx"&gt;App&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;./App.tsx&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.css&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="nx"&gt;reportWebVitals&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;./reportWebVitals&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.StrictMode&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: It is important to import index.css after App.tsx to ensure that all styles are correctly applied. This ensures that any global styles are loaded after the component has been imported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  User-Forms
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Formbox&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;react-form-toaster&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-form-toaster/dist/dist/tailwind.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Formbox&lt;/span&gt;
  &lt;span class="nx"&gt;formtoogle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setfirstform&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;formtitle&lt;/span&gt;&lt;span class="o"&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Form-Builder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;className&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="s2"&gt;text-2xl font-bold &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;textfield&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your Firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FirstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// type: "text"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter your age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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;buttons&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submitbutton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submitbutton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&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;validationSchema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlesubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;h4&gt;
  
  
  Zod Validation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validationSchema&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;firstname&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="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First name must be at least 4 characters&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;age&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="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You must be at least 18 years old&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Confirmation-Forms
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &amp;lt;Formbox
 &lt;span class="nv"&gt;formtoogle&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;setsecondform&lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="nv"&gt;formtitle&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 title: &lt;span class="s2"&gt;"Confirmation-Form"&lt;/span&gt;,
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 message: &lt;span class="s2"&gt;"This is very important file Are you sure want to delete this file? Please reconfirm it!"&lt;/span&gt;
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 &lt;span class="nv"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;={[{&lt;/span&gt;
 name: &lt;span class="s2"&gt;"Ok"&lt;/span&gt;,
 label: &lt;span class="s2"&gt;"Confirm"&lt;/span&gt;,
 &lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"ok"&lt;/span&gt;,
 &lt;span class="k"&gt;function&lt;/span&gt;: &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handleConfirm&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;,
 className: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"bg-red-600"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="o"&gt;{&lt;/span&gt;
 name: &lt;span class="s2"&gt;"Cancel"&lt;/span&gt;,
 label: &lt;span class="s2"&gt;"Cancel"&lt;/span&gt;,
 &lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"cancel"&lt;/span&gt;,
 &lt;span class="k"&gt;function&lt;/span&gt;: &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handleConfirm&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;,200&lt;span class="o"&gt;)&lt;/span&gt;,
 className: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"text-red-600 border-1 border-red-600 bg-gray-100 hover:border-red-600 "&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
 &lt;span class="o"&gt;}]}&lt;/span&gt;
 /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleConfirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;productId&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;confirm&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; We got both of them. Hurrah! 🏆 &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="nf"&gt;setsecondform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;h2&gt;
  
  
  Component Attributes
&lt;/h2&gt;

&lt;p&gt;The following tables detail all available attributes for each component in React-Form-Toaster:&lt;/p&gt;

&lt;h3&gt;
  
  
  Formbox Component Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;className&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string[]&lt;/td&gt;
&lt;td&gt;Custom classes for the form container&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;formtoogle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;td&gt;Function to toggle form visibility&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;formtitle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object[]&lt;/td&gt;
&lt;td&gt;Form title configuration&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;textfield&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object[]&lt;/td&gt;
&lt;td&gt;Text input field configurations&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;buttons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object[]&lt;/td&gt;
&lt;td&gt;Button configurations&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;message&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object[]&lt;/td&gt;
&lt;td&gt;Message configurations for confirmation forms&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validationSchema&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;td&gt;Zod validation schema&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  TextField Component Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Input field name&lt;/td&gt;
&lt;td&gt;"firstname"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;placeholder&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Placeholder text&lt;/td&gt;
&lt;td&gt;"Enter your Firstname..."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;label&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Label text&lt;/td&gt;
&lt;td&gt;"FirstName"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Input type (text, number, file, etc.)&lt;/td&gt;
&lt;td&gt;"number"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;required&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;Whether field is required&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;arialabel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Accessibility label&lt;/td&gt;
&lt;td&gt;"FileUpload"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  File Upload Specific Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;number&lt;/td&gt;
&lt;td&gt;Maximum number of files&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Preview type ("image")&lt;/td&gt;
&lt;td&gt;"image"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;previewClassName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string[]&lt;/td&gt;
&lt;td&gt;Classes for preview element&lt;/td&gt;
&lt;td&gt;["h-32 w-32"]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;icon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSX.Element&lt;/td&gt;
&lt;td&gt;Icon for removing files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;RiCloseLargeLine /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Button Component Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Button text&lt;/td&gt;
&lt;td&gt;"Submit"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Button type (submit, reset, ok, cancel)&lt;/td&gt;
&lt;td&gt;"submit"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;label&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;ARIA label&lt;/td&gt;
&lt;td&gt;"Submitbutton"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;function&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;td&gt;Click handler&lt;/td&gt;
&lt;td&gt;handlesubmit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;className&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string[]&lt;/td&gt;
&lt;td&gt;Custom classes&lt;/td&gt;
&lt;td&gt;["bg-red-600"]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;arialabel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Accessibility label&lt;/td&gt;
&lt;td&gt;"Submit_button"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tooltip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Tooltip text&lt;/td&gt;
&lt;td&gt;"Submit Form"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Loader Component Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;loader&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;Whether to show loader&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;className&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string[]&lt;/td&gt;
&lt;td&gt;Loader custom classes&lt;/td&gt;
&lt;td&gt;["border-red-500"]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Message Component Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;message&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Message text&lt;/td&gt;
&lt;td&gt;"Are you sure want to delete this file?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;className&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string[]&lt;/td&gt;
&lt;td&gt;Custom classes&lt;/td&gt;
&lt;td&gt;["text-gray-700"]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;Show your ❤️ and support by giving a ⭐. Any suggestions are welcome! Take a look at the contributing guide.&lt;br&gt;
You can also find me on Github &lt;a href="https://github.com/277pawan" rel="noopener noreferrer"&gt;&lt;strong&gt;277pawan&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Library, Happy Coding😎😎!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>typescript</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
