Skip to content

Konixy/better-svelte-email

Repository files navigation

Better Svelte Email

Create beautiful emails in Svelte with first-class Tailwind support

Website Β· GitHub

Tests npm version GitHub stars

Features

  • Stable & Future-Proof - Uses Svelte's public preprocessor API
  • Tailwind CSS Support - Transforms Tailwind classes to inline styles for email clients
  • Built-in Email Preview - Visual email preview and test sending
  • TypeScript First - Fully typed with comprehensive type definitions
  • Well Tested - Extensive test coverage with unit and integration tests

See Roadmap for future features and planned improvements.

Why?

Existing Svelte email solutions have significant limitations:

  • svelte-email hasn't been updated in over 2 years
  • svelte-email-tailwind suffers from stability issues and maintaining it is not sustainable anymore

Better Svelte Email is a complete rewrite built on Svelte's official preprocessor API, providing the rock-solid foundation your email infrastructure needs. It brings the simplicity, reliability, and feature richness of React Email to the Svelte ecosystem.

Quick Start

1. Install the package

npm i -D better-svelte-email
# or
bun add -D better-svelte-email
# or
pnpm add -D better-svelte-email

2. Configure the Preprocessor

Add the preprocessor to your svelte.config.js:

import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { betterSvelteEmailPreprocessor } from 'better-svelte-email';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	preprocess: [vitePreprocess(), betterSvelteEmailPreprocessor()],
	kit: {
		adapter: adapter()
	}
};

export default config;

3. Create Email Components

Create your email templates in src/lib/emails/:

<!-- src/lib/emails/welcome.svelte -->
<script>
	import { Html, Head, Body, Preview, Container, Text, Button } from 'better-svelte-email';

	let { name = 'User' } = $props();
</script>

<Html>
	<Head />
	<Body class="bg-gray-100">
		<Preview preview="Welcome Email" />
		<Container class="mx-auto p-8">
			<Text class="mb-4 text-2xl font-bold">
				Welcome, {name}!
			</Text>

			<Button
				href="https://example.com"
				class="rounded bg-orange-600 px-6 py-3 text-white sm:text-sm"
			>
				Get Started
			</Button>
		</Container>
	</Body>
</Html>

4. Render and Send

// src/routes/api/send-email/+server.ts
import { render } from 'svelte/server';
import WelcomeEmail from '$lib/emails/welcome.svelte';

export async function POST({ request }) {
	const { name, email } = await request.json();

	// Render email (preprocessor already ran at build time!)
	const result = render(WelcomeEmail, { props: { name } });

	// Send email using your preferred service (Resend, SendGrid, etc.)
	// await resend.emails.send({
	//   from: 'noreply@example.com',
	//   to: email,
	//   subject: 'Welcome!',
	//   html: result.body
	// });

	return new Response('Sent');
}

Email Preview Component

Better Svelte Email includes a built-in preview component for visually developing and testing your email templates during development.

Setup

Create a preview route in your SvelteKit app:

<!-- src/routes/preview/+page.svelte -->
<script lang="ts">
	import { EmailPreview } from 'better-svelte-email/preview';

	let { data } = $props();
</script>

<EmailPreview emailList={data.emails} />
// src/routes/preview/+page.server.ts
import { emailList, createEmail, sendEmail } from 'better-svelte-email/preview';
import { env } from '$env/dynamic/private';

export function load() {
	const emails = emailList({
		path: '/src/lib/emails' // optional, defaults to '/src/lib/emails'
	});

	return { emails };
}

export const actions = {
	...createEmail,
	...sendEmail({ resendApiKey: env.RESEND_API_KEY })
};

Features

  • HTML Source View - Inspect the generated HTML with syntax highlighting
  • Copy to Clipboard - Quickly copy the rendered HTML
  • Test Email Sending - Send test emails directly from the preview UI using Resend
  • Template List - Browse all your email templates in one place

Environment Variables

To enable test email sending, add your Resend API key to your .env file:

RESEND_API_KEY=re_your_api_key_here

Get your API key from Resend.

Custom Email Provider

If you prefer to use a different email provider, you can pass a custom send function:

export const actions = {
	...createEmail,
	...sendEmail({
		customSendEmailFunction: async ({ from, to, subject, html }) => {
			// Use your preferred email service (SendGrid, Mailgun, etc.)
			try {
				await yourEmailService.send({ from, to, subject, html });
				return { success: true };
			} catch (error) {
				return { success: false, error };
			}
		}
	})
};

Configuration

Here are the available options:

betterSvelteEmailPreprocessor({
	pathToEmailFolder: '/src/lib/emails',
	debug: false,
	tailwindConfig: {
		theme: {
			extend: {
				colors: {
					brand: '#FF3E00'
				}
			}
		}
	}
});

Minimum Svelte Version

The minimum supported Svelte version is 5.14.3. For older versions, you can use svelte-email-tailwind.

Supported Features

βœ… Supported

  • βœ… Static Tailwind classes
  • βœ… Custom Tailwind classes (bg-[#fff], my:[40px], ...)
  • βœ… All standard Tailwind (v3) utilities (colors, spacing, typography, etc.)
  • βœ… Responsive breakpoints (sm:, md:, lg:, xl:, 2xl:)
  • βœ… HTML elements and Svelte components
  • βœ… Nested components
  • βœ… Conditional blocks ({#if})
  • βœ… Each blocks ({#each})
  • βœ… Custom Tailwind configurations

❌ Not Supported (Yet) (See Roadmap)

  • ❌ Tailwind v4
  • ❌ CSS Object (style={{ color: 'red' }})
  • ❌ Dynamic class expressions (class={someVar})
  • ❌ Arbitrary values in responsive classes (sm:[color:red])
  • ❌ Container queries

Author

Anatole Dufour (@Konixy)

Development

Running Tests

bun run test

All tests must pass before pushing to main. The CI/CD pipeline will automatically run tests on every push and pull request.

Building

bun run build

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

To do so, you'll need to:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/amazing-feature)
  3. Make your changes
  4. Run tests (bun run test)
  5. Commit your changes using conventional commits:
    • feat: - New features
    • fix: - Bug fixes
    • docs: - Documentation changes
    • test: - Test additions/changes
    • chore: - Maintenance tasks
  6. Push to your branch (git push origin feat/amazing-feature)
  7. Open a Pull Request

Acknowledgements

Many components and logic were inspired by or adapted from svelte-email-tailwind and react-email. Huge thanks to the authors and contributors of these projects for their excellent work.

About

πŸ“§ Render emails in Svelte effortlessly with first-class tailwind support

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published