Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4825786
feat!: migrated codebase to monorepo
Konixy Feb 20, 2026
72247b6
fix: fixed vercel deployment
Konixy Feb 20, 2026
a78aae6
wrong tsconfig for components package
Konixy Feb 21, 2026
84a4062
Update .changeset/config.json
Konixy Feb 21, 2026
d979ab3
fixed vercel deployment for email preview
Konixy Feb 21, 2026
566f8f0
removed useless svelte config at root
Konixy Feb 21, 2026
aa41ac5
updated svelte config path in esling config
Konixy Feb 21, 2026
8471ada
docs: updated docs to v2
Konixy Feb 22, 2026
19e8f9d
feat(cli-preview): init
Konixy Mar 5, 2026
98fe53b
feat: cli & preview server
Konixy Mar 24, 2026
554e83a
test(server): updated snapshots
Konixy Mar 24, 2026
bf2b1db
test: added tests to cli and preview-server
Konixy Mar 24, 2026
6c21f62
working dev preview
Konixy Mar 24, 2026
0af4025
persist url search params
Konixy Mar 24, 2026
ca18646
test(server): updated snapshot
Konixy Mar 24, 2026
bec3035
chore: formatted files
Konixy Mar 24, 2026
1fcf623
test(inline-preview): fix test not passing
Konixy Mar 24, 2026
e2d41ca
chore(deps): updated docs deps
Konixy Mar 24, 2026
d0067d4
finished docs ui
Konixy Mar 26, 2026
5cace47
changed code highliting theme in preview server
Konixy Mar 26, 2026
857847c
chore: missing dependency
Konixy Mar 27, 2026
4070615
fixing things
Konixy Mar 27, 2026
b7268da
prevent preview-server from being built twice
Konixy Mar 27, 2026
79f02ce
updated tsconfig and removed .js extension on imports
Konixy Mar 27, 2026
54c87b5
chore(deps): updated deps
Konixy Mar 27, 2026
6d4e9a5
chore(preview): better error handling
Konixy Mar 27, 2026
9af264b
test(preview): removed stupid test
Konixy Mar 27, 2026
87155b5
chore: updated dev command
Konixy Mar 27, 2026
b40e604
chore(docs): updated tsconfig to resolve linter erros
Konixy Mar 27, 2026
4677fe2
new slogan
Konixy Mar 27, 2026
90d673e
new banner
Konixy Mar 27, 2026
83f7b87
og banner in docs
Konixy Mar 27, 2026
0af2bae
prepare for release
Konixy Mar 27, 2026
20f7603
solve conflict
Konixy Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
13 changes: 13 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"mode": "pre",
"tag": "beta",
"initialVersions": {
"better-svelte-email": "1.4.0",
"@better-svelte-email/cli": "1.4.0",
"@better-svelte-email/components": "1.4.0",
"@better-svelte-email/preview": "1.4.0",
"@better-svelte-email/preview-server": "1.4.0",
"@better-svelte-email/server": "1.4.0"
},
"changesets": []
}
60 changes: 60 additions & 0 deletions .changeset/twenty-cats-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
'better-svelte-email': major
'@better-svelte-email/cli': major
'@better-svelte-email/components': major
'@better-svelte-email/preview': major
'@better-svelte-email/preview-server': major
'@better-svelte-email/server': major
---

# New in v2

A CLI (`npx @better-svelte-email/cli`) has been added to preview your emails locally. It replaces the old preview system.

I also have migrated the codebase to a monorepo with new isolated packages (ex: @better-svelte-email/preview, @better-svelte-email/server, @better-svelte-email/components) instead of a single package. This allows for better isolation and modularity, making it easier to maintain and update the different parts of the library. It also reduces the bundle size of the library, when you only need to install the packages you need.

## Migration Guide

### Update your dependencies

First, uninstall the old package:

```bash
npm uninstall better-svelte-email
```

Then, install the new packages:

```bash
npm install @better-svelte-email/components @better-svelte-email/server
```

If you are using the preview system, you will need to install the preview package:

```bash
npm install @better-svelte-email/preview
```

### Update your imports

You will need to update all your imports across your project to use the new packages.

For the renderer, import it from the server package:

```typescript
import { Renderer } from '@better-svelte-email/server';
```

For the components, import them from the components package:

```typescript
import { Button, Text, Heading, Container, Section } from '@better-svelte-email/components';
```

For the preview, import it from the preview package:

```typescript
import { EmailPreview } from '@better-svelte-email/preview';
```

And that's it!
14 changes: 2 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,11 @@ jobs:
- name: Install dependencies
run: bun install

- name: Build project
- name: Build workspace
run: bun run build

- name: Run linter
run: bun run lint || echo "Linter not configured, skipping..."
run: bun run lint

- name: Run tests
run: bun run test

- name: Test summary
if: always()
run: |
if [ $? -eq 0 ]; then
echo "✅ All tests passed!"
else
echo "❌ Tests failed!"
exit 1
fi
109 changes: 17 additions & 92 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ on:
push:
branches:
- main
pull_request:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
contents: write
pull-requests: read
pull-requests: write
id-token: write

jobs:
Expand All @@ -32,14 +31,14 @@ jobs:
- name: Install dependencies
run: bun install

- name: Build project
- name: Build workspace
run: bun run build

- name: Run tests
run: bun run test

publish:
name: Publish to NPM
release:
name: Changesets Release
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Expand All @@ -62,95 +61,21 @@ jobs:
node-version: lts/*
registry-url: 'https://registry.npmjs.org'

- name: Get current version
id: current_version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Current version: $VERSION"

- name: Detect prerelease tag
id: prerelease_tag
run: |
VERSION="${{ steps.current_version.outputs.version }}"

# Check if version contains a prerelease identifier (e.g., -alpha, -beta, -rc)
if [[ "$VERSION" =~ -([a-zA-Z]+)\. ]]; then
TAG="${BASH_REMATCH[1]}"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "is_prerelease=true" >> $GITHUB_OUTPUT
echo "📦 Detected prerelease version: $VERSION → dist-tag: $TAG"
else
echo "tag=latest" >> $GITHUB_OUTPUT
echo "is_prerelease=false" >> $GITHUB_OUTPUT
echo "📦 Stable version: $VERSION → dist-tag: latest"
fi

- name: Check if version is published
id: check_published
run: |
PACKAGE_NAME=$(node -p "require('./package.json').name")
VERSION="${{ steps.current_version.outputs.version }}"

if npm view "$PACKAGE_NAME@$VERSION" version 2>/dev/null; then
echo "published=true" >> $GITHUB_OUTPUT
echo "📦 Version $VERSION is already published to npm"
else
echo "published=false" >> $GITHUB_OUTPUT
echo "✨ Version $VERSION is not published yet"
fi

- name: Install dependencies
if: steps.check_published.outputs.published == 'false'
run: bun install

- name: Build package
if: steps.check_published.outputs.published == 'false'
run: bun run prepack

- name: Publish to NPM
if: steps.check_published.outputs.published == 'false'
run: npm publish --provenance --access public --tag ${{ steps.prerelease_tag.outputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Skip publishing
if: steps.check_published.outputs.published == 'true'
run: |
echo "⏭️ Skipping npm publish - version ${{ steps.current_version.outputs.version }} already published"

outputs:
version: ${{ steps.current_version.outputs.version }}
should_release: ${{ steps.check_published.outputs.published == 'false' }}

release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: publish
if: needs.publish.outputs.should_release == 'true'

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Build publishable packages
run: bunx turbo run build --filter={./packages/*}

- name: Setup Node.js
uses: actions/setup-node@v4
- name: Create Release Pull Request or Publish
uses: changesets/action@v1
with:
node-version: lts/*

- name: Create and push tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v${{ needs.publish.outputs.version }}" -m "Release v${{ needs.publish.outputs.version }}"
git push origin "v${{ needs.publish.outputs.version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Generate changelog and create release
run: npx changelogithub
version: bun run version
publish: bunx changeset publish --access public
commit: 'chore: version packages'
title: 'chore: version packages'
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ node_modules
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vercel
.turbo
apps/*/.svelte-kit
apps/*/build
packages/*/.svelte-kit
packages/*/dist
packages/*/build
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ bun.lockb

# Miscellaneous
/static/
**/.svelte-kit/
**/dist/
**/build/
.turbo/
**/.turbo/
**/.vercel/
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
}
}
],
"tailwindStylesheet": "./src/app.css"
"tailwindStylesheet": "./apps/docs/src/app.css"
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.experimental.useTsgo": true
}
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
<p align="center">
<img src="static/favicon.svg" alt="Better Svelte Email" width="128" height="128">
<h3 align="center">Better Svelte Email</h3>
<p align="center">
Create beautiful emails in Svelte with first-class Tailwind support
</p>
<p align="center">
<a href="https://better-svelte-email.konixy.fr">Website</a>
·
<a href="https://github.com/Konixy/better-svelte-email">GitHub</a>
</p>
<a href="https://better-svelte-email.konixy.dev">
<img src="/banner.png" alt="Better Svelte Email, the only way to build emails in Svelte" width="1280" height="640">
</a>
<p align="center">
<a href="https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml">
<img src="https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml/badge.svg" alt="Tests">
</a>
<a href="https://www.npmjs.com/package/better-svelte-email">
<img src="https://img.shields.io/npm/v/better-svelte-email.svg?logo=npm" alt="npm version">
</a>
<a href="https://github.com/Konixy/better-svelte-email/stargazers">
<img src="https://img.shields.io/github/stars/Konixy/better-svelte-email?style=default&logo=github" alt="GitHub stars">
</a>
<a href="https://www.npmjs.com/package/better-svelte-email">
<img src="https://img.shields.io/npm/dw/better-svelte-email" alt="npm downloads">
</a>
</p>
<p align="center">
<a href="https://better-svelte-email.konixy.dev">Website</a>
·
<a href="https://github.com/Konixy/better-svelte-email">GitHub</a>
</p>
</p>

## Usage

See the [documentation](https://better-svelte-email.konixy.fr/docs) for a complete guide on how to use Better Svelte Email.
See the [documentation](https://better-svelte-email.konixy.dev/docs) for a complete guide on how to use Better Svelte Email.

## Features

Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions apps/docs/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"tailwind": {
"css": "src/app.css",
"baseColor": "stone"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils",
"ui": "$lib/components/ui",
"hooks": "$lib/hooks",
"lib": "$lib"
},
"typescript": true,
"registry": "https://shadcn-svelte.com/registry"
}
46 changes: 46 additions & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "docs",
"private": true,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . --ignore-path ../../.prettierignore && eslint src",
"test": "vitest run --passWithNoTests",
"test:watch": "vitest"
},
"dependencies": {
"@better-svelte-email/components": "workspace:*",
"@better-svelte-email/preview": "workspace:*",
"@better-svelte-email/server": "workspace:*",
"@lucide/svelte": "^1.7.0",
"clsx": "^2.1.1",
"mdsvex": "^0.12.7",
"mode-watcher": "^1.1.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-slug": "^6.0.0",
"resend": "^6.9.4",
"shiki": "^4.0.2",
"tailwind-merge": "^3.5.0",
"tailwindcss-motion": "^1.1.1",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@internationalized/date": "^3.10.0",
"@sveltejs/adapter-vercel": "^6.3.3",
"@sveltejs/kit": "^2.50.2",
"@tailwindcss/vite": "^4.1.18",
"@types/node": "24.10.9",
"bits-ui": "^2.16.4",
"prettier": "^3.8.1",
"svelte": "5.55.0",
"tailwind-variants": "^3.2.2",
"vite": "^8.0.2",
"vite-plugin-devtools-json": "^1.0.0",
"vitest": "^4.1.1"
}
}
Loading
Loading