<?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: Maksym Balatsko</title>
    <description>The latest articles on DEV Community by Maksym Balatsko (@mbalatsko).</description>
    <link>https://dev.to/mbalatsko</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3360338%2F1671c01e-1a56-4eec-9c10-2022a0933b5f.jpeg</url>
      <title>DEV Community: Maksym Balatsko</title>
      <link>https://dev.to/mbalatsko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mbalatsko"/>
    <language>en</language>
    <item>
      <title>📧 From Syntax to SMTP: The Ultimate Guide to Email Validation in Kotlin</title>
      <dc:creator>Maksym Balatsko</dc:creator>
      <pubDate>Tue, 29 Jul 2025 11:42:46 +0000</pubDate>
      <link>https://dev.to/mbalatsko/from-syntax-to-smtp-the-ultimate-guide-to-email-validation-in-kotlin-1ca9</link>
      <guid>https://dev.to/mbalatsko/from-syntax-to-smtp-the-ultimate-guide-to-email-validation-in-kotlin-1ca9</guid>
      <description>&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%2F9xs6te8d979lapdxv2gd.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%2F9xs6te8d979lapdxv2gd.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
As developers, we've all been there. You build a beautiful sign-up form, and within hours, your database is cluttered with entries like &lt;code&gt;test@test.com&lt;/code&gt;, &lt;code&gt;no@no.com&lt;/code&gt;, or worse, emails from disposable services like &lt;code&gt;mailinator.com&lt;/code&gt;. These bad emails lead to bounced messages, skewed analytics, and a frustrating user experience.&lt;/p&gt;

&lt;p&gt;A simple regex can catch basic typos, but it can't tell you if a domain is real, if it's configured to receive email, or if it's a temporary address destined to be abandoned.&lt;/p&gt;

&lt;p&gt;What if you had a smarter, more comprehensive tool? Enter &lt;strong&gt;&lt;a href="https://github.com/mbalatsko/emailverifier-kt" rel="noopener noreferrer"&gt;emailverifier-kt&lt;/a&gt;&lt;/strong&gt;, a composable, pluggable Kotlin library designed to give you a real signal on whether an email is worth accepting.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Makes EmailVerifier Different?
&lt;/h2&gt;

&lt;p&gt;This isn't your average validator. It performs a whole suite of checks, giving you a multi-layered defense against bad data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;✅ Syntax Validation&lt;/strong&gt;: Checks for well-formed email structure (RFC 5322 subset).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Domain Registrability&lt;/strong&gt;: Uses the Public Suffix List to ensure the domain is actually registrable (goodbye, &lt;code&gt;user@something.invalid&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ MX Record Lookup&lt;/strong&gt;: Queries DNS to see if the domain is configured to receive emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Disposable Email Detection&lt;/strong&gt;: Filters out thousands of known temporary email providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Free Provider &amp;amp; Role-Based Checks&lt;/strong&gt;: Identifies emails from free services (&lt;code&gt;gmail.com&lt;/code&gt;) and generic roles (&lt;code&gt;info@&lt;/code&gt;, &lt;code&gt;admin@&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Gravatar Check&lt;/strong&gt;: See if the email has a Gravatar profile, often a good sign of a real user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ SMTP Deliverability Check&lt;/strong&gt;: (Use with caution!) A deep check that connects to the mail server to see if the mailbox exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best of all, it's built with modern Kotlin in mind, featuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🚀 High Performance&lt;/strong&gt;: Uses coroutines to run I/O-bound checks concurrently, making it fast and efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✨ Fluent DSL&lt;/strong&gt;: A clean, readable DSL to configure exactly the checks you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🌐 Powerful Offline Mode&lt;/strong&gt;: Can run using bundled datasets in environments without internet access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔧 Extreme Configurability&lt;/strong&gt;: Tweak every aspect, from timeouts to custom data sources.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Getting Started: The Basics
&lt;/h2&gt;

&lt;p&gt;First, add the dependency to your &lt;code&gt;build.gradle.kts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.mbalatsko:emailverifier-kt:LATEST_VERSION"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Check Maven Central for the latest version)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, let's see it in action. The library is designed to be reused, so you should create a single instance for your application's lifecycle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.mbalatsko.emailverifier.emailVerifier&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.runBlocking&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Create a verifier instance (do this once!)&lt;/span&gt;
    &lt;span class="c1"&gt;// The initialization block downloads the necessary datasets.&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;verifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;emailVerifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// For now, we'll use default settings.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Verify an email&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"john.doe@gmail.com"&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. Check the result&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isLikelyDeliverable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"'$email' looks like a valid, deliverable email!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Validation failed for '$email'."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// The result object gives you granular details&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disposable&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;CheckResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Reason: It's a disposable email address."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mx&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;CheckResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Reason: The domain has no MX records."&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 &lt;code&gt;isLikelyDeliverable()&lt;/code&gt; function is a great starting point. It aggregates the most critical checks: syntax, domain registrability, MX records, and disposable status.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case 1: In a Spring Boot Application
&lt;/h2&gt;

&lt;p&gt;In a Spring Boot app, you should define the &lt;code&gt;EmailVerifier&lt;/code&gt; as a singleton &lt;code&gt;@Bean&lt;/code&gt;. This ensures the initial setup cost (downloading data) happens only once at startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a configuration class:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.mbalatsko.emailverifier.EmailVerifier&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.mbalatsko.emailverifier.emailVerifier&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.runBlocking&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;

&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailVerifierConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;emailVerifier&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;EmailVerifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// runBlocking is acceptable here as it's part of the bean initialization&lt;/span&gt;
        &lt;span class="c1"&gt;// at application startup.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emailVerifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Disable the Gravatar check to speed up validation&lt;/span&gt;
                &lt;span class="nf"&gt;gravatar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&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;&lt;strong&gt;2. Inject and use it in your service:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Service&lt;/span&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;emailVerifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EmailVerifier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;registerUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validationResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailVerifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&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="n"&gt;validationResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isLikelyDeliverable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid email provided."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validationResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;roleBasedUsername&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;CheckResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please use a personal email, not a role-based one."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// ... proceed with user registration ...&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;
  
  
  Use Case 2: On an Android Client
&lt;/h2&gt;

&lt;p&gt;On Android, you need to be mindful of the main thread and data usage. &lt;code&gt;EmailVerifier&lt;/code&gt; is perfect for this, thanks to its coroutine support and offline capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Set up your ViewModel:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's best to use the verifier within a &lt;code&gt;ViewModel&lt;/code&gt; and launch verification in &lt;code&gt;viewModelScope&lt;/code&gt;. For a snappy user experience and to save data, consider using the offline mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.ViewModel&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.viewModelScope&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.mbalatsko.emailverifier.EmailVerifier&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.mbalatsko.emailverifier.emailVerifier&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegistrationViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Lazily initialize the verifier. The first access will trigger&lt;/span&gt;
    &lt;span class="c1"&gt;// the setup, which we'll ensure happens on a background thread.&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;emailVerifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EmailVerifier&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Since this is a lazy init, it won't block the main thread on VM creation.&lt;/span&gt;
        &lt;span class="c1"&gt;// The first call to verify() will trigger this block.&lt;/span&gt;
        &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emailVerifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Use the bundled offline data for maximum speed and to save user data.&lt;/span&gt;
                &lt;span class="c1"&gt;// This disables network checks (MX, Gravatar, SMTP).&lt;/span&gt;
                &lt;span class="n"&gt;allOffline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&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="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// This is now super fast because it uses local data!&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailVerifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isLikelyDeliverable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Update UI State: Email is valid&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Update UI State: Email is invalid, maybe show an error message&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;By setting &lt;code&gt;allOffline = true&lt;/code&gt;, you get instant feedback on syntax, disposability, and other checks that can use the bundled data, creating a great UX without hitting the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go Forth and Verify!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;emailverifier-kt&lt;/strong&gt; is a powerful, flexible, and modern library that solves a common but tricky problem. By giving you detailed results and extensive configuration, it puts you in control of your application's data quality.&lt;/p&gt;

&lt;p&gt;Stop letting bad emails into your system. Give your users instant feedback and ensure the data you collect is reliable.&lt;/p&gt;

&lt;p&gt;Check out the project on &lt;a href="https://github.com/mbalatsko/emailverifier-kt" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to see more advanced configurations and contribute!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>java</category>
      <category>springboot</category>
      <category>android</category>
    </item>
  </channel>
</rss>
