npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@truelist/vue

v0.1.0

Published

Vue composables and components for Truelist.io email validation

Downloads

11

Readme

@truelist/vue

Free tier Vue composables and components for real-time email validation with Truelist.io.

Validate emails at the point of entry with a headless composable, a pre-built input component, or a provide/inject provider pattern.

npm install @truelist/vue

Start free — 100 validations + 10 enhanced credits, no credit card required. Get your API key →

Quick Start

Use the composable directly with an API key:

<script setup>
import { useEmailValidation } from '@truelist/vue'

const { email, result, isValidating } = useEmailValidation({
  apiKey: 'your-api-key',
})
</script>

<template>
  <input v-model="email" type="email" placeholder="[email protected]" />
  <span v-if="isValidating">Checking...</span>
  <span v-else-if="result?.state === 'ok'">Valid!</span>
  <span v-else-if="result?.state === 'email_invalid'">Invalid email</span>
</template>

Provider Pattern

Wrap your app with TruelistProvider to make the API key available to all composables and components:

<!-- App.vue -->
<script setup>
import { TruelistProvider } from '@truelist/vue'
</script>

<template>
  <TruelistProvider api-key="your-api-key">
    <router-view />
  </TruelistProvider>
</template>

Then use composables without passing the API key:

<script setup>
import { useEmailValidation } from '@truelist/vue'

const { email, result, isValidating } = useEmailValidation()
</script>

Composable: useEmailValidation

The primary way to add email validation to any UI. Headless by design -- you control the rendering.

<script setup>
import { useEmailValidation } from '@truelist/vue'

const { email, result, isValidating, error, validate, reset } = useEmailValidation({
  apiKey: 'your-api-key',
  debounceMs: 500,
  validateOn: 'blur',
  onResult: (result) => console.log(result),
  onError: (error) => console.error(error),
})
</script>

<template>
  <div>
    <input v-model="email" type="email" @blur="validate" placeholder="[email protected]" />
    <span v-if="isValidating">Checking...</span>
    <span v-else-if="result?.state === 'email_invalid'">This email is not valid.</span>
    <span v-else-if="result?.state === 'accept_all'">This email may not be verifiable.</span>
    <span v-if="result?.suggestion">Did you mean {{ result.suggestion }}?</span>
    <span v-if="error">{{ error }}</span>
    <button @click="reset">Clear</button>
  </div>
</template>

Return Value

| Property | Type | Description | |---|---|---| | email | Ref<string> | Reactive email value for v-model binding | | result | Ref<ValidationResult \| null> | The validation result, or null | | isValidating | Ref<boolean> | Whether a request is in-flight | | error | Ref<string \| null> | Error message, or null | | validate | () => Promise<void> | Trigger validation manually | | reset | () => void | Clear result, error, and abort pending requests |

Options

| Option | Type | Default | Description | |---|---|---|---| | apiKey | string | -- | Your Truelist API key (or use provider) | | baseUrl | string | https://api.truelist.io | Custom API base URL | | debounceMs | number | 500 | Debounce delay. Set to 0 to disable. | | validateOn | "blur" \| "change" | "blur" | When to trigger automatic validation | | onResult | (result: ValidationResult) => void | -- | Callback when validation succeeds | | onError | (error: string) => void | -- | Callback when validation fails |

Component: TruelistEmailInput

A composable, unstyled email input with built-in validation.

<script setup>
import { ref } from 'vue'
import { TruelistEmailInput } from '@truelist/vue'

const email = ref('')

function handleResult(result) {
  console.log('Validation:', result)
}
</script>

<template>
  <TruelistEmailInput
    v-model="email"
    api-key="your-api-key"
    validate-on="blur"
    :debounce-ms="500"
    placeholder="[email protected]"
    @validation-result="handleResult"
  />
</template>

Slots

Customize rendering with named slots:

<TruelistEmailInput v-model="email" api-key="your-api-key">
  <template #validating>
    <span class="spinner">Verifying...</span>
  </template>

  <template #suggestion="{ suggestion }">
    <span class="suggestion">Did you mean {{ suggestion }}?</span>
  </template>

  <template #error="{ error }">
    <span class="error">{{ error }}</span>
  </template>

  <template #result="{ result }">
    <span v-if="result.state === 'ok'" class="success">Looks good!</span>
  </template>
</TruelistEmailInput>

Styling with Data Attributes

The input exposes a data-validation-state attribute for CSS styling:

input[data-validation-state="ok"] {
  border-color: green;
}

input[data-validation-state="email_invalid"] {
  border-color: red;
}

input[data-validation-state="accept_all"] {
  border-color: orange;
}

input[data-validation-state="validating"] {
  border-color: blue;
}

input[data-validation-state="idle"] {
  border-color: gray;
}

Props

| Prop | Type | Default | Description | |---|---|---|---| | modelValue / v-model | string | "" | The email value | | apiKey | string | -- | Your Truelist API key (or use provider) | | baseUrl | string | https://api.truelist.io | Custom API base URL | | validateOn | "blur" \| "change" | "blur" | When to trigger validation | | debounceMs | number | 500 | Debounce delay for "change" mode | | placeholder | string | -- | Input placeholder text | | disabled | boolean | false | Disable the input | | name | string | -- | Input name attribute | | id | string | -- | Input id attribute |

Events

| Event | Payload | Description | |---|---|---| | update:modelValue | string | Emitted when the email value changes | | validation-result | ValidationResult | Emitted when validation completes |

Exposed Methods

Access component methods via template ref:

<script setup>
import { ref } from 'vue'
import { TruelistEmailInput } from '@truelist/vue'

const inputRef = ref()

function manualValidate() {
  inputRef.value?.validate()
}
</script>

<template>
  <TruelistEmailInput ref="inputRef" api-key="your-api-key" v-model="email" />
  <button @click="manualValidate">Validate</button>
</template>

Types

import type {
  ValidationState,
  ValidationSubState,
  ValidationResult,
  TruelistConfig,
} from '@truelist/vue'

ValidationState

type ValidationState = "ok" | "email_invalid" | "accept_all" | "unknown";

ValidationSubState

type ValidationSubState =
  | "email_ok"
  | "accept_all"
  | "is_disposable"
  | "is_role"
  | "failed_mx_check"
  | "failed_spam_trap"
  | "failed_no_mailbox"
  | "failed_greylisted"
  | "failed_syntax_check"
  | "unknown";

ValidationResult

type ValidationResult = {
  email: string;
  domain: string;
  canonical: string;
  mxRecord: string | null;
  firstName: string | null;
  lastName: string | null;
  state: ValidationState;
  subState: ValidationSubState;
  verifiedAt: string;
  suggestion: string | null;
};

TruelistConfig

type TruelistConfig = {
  apiKey: string;
  baseUrl?: string;
};

Configuration

Provider Props

| Prop | Type | Default | Description | |---|---|---|---| | apiKey | string | required | Your Truelist API key | | baseUrl | string | https://api.truelist.io | Custom API base URL |

API Details

  • Endpoint: POST https://api.truelist.io/api/v1/verify_inline?email=...
  • Auth: Bearer token (your API key)
  • Response: { "emails": [{ ... }] }

Get your API key at truelist.io.

Getting Started

Sign up for a free Truelist account to get your API key. The free plan includes 100 validations and 10 enhanced credits — no credit card required.

License

MIT