Why We Build sevk Markup Language
Why we built a new markup format when React Email and MJML already exist, and who it is actually for.
Email HTML has not meaningfully moved in twenty years. Nested tables, inline styles on every element, VML for Outlook, and a different rendering quirk for every client. sevk Markup Language exists so you do not have to hand-write any of that.
The Email HTML Problem
Modern web development has come incredibly far. We have React, Vue, Svelte - tools that make building complex UIs feel natural. But the moment you step into the email world, it's like traveling back in time. Gmail strips your <style>tags. Outlook uses Microsoft Word's rendering engine. Yahoo does its own thing entirely.
The result? Developers end up writing something like this just to create a simple centered button:
<table role="presentation" border="0" cellpadding="0"
cellspacing="0" width="100%">
<tr>
<td align="center" style="padding: 20px 0;">
<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml"
href="https://example.com" style="height:40px;
v-text-anchor:middle;width:200px;"
arcsize="10%" strokecolor="#000000"
fillcolor="#000000">
<w:anchorlock/>
<center style="color:#ffffff;">Click Me</center>
</v:roundrect>
<![endif]-->
<!--[if !mso]><!-->
<a href="https://example.com" style="background-color:
#000000; border-radius: 4px; color: #ffffff;
display: inline-block; font-size: 16px;
line-height: 40px; text-align: center;
text-decoration: none; width: 200px;">
Click Me
</a>
<!--<![endif]-->
</td>
</tr>
</table>That's over 20 lines of code for a single button. Now imagine building a full email template with headers, columns, images, and a footer. It's not just tedious - it's error-prone and nearly impossible to maintain.
Enter sevk Markup Language
sevk Markup Language is an XML-like syntax scoped to email. You write semantic tags. The compiler turns them into the table-based layouts, inline styles, and MSO conditionals that email clients actually need.
Here's that same button in sevk Markup:
<button href="https://example.com"
background-color="#000000" color="#ffffff"
padding="12px 24px" border-radius="4px">
Click Me
</button>Four lines. That's it. The compiler takes care of generating the MSO-compatible VML fallback, the proper inline styles, and the correct table structure - all automatically.
The Core Principle
Write what you mean, not what email clients need. sevk Markup abstracts away the complexity so you can focus on content and design.
The Building Blocks
sevk Markup provides a set of semantic components that map to common email patterns. Each component handles its own cross-client quirks internally:
Layout Components
Section, Container, Row, and Column give you a powerful layout system. Under the hood, they compile to properly nested tables with correct cellpadding, cellspacing, and role="presentation" attributes.
<section padding="40px 20px" background-color="#f8f9fa">
<container max-width="600px">
<row gap="20px">
<column>
<heading level="2" color="#333">Left Column</heading>
<paragraph color="#666">Content goes here.</paragraph>
</column>
<column>
<heading level="2" color="#333">Right Column</heading>
<paragraph color="#666">More content here.</paragraph>
</column>
</row>
</container>
</section>Content Components
Heading, Paragraph, Text, Image, Button, Link, List, and Divider cover everything you need for email content. Each accepts style attributes directly as props - no need for separate CSS or inline style strings.
<heading level="1" color="#1a1a1a" font-size="28px">
Welcome to sevk
</heading>
<paragraph color="#666" font-size="16px" line-height="1.6">
Start building beautiful emails in minutes.
</paragraph>
<image src="https://example.com/hero.png"
alt="Hero" width="600px" border-radius="8px" />
<button href="https://app.sevk.io"
background-color="#000000" color="#fff"
padding="14px 32px" border-radius="8px">
Get Started
</button>
<divider border-top="1px solid #e0e0e0" margin="20px 0" />Code Blocks with Syntax Highlighting
Need to send code snippets in your emails? The Codeblock component supports 40+ programming languages with built-in Prism.js syntax highlighting and multiple themes including One Dark, VS Code Dark+, One Light, and Visual Studio.
<codeblock language="typescript" theme="oneDark">
import { Sevk } from 'sevk'
const sevk = new Sevk('sevk_your_api_key')
await sevk.emails.send({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Welcome!',
markup: '<heading>Hello World</heading>'
})
</codeblock>How It Works Under the Hood
The sevk Markup compiler uses a regex-based, innermost-first parsing approach. This means it processes the most deeply nested tags first and works its way outward - handling nested layouts correctly without requiring a full DOM parser.
Here's what happens when you compile a sevk Markup template:
- Normalization - The markup is wrapped in a standard email structure if needed
- Tag Processing - Each semantic tag is converted to its email-safe HTML equivalent with proper table structures
- Style Extraction - Attributes like
color,padding,background-colorare extracted and converted to inline styles - MSO Compatibility - Buttons get VML fallbacks, images get proper dimensions, and layouts get conditional comments for Outlook
- Head Generation - Title, preview text, web fonts, and custom styles are injected into the HTML head
- Full HTML Output - A complete, valid XHTML Transitional document is generated, ready to send
The Playground: Try It Yourself
We built the sevk Playground so you can experience sevk Markup firsthand - no account required. The playground includes:
- Live Code Editor - Write sevk Markup and see the rendered email in real-time
- Visual Editor - Drag-and-drop components for a no-code experience
- AI Content Generator - Describe your email in plain English and let AI write the sevk Markup for you
- Component Library - Pre-built components you can insert with a single click
- Structure Tree- Visualize and navigate your email's component hierarchy
- Send Test Email - Send the email directly from the playground to see how it looks in real inboxes
Full Email Structure
sevk Markup also supports a full email document structure with head settings. You can define the email title, preview text (preheader), custom fonts, and styles - all within the markup itself:
<email>
<head>
<title>Welcome to sevk</title>
<preview>Your account is ready to go!</preview>
<font name="Inter"
url="https://fonts.googleapis.com/css2?family=Inter" />
<style>
.footer { color: #999; font-size: 12px; }
</style>
</head>
<body>
<section padding="40px 20px" background-color="#ffffff">
<container max-width="600px">
<heading level="1" color="#1a1a1a"
font-family="Inter, sans-serif">
Welcome!
</heading>
<paragraph color="#666666">
Your account has been created successfully.
</paragraph>
<button href="https://app.sevk.io"
background-color="#000000" color="#ffffff"
padding="12px 24px" border-radius="8px">
Go to Dashboard
</button>
</container>
</section>
</body>
</email>Available Everywhere via SDKs
The sevk Markup renderer is bundled into every official SDK. Whether you're using Bun, Node.js, Python, Go, PHP, Ruby, C#, Java, or Rust - you can render sevk Markup directly in your application without any external service calls.
Pass sevk Markup to the SDK when sending an email. It renders the markup locally and sends the resulting HTML to the API:
import { Sevk } from 'sevk'
const sevk = new Sevk('sevk_your_api_key')
// Send an email using sevk Markup
await sevk.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Welcome aboard!',
markup: `
<section padding="40px 20px" background-color="#f8f9fa">
<container max-width="600px">
<heading level="1" color="#1a1a1a">
Welcome!
</heading>
<paragraph color="#666">
We're glad to have you here.
</paragraph>
<button href="https://app.example.com"
background-color="#000000" color="#fff"
padding="12px 24px">
Get Started
</button>
</container>
</section>
`
})But you don't have to be a sevk customer to use sevk Markup. The render function lets you convert sevk Markup to email-compatible HTML locally - no API key, no network calls, no vendor lock-in. Use it with any email provider you want:
import { render } from 'sevk'
const markup = `
<section padding="32px" background-color="#f8f9fa">
<container max-width="600px">
<heading level="1" color="#1a1a1a">Hello World</heading>
<paragraph color="#666666">
This is a paragraph with some text.
</paragraph>
<button href="https://example.com" background-color="#000" color="#fff">
Click Me
</button>
</container>
</section>
`
const html = render(markup)
// Returns a complete, email-compatible HTML document
// Use it with any email provider: SendGrid, AWS SES, Postmark, etc.What About React Email, MJML, and Foundation for Emails?
React Email, MJML, and Zurb's Foundation for Emails are all solid projects. If one of them fits your stack, use it. sevk Markup is not meant to replace them for people they already serve. It exists because of the people they do not serve well:
- React Email is React. It is great if your app is a React or Next.js app. It is not a fit if your backend is Go, Rust, Python, PHP, Ruby, Java, or .NET and you do not want to stand up a Node service just to render emails.
- MJML's official runtime is Node. There are community ports for other languages, but they lag behind the reference implementation and are maintained by volunteers. If you are picking a tool for production in a non-Node stack, that trade-off matters.
- Foundation for Emails is Inky plus a Sass framework. It assumes you have a build step and a workflow that outputs static templates. That does not map cleanly to apps that generate email bodies dynamically from runtime data.
- None of them are designed to be typed by a human on a marketing team or pasted into a chat with an AI assistant. They are developer tools written for developers.
sevk Markup is a single string. That is the whole design choice everything else falls out of:
- Easy to share. A template fits in a message, a database column, a JSON field, or a git commit without any packaging.
- Easy for AI to write. The tag set is small and predictable, so LLMs produce valid markup on the first try instead of guessing at nested table structures.
- Local rendering. Render the same markup format in Node, PHP, or any other supported language without calling an external service.
- Audience is wider than developers. Marketers, designers, founders, and AI agents can all produce sevk Markup. It is short enough to read and write without training.
If you are happy with React Email, stay there. If you ship from a polyglot backend, want a format your non-technical team can edit, or want AI agents to write emails in a shared format, sevk Markup is built for that case.
Try sevk Markup Today
Head over to the playground and start building your first email with sevk Markup - no signup required.
Questions or feedback? Reach out at kubilay@sevk.io
